Commit f46792d0 authored by Matthias Braun's avatar Matthias Braun
Browse files

remove ilp scheduler; simplify listsched interface

[r28010]
parent ad9464a5
......@@ -346,39 +346,6 @@ static void TEMPLATE_get_call_abi(const void *self, ir_type *method_type,
}
}
static int TEMPLATE_to_appear_in_schedule(void *block_env, const ir_node *irn)
{
(void) block_env;
if (!is_TEMPLATE_irn(irn))
return -1;
return 1;
}
list_sched_selector_t TEMPLATE_sched_selector;
/**
* Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
*/
static const list_sched_selector_t *TEMPLATE_get_list_sched_selector(
const void *self, list_sched_selector_t *selector)
{
(void) self;
(void) selector;
TEMPLATE_sched_selector = trivial_selector;
TEMPLATE_sched_selector.to_appear_in_schedule = TEMPLATE_to_appear_in_schedule;
return &TEMPLATE_sched_selector;
}
static const ilp_sched_selector_t *TEMPLATE_get_ilp_sched_selector(
const void *self)
{
(void) self;
return NULL;
}
/**
* Returns the necessary byte alignment for storing a register of given class.
*/
......@@ -413,21 +380,6 @@ static const backend_params *TEMPLATE_get_backend_params(void)
return &p;
}
static const be_execution_unit_t ***TEMPLATE_get_allowed_execution_units(
const ir_node *irn)
{
(void) irn;
/* TODO */
return NULL;
}
static const be_machine_t *TEMPLATE_get_machine(const void *self)
{
(void) self;
/* TODO */
return NULL;
}
static ir_graph **TEMPLATE_get_backend_irg_list(const void *self,
ir_graph ***irgs)
{
......@@ -456,12 +408,8 @@ const arch_isa_if_t TEMPLATE_isa_if = {
TEMPLATE_get_reg_class,
TEMPLATE_get_reg_class_for_mode,
TEMPLATE_get_call_abi,
TEMPLATE_get_list_sched_selector,
TEMPLATE_get_ilp_sched_selector,
TEMPLATE_get_reg_class_alignment,
TEMPLATE_get_backend_params,
TEMPLATE_get_allowed_execution_units,
TEMPLATE_get_machine,
TEMPLATE_get_backend_irg_list,
NULL, /* mark remat */
TEMPLATE_parse_asm_constraint,
......
......@@ -505,39 +505,6 @@ static void amd64_get_call_abi(const void *self, ir_type *method_type,
}
}
static int amd64_to_appear_in_schedule(void *block_env, const ir_node *irn)
{
(void) block_env;
if(!is_amd64_irn(irn))
return -1;
return 1;
}
list_sched_selector_t amd64_sched_selector;
/**
* Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
*/
static const list_sched_selector_t *amd64_get_list_sched_selector(
const void *self, list_sched_selector_t *selector)
{
(void) self;
(void) selector;
amd64_sched_selector = trivial_selector;
amd64_sched_selector.to_appear_in_schedule = amd64_to_appear_in_schedule;
return &amd64_sched_selector;
}
static const ilp_sched_selector_t *amd64_get_ilp_sched_selector(
const void *self)
{
(void) self;
return NULL;
}
/**
* Returns the necessary byte alignment for storing a register of given class.
*/
......@@ -571,23 +538,6 @@ static const backend_params *amd64_get_backend_params(void) {
return &p;
}
static const be_execution_unit_t ***amd64_get_allowed_execution_units(
const ir_node *irn)
{
(void) irn;
/* TODO */
assert(0);
return NULL;
}
static const be_machine_t *amd64_get_machine(const void *self)
{
(void) self;
/* TODO */
assert(0);
return NULL;
}
static ir_graph **amd64_get_backend_irg_list(const void *self,
ir_graph ***irgs)
{
......@@ -616,12 +566,8 @@ const arch_isa_if_t amd64_isa_if = {
amd64_get_reg_class,
amd64_get_reg_class_for_mode,
amd64_get_call_abi,
amd64_get_list_sched_selector,
amd64_get_ilp_sched_selector,
amd64_get_reg_class_alignment,
amd64_get_backend_params,
amd64_get_allowed_execution_units,
amd64_get_machine,
amd64_get_backend_irg_list,
NULL, /* mark remat */
amd64_parse_asm_constraint,
......
......@@ -50,7 +50,6 @@
#include "../besched.h"
#include "be.h"
#include "../bemachine.h"
#include "../beilpsched.h"
#include "../bemodule.h"
#include "../beirg.h"
#include "../bespillslots.h"
......@@ -514,36 +513,6 @@ static const arch_register_class_t *arm_get_reg_class_for_mode(const ir_mode *mo
return &arm_reg_classes[CLASS_arm_gp];
}
static int arm_to_appear_in_schedule(void *block_env, const ir_node *irn)
{
(void) block_env;
if (!is_arm_irn(irn))
return -1;
return 1;
}
list_sched_selector_t arm_sched_selector;
/**
* Returns the reg_pressure scheduler with to_appear_in_schedule() over\loaded
*/
static const list_sched_selector_t *arm_get_list_sched_selector(const void *self, list_sched_selector_t *selector)
{
(void) self;
memcpy(&arm_sched_selector, selector, sizeof(arm_sched_selector));
/* arm_sched_selector.exectime = arm_sched_exectime; */
arm_sched_selector.to_appear_in_schedule = arm_to_appear_in_schedule;
return &arm_sched_selector;
}
static const ilp_sched_selector_t *arm_get_ilp_sched_selector(const void *self)
{
(void) self;
return NULL;
}
/**
* Returns the necessary byte alignment for storing a register of given class.
*/
......@@ -554,20 +523,6 @@ static int arm_get_reg_class_alignment(const arch_register_class_t *cls)
return 4;
}
static const be_execution_unit_t ***arm_get_allowed_execution_units(const ir_node *irn)
{
(void) irn;
/* TODO */
panic("Unimplemented arm_get_allowed_execution_units()");
}
static const be_machine_t *arm_get_machine(const void *self)
{
(void) self;
/* TODO */
panic("Unimplemented arm_get_machine()");
}
/**
* Return irp irgs in the desired order.
*/
......@@ -675,12 +630,8 @@ const arch_isa_if_t arm_isa_if = {
arm_get_reg_class,
arm_get_reg_class_for_mode,
NULL,
arm_get_list_sched_selector,
arm_get_ilp_sched_selector,
arm_get_reg_class_alignment,
arm_get_libfirm_params,
arm_get_allowed_execution_units,
arm_get_machine,
arm_get_irg_list,
NULL, /* mark remat */
arm_parse_asm_constraint,
......
......@@ -58,11 +58,6 @@ enum {
BE_VERIFY_ASSERT
};
enum {
BE_SCHED_LIST,
BE_SCHED_ILP
};
/** Backend options */
struct be_options_t {
unsigned dump_flags; /**< backend dumping flags */
......@@ -73,7 +68,6 @@ struct be_options_t {
int pic; /**< create position independent code */
int gprof; /**< create gprof compatible profiling code */
int verify_option; /**< backend verify option */
int scheduler; /**< the scheduler */
char target_os[128]; /**< target operating system name */
char ilp_server[128]; /**< the ilp server name */
char ilp_solver[128]; /**< the ilp solver name */
......
......@@ -47,8 +47,8 @@ typedef enum arch_irn_flags_t {
default check_modifies
implementation in beflags */
arch_irn_flags_simple_jump = 1U << 3, /**< a simple jump instruction */
arch_irn_flags_backend = 1U << 4, /**< begin of custom backend
arch_irn_flags_not_scheduled = 1U << 4, /**< node must not be scheduled*/
arch_irn_flags_backend = 1U << 5, /**< begin of custom backend
flags */
} arch_irn_flags_t;
......
......@@ -511,24 +511,6 @@ struct arch_isa_if_t {
void (*get_call_abi)(const void *self, ir_type *call_type,
be_abi_call_t *abi);
/**
* Get the list scheduler to use. There is already a selector given, the
* backend is free to modify and/or ignore it.
*
* @param self The isa object.
* @param selector The selector given by options.
* @return The list scheduler selector.
*/
const list_sched_selector_t *(*get_list_sched_selector)(const void *self,
list_sched_selector_t *selector);
/**
* Get the ILP scheduler to use.
* @param self The isa object.
* @return The ILP scheduler selector
*/
const ilp_sched_selector_t *(*get_ilp_sched_selector)(const void *self);
/**
* Get the necessary alignment for storing a register of given class.
* @param self The isa object.
......@@ -543,30 +525,6 @@ struct arch_isa_if_t {
*/
const backend_params *(*get_params)(void);
/**
* Returns an 2-dim array of execution units, @p irn can be executed on.
* The first dimension is the type, the second the allowed units of this
* type.
* Each dimension is a NULL terminated list.
* @param self The isa object.
* @param irn The node.
* @return An array of allowed execution units.
* exec_unit = {
* { unit1_of_tp1, ..., unitX1_of_tp1, NULL },
* ...,
* { unit1_of_tpY, ..., unitXn_of_tpY, NULL },
* NULL
* };
*/
const be_execution_unit_t ***(*get_allowed_execution_units)(
const ir_node *irn);
/**
* Return the abstract machine for this isa.
* @param self The isa object.
*/
const be_machine_t *(*get_machine)(const void *self);
/**
* Return an ordered list of irgs where code should be generated for.
* If NULL is returned, all irg will be taken into account and they will be
......@@ -650,8 +608,6 @@ struct arch_isa_if_t {
#define arch_env_get_reg_class(env,i) ((env)->impl->get_reg_class(i))
#define arch_env_get_reg_class_for_mode(env,mode) ((env)->impl->get_reg_class_for_mode((mode)))
#define arch_env_get_call_abi(env,tp,abi) ((env)->impl->get_call_abi((env), (tp), (abi)))
#define arch_env_get_list_sched_selector(env,selector) ((env)->impl->get_list_sched_selector((env), (selector)))
#define arch_env_get_ilp_sched_selector(env) ((env)->impl->get_ilp_sched_selector(env))
#define arch_env_get_reg_class_alignment(env,cls) ((env)->impl->get_reg_class_alignment((cls)))
#define arch_env_get_params(env) ((env)->impl->get_params())
#define arch_env_get_allowed_execution_units(env,irn) ((env)->impl->get_allowed_execution_units((irn)))
......
This diff is collapsed.
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief ILP based instruction scheduling.
* @author Christian Wuerdig
* @date 22.10.2006
* @version $Id$
*
* An ILP scheduler based on
* "ILP-based Instruction Scheduling for IA-64"
* by Daniel Kaestner and Sebastian Winkel
* extended with register pressure constraints by Christian Wuerdig
*/
#ifndef FIRM_BE_BEILPSCHED_H
#define FIRM_BE_BEILPSCHED_H
#include "irgraph.h"
#include "irnode.h"
#include "be_types.h"
/**
* A selector interface which is used by the ILP schedule framework.
* These functions provide the ILP scheduler with necessary information
* from the backend or they pass back information to the backend about
* the state of scheduling.
*/
struct ilp_sched_selector_if_t {
/**
* This function is called before the scheduling of the irg.
* @param self The this pointer.
* @param irg The irg being scheduled.
* @return An irg scheduling environment.
*/
void *(*init_irg_ilp_schedule)(const void *self, ir_graph *irg);
/**
* This functions is called after an irg has been scheduled.
* @param self The this pointer.
* @param irg The irg which has been scheduled.
* @param irg_env The irg scheduling environment.
*/
void (*finish_irg_ilp_schedule)(const void *self, ir_graph *irg, void *irg_env);
/**
* This function is called before the scheduling of a block starts.
* @param self The this pointer.
* @param block The block being scheduled.
* @return A block scheduling environment.
*/
void *(*init_block_ilp_schedule)(const void *self, ir_node *block);
/**
* This functions is called after a block has been scheduled.
* @param self The this pointer.
* @param block The block which has been scheduled.
* @param block_env The block scheduling environment.
*/
void (*finish_block_ilp_schedule)(const void *self, ir_node *block, void *block_env);
/**
* Calculates the latency of node @p irn.
* @param self The this pointer.
* @param irn The node.
* @param block_env The block scheduling environment.
* @return The latency in cycles of node @p irn.
*/
unsigned (*latency)(const void *self, ir_node *irn, void *block_env);
/**
* This function is called after a certain node has been scheduled.
* @param self The this pointer.
* @param irn The node which has been scheduled.
* @param cycle The cycle at which the node is scheduled.
* @param block_env The block scheduling environment.
*/
void (*node_scheduled)(const void *self, const ir_node *irn, unsigned cycle, void *block_env);
};
/**
* The actual ILP schedule selector.
*/
struct ilp_sched_selector_t {
ilp_sched_selector_if_t *impl;
};
/**
* Some helper macros.
*/
#define BE_ILP_SCHED_CALL(func, self, obj, env) \
do { \
if ((self) && (self)->impl->func) \
(self)->impl->func((self), (obj), (env)); \
} while (0)
#define BE_ILP_SCHED_CALL2(func, self, obj, obj2, env) \
do { \
if ((self) && (self)->impl->func) \
(self)->impl->func((self), (obj), (obj2), (env)); \
} while (0)
#define BE_ILP_SCHED_CALL_ENVRET(func, self, obj, defret) \
((self) && (self)->impl->func ? (self)->impl->func((self), (obj)) : (defret))
#define BE_ILP_SCHED_CALL_RET(func, self, obj, env, defret) \
((self) && (self)->impl->func ? (self)->impl->func((self), (obj), (env)) : (defret))
/**
* Convenience macros for all functions.
*/
#define be_ilp_sched_init_irg_ilp_schedule(self, irg) \
BE_ILP_SCHED_CALL_ENVRET(init_irg_ilp_schedule, self, irg, NULL)
#define be_ilp_sched_finish_irg_ilp_schedule(self, irg, irg_env) \
BE_ILP_SCHED_CALL(finish_irg_ilp_schedule, self, irg, irg_env)
#define be_ilp_sched_init_block_ilp_schedule(self, block) \
BE_ILP_SCHED_CALL_ENVRET(init_block_ilp_schedule, self, block, NULL)
#define be_ilp_sched_finish_block_ilp_schedule(self, block, block_env) \
BE_ILP_SCHED_CALL(finish_block_ilp_schedule, self, block, block_env)
#define be_ilp_sched_latency(self, irn, block_env) \
BE_ILP_SCHED_CALL_RET(latency, self, irn, block_env, 0)
#define be_ilp_sched_node_scheduled(self, irn, cycle, block_env) \
BE_ILP_SCHED_CALL2(node_scheduled, self, irn, cycle, block_env)
/**
* Perform ILP scheduling on given irg.
*/
void be_ilp_sched(ir_graph *irg);
#endif
......@@ -64,8 +64,6 @@
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL);
#define BE_SCHED_NODE(irn) (be_is_Keep(irn) || be_is_CopyKeep(irn) || be_is_Start(irn))
enum {
BE_SCHED_SELECT_TRIVIAL,
BE_SCHED_SELECT_REGPRESS,
......@@ -156,24 +154,6 @@ typedef struct block_sched_env_t {
void *selector_block_env;
} block_sched_env_t;
/**
* Returns non-zero if a node must be placed in the schedule.
*/
static inline int must_appear_in_schedule(const list_sched_selector_t *sel, void *block_env, const ir_node *irn)
{
int res = -1;
/* if there are no uses, don't schedule */
if (get_irn_n_edges(irn) < 1)
return 0;
/* else ask the scheduler */
if (sel->to_appear_in_schedule)
res = sel->to_appear_in_schedule(block_env, irn);
return res >= 0 ? res : ((to_appear_in_schedule(irn) || BE_SCHED_NODE(irn)) && ! is_Unknown(irn));
}
/**
* Returns non-zero if the node is already scheduled
*/
......@@ -235,7 +215,7 @@ static inline int make_ready(block_sched_env_t *env, ir_node *pred, ir_node *irn
return 0;
}
if (! must_appear_in_schedule(env->selector, env, irn)) {
if (! to_appear_in_schedule(irn)) {
add_to_sched(env, irn);
DB((dbg, LEVEL_3, "\tmaking immediately available: %+F\n", irn));
} else {
......@@ -393,13 +373,13 @@ static void add_to_sched(block_sched_env_t *env, ir_node *irn)
{
/* If the node consumes/produces data, it is appended to the schedule
* list, otherwise, it is not put into the list */
if (must_appear_in_schedule(env->selector, env->selector_block_env, irn)) {
if (to_appear_in_schedule(irn)) {
update_sched_liveness(env, irn);
sched_add_before(env->block, irn);
DBG((dbg, LEVEL_2, "\tadding %+F\n", irn));
/* Remove the node from the ready set */
/* Remove the node from the ready set */
ir_nodeset_remove(&env->cands, irn);
}
......@@ -549,18 +529,18 @@ void list_sched(ir_graph *irg)
int num_nodes;
sched_env_t env;
mris_env_t *mris = NULL;
list_sched_selector_t sel;
const list_sched_selector_t *selector;
/* Select a scheduler based on backend options */
switch (list_sched_options.select) {
case BE_SCHED_SELECT_TRIVIAL: sel = trivial_selector; break;
case BE_SCHED_SELECT_RANDOM: sel = random_selector; break;
case BE_SCHED_SELECT_REGPRESS: sel = reg_pressure_selector; break;
case BE_SCHED_SELECT_MUCHNIK: sel = muchnik_selector; break;
case BE_SCHED_SELECT_HEUR: sel = heuristic_selector; break;
case BE_SCHED_SELECT_NORMAL: sel = normal_selector; break;
case BE_SCHED_SELECT_TRIVIAL: selector = &trivial_selector; break;
case BE_SCHED_SELECT_RANDOM: selector = &random_selector; break;
case BE_SCHED_SELECT_REGPRESS: selector = &reg_pressure_selector; break;
case BE_SCHED_SELECT_MUCHNIK: selector = &muchnik_selector; break;
case BE_SCHED_SELECT_HEUR: selector = &heuristic_selector; break;
case BE_SCHED_SELECT_NORMAL: selector = &normal_selector; break;
default:
case BE_SCHED_SELECT_HMUCHNIK: sel = heuristic_selector; break;
case BE_SCHED_SELECT_HMUCHNIK: selector = &heuristic_selector; break;
}
#if 1
......@@ -589,7 +569,7 @@ void list_sched(ir_graph *irg)
/* initialize environment for list scheduler */
memset(&env, 0, sizeof(env));
env.selector = arch_env_get_list_sched_selector(be_get_irg_arch_env(irg), &sel);
env.selector = selector;
env.sched_info = NEW_ARR_F(sched_irn_t, num_nodes);
memset(env.sched_info, 0, num_nodes * sizeof(env.sched_info[0]));
......@@ -614,18 +594,18 @@ void list_sched_single_block(ir_graph *irg, ir_node *block)
{
int num_nodes;
sched_env_t env;
list_sched_selector_t sel;
const list_sched_selector_t *selector;
/* Select a scheduler based on backend options */
switch (list_sched_options.select) {
case BE_SCHED_SELECT_TRIVIAL: sel = trivial_selector; break;
case BE_SCHED_SELECT_RANDOM: sel = random_selector; break;
case BE_SCHED_SELECT_REGPRESS: sel = reg_pressure_selector; break;
case BE_SCHED_SELECT_MUCHNIK: sel = muchnik_selector; break;
case BE_SCHED_SELECT_HEUR: sel = heuristic_selector; break;
case BE_SCHED_SELECT_NORMAL: sel = normal_selector; break;
case BE_SCHED_SELECT_TRIVIAL: selector = &trivial_selector; break;
case BE_SCHED_SELECT_RANDOM: selector = &random_selector; break;
case BE_SCHED_SELECT_REGPRESS: selector = &reg_pressure_selector; break;
case BE_SCHED_SELECT_MUCHNIK: selector = &muchnik_selector; break;
case BE_SCHED_SELECT_HEUR: selector = &heuristic_selector; break;
case BE_SCHED_SELECT_NORMAL: selector = &normal_selector; break;
default:
case BE_SCHED_SELECT_HMUCHNIK: sel = trivial_selector; break;
case BE_SCHED_SELECT_HMUCHNIK: selector = &trivial_selector; break;
}
/* Assure, that the out edges are computed */
......@@ -636,7 +616,7 @@ void list_sched_single_block(ir_graph *irg, ir_node *block)
/* initialize environment for list scheduler */
memset(&env, 0, sizeof(env));
env.selector = arch_env_get_list_sched_selector(be_get_irg_arch_env(irg), &sel);
env.selector = selector;
env.sched_info = NEW_ARR_F(sched_irn_t, num_nodes);
memset(env.sched_info, 0, num_nodes * sizeof(env.sched_info[0]));
......
......@@ -77,16 +77,6 @@ struct list_sched_selector_t {
ir_node *(*select)(void *block_env, ir_nodeset_t *ready_set,
ir_nodeset_t *live_set);
/**
* This function decides, if a node should appear in a schedule.
* May be NULL.
*
* @param block_env The block environment.
* @param irn The node.
* @return 1, if the node should be scheduled, 0 if not.
*/
int (*to_appear_in_schedule)(void *block_env, const ir_node *irn);
/**
* This function gets executed after a node finally has been made ready.
* May be NULL.
......
......@@ -77,10 +77,6 @@