Commit 546bbbe4 authored by Matthias Braun's avatar Matthias Braun
Browse files

remove support for schedule preparation steps (both are unmaintained and broken)

parent 7a2c7fed
......@@ -67,11 +67,6 @@ typedef struct be_stack_layout_t be_stack_layout_t;
typedef struct be_dom_front_info_t be_dom_front_info_t;
typedef struct list_sched_selector_t list_sched_selector_t;
typedef struct ilp_sched_selector_t ilp_sched_selector_t;
typedef struct ilp_sched_selector_if_t ilp_sched_selector_if_t;
typedef struct be_execution_unit_type_t be_execution_unit_type_t;
typedef struct be_execution_unit_t be_execution_unit_t;
typedef struct be_machine_t be_machine_t;
......
......@@ -53,8 +53,6 @@
#include "beutil.h"
#include "belive_t.h"
#include "belistsched.h"
#include "beschedmris.h"
#include "beschedrss.h"
#include "bearch.h"
#include "bestat.h"
#include "beirg.h"
......@@ -82,12 +80,10 @@ enum {
typedef struct list_sched_options_t {
int select; /**< the node selector */
int prep; /**< schedule preparation */
} list_sched_options_t;
static list_sched_options_t list_sched_options = {
BE_SCHED_SELECT_NORMAL, /* mueller heuristic selector */
BE_SCHED_PREP_NONE, /* no scheduling preparation */
};
/* schedule selector options. */
......@@ -102,24 +98,11 @@ static const lc_opt_enum_int_items_t sched_select_items[] = {
{ NULL, 0 }
};
/* schedule preparation options. */
static const lc_opt_enum_int_items_t sched_prep_items[] = {
{ "none", BE_SCHED_PREP_NONE },
{ "mris", BE_SCHED_PREP_MRIS },
{ "rss", BE_SCHED_PREP_RSS },
{ NULL, 0 }
};
static lc_opt_enum_int_var_t sched_select_var = {
&list_sched_options.select, sched_select_items
};
static lc_opt_enum_int_var_t sched_prep_var = {
&list_sched_options.prep, sched_prep_items
};
static const lc_opt_table_entry_t list_sched_option_table[] = {
LC_OPT_ENT_ENUM_PTR("prep", "schedule preparation", &sched_prep_var),
LC_OPT_ENT_ENUM_PTR("select", "node selector", &sched_select_var),
LC_OPT_LAST
};
......@@ -523,7 +506,6 @@ void list_sched(ir_graph *irg)
{
int num_nodes;
sched_env_t env;
mris_env_t *mris = NULL;
const list_sched_selector_t *selector;
/* Select a scheduler based on backend options */
......@@ -549,17 +531,6 @@ void list_sched(ir_graph *irg)
edges_activate(irg);
#endif
switch (list_sched_options.prep) {
case BE_SCHED_PREP_MRIS:
mris = be_sched_mris_preprocess(irg);
break;
case BE_SCHED_PREP_RSS:
rss_schedule_preparation(irg);
break;
default:
break;
}
num_nodes = get_irg_last_idx(irg);
/* initialize environment for list scheduler */
......@@ -578,9 +549,6 @@ void list_sched(ir_graph *irg)
if (env.selector->finish_graph)
env.selector->finish_graph(env.selector_env);
if (list_sched_options.prep == BE_SCHED_PREP_MRIS)
be_sched_mris_free(mris);
DEL_ARR_F(env.sched_info);
}
......
......@@ -68,7 +68,6 @@
#include "bessadestr.h"
#include "beabi.h"
#include "belower.h"
#include "beschedmris.h"
#include "bestat.h"
#include "beverify.h"
#include "be_dbgout.h"
......
......@@ -38,7 +38,6 @@ void be_init_blocksched(void);
void be_init_spill(void);
void be_init_spilloptions(void);
void be_init_listsched(void);
void be_init_schedrss(void);
void be_init_chordal(void);
void be_init_pbqp_coloring(void);
void be_init_chordal_main(void);
......@@ -99,7 +98,6 @@ void be_init_modules(void)
be_init_spilloptions();
be_init_dbgout();
be_init_listsched();
be_init_schedrss();
be_init_chordal_main();
be_init_chordal_common();
be_init_chordal();
......
/*
* 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 Implements a list scheduler for the MRIS algorithm.
* @author Sebastian Hack
* @date 04.04.2006
* @version $Id$
*
* Implements a list scheduler for the MRIS algorithm in:
* Govindarajan, Yang, Amaral, Zhang, Gao
* Minimum Register Instruction Sequencing to Reduce Register Spills
* in out-of-order issue superscalar architectures
*/
#include "config.h"
#include <limits.h>
#include "obst.h"
#include "debug.h"
#include "irgraph_t.h"
#include "irnode_t.h"
#include "iredges_t.h"
#include "ircons_t.h"
#include "irphase_t.h"
#include "irdump_t.h"
#include "irgwalk.h"
#include "irtools.h"
#include "irbitset.h"
#include "irnodeset.h"
#include "heights.h"
#include "benode.h"
#include "besched.h"
#include "beschedmris.h"
#include "beirg.h"
#include "belistsched.h"
struct mris_env_t {
ir_phase ph;
ir_heights_t *heights;
ir_graph *irg;
ir_node *bl;
int visited;
struct list_head lineage_head;
struct obstack obst;
DEBUG_ONLY(firm_dbg_module_t *dbg;)
};
typedef struct mris_irn_t {
int visited;
ir_node *lineage_start;
ir_node *lineage_next;
ir_node *lineage_end;
struct list_head lineage_list;
} mris_irn_t;
#define to_appear(env, irn) (to_appear_in_schedule(irn) && get_nodes_block(irn) == env->bl)
#define get_mris_irn(env, irn) ((mris_irn_t *) phase_get_or_set_irn_data(&env->ph, irn))
#define foreach_lineage(env, pos, tmp) list_for_each_entry_safe(mris_irn_t, pos, tmp, &(env)->lineage_head, lineage_list)
static void *mris_irn_data_init(ir_phase *ph, const ir_node *irn)
{
mris_irn_t *mi = (mris_irn_t*)phase_alloc(ph, sizeof(mi[0]));
(void) irn;
memset(mi, 0, sizeof(mi[0]));
INIT_LIST_HEAD(&mi->lineage_list);
return mi;
}
#define valid_node(env, dep) (to_appear(env, dep) && !be_is_Keep(dep))
static void grow_all_descendands(mris_env_t *env, ir_node *irn, bitset_t *visited)
{
const ir_edge_t *edge;
// assert(get_irn_mode(irn) != mode_T);
foreach_out_edge(irn, edge) {
ir_node *desc = get_edge_src_irn(edge);
if (valid_node(env, desc) && !bitset_contains_irn(visited, desc)) {
obstack_ptr_grow(&env->obst, desc);
bitset_add_irn(visited, desc);
}
}
foreach_out_edge_kind(irn, edge, EDGE_KIND_DEP) {
ir_node *desc = get_edge_src_irn(edge);
if (valid_node(env, desc) && !bitset_contains_irn(visited, desc)) {
obstack_ptr_grow(&env->obst, desc);
bitset_add_irn(visited, desc);
}
}
}
static ir_node **all_descendants(mris_env_t *env, ir_node *irn)
{
bitset_t *visited = bitset_irg_malloc(env->irg);
grow_all_descendands(env, irn, visited);
#if 0
if (get_irn_mode(irn) == mode_T) {
const ir_edge_t *edge;
foreach_out_edge(irn, edge) {
ir_node *desc = get_edge_src_irn(edge);
assert(is_Proj(desc) && get_irn_mode(desc) != mode_T);
grow_all_descendands(env, desc, visited);
}
}
else
grow_all_descendands(env, irn, visited);
#endif
bitset_free(visited);
obstack_ptr_grow(&env->obst, NULL);
return (ir_node**)obstack_finish(&env->obst);
}
static ir_node *put_lowest_in_front(mris_env_t *env, ir_node **in)
{
int lowest_index = 0;
unsigned lowest_height = INT_MAX;
int i;
for (i = 0; in[i]; ++i) {
unsigned height = get_irn_height(env->heights, in[i]);
if (height < lowest_height) {
lowest_height = height;
lowest_index = i;
}
}
if (i > 0) {
ir_node *tmp = in[0];
in[0] = in[lowest_index];
in[lowest_index] = tmp;
}
return in[0];
}
static inline ir_node *skip_Projs(ir_node *irn)
{
return is_Proj(irn) ? skip_Projs(get_Proj_pred(irn)) : irn;
}
static void lineage_formation(mris_env_t *env)
{
DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg);
ir_nodeset_t nodes;
const ir_edge_t *edge;
ir_nodeset_init(&nodes);
foreach_out_edge(env->bl, edge) {
ir_node *irn = get_edge_src_irn(edge);
if (to_appear(env, irn))
ir_nodeset_insert(&nodes, irn);
}
while (ir_nodeset_size(&nodes) > 0) {
mris_irn_t *mi;
ir_node *irn;
ir_node *highest_node = NULL;
ir_node *lowest_desc = NULL;
ir_node *start;
mris_irn_t *start_mi;
ir_nodeset_iterator_t iter;
ir_node **in;
int recompute_height = 0;
unsigned curr_height = 0;
/* search the highest node which is not yet in a lineage. */
foreach_ir_nodeset(&nodes, irn, iter) {
unsigned height = get_irn_height(env->heights, irn);
if (height > curr_height) {
highest_node = irn;
curr_height = height;
}
}
assert(highest_node);
DBG((dbg, LEVEL_2, "highest node is %+F height %d\n", highest_node, get_irn_height(env->heights, highest_node)));
start = highest_node;
mi = start_mi = get_mris_irn(env, highest_node);
/* start a lineage beginning with highest_node. */
mi->lineage_start = highest_node;
mi->lineage_next = NULL;
mi->lineage_end = NULL;
list_add(&mi->lineage_list, &env->lineage_head);
ir_nodeset_remove(&nodes, highest_node);
/*
put all descendants in an array.
we also move the lowest descendant in front, so that the other nodes
are easily accessible as an array, too.
*/
in = all_descendants(env, highest_node);
lowest_desc = put_lowest_in_front(env, in);
/* as long as the current highest node has still descendants */
while (lowest_desc) {
mris_irn_t *lowest_mi = get_mris_irn(env, lowest_desc);
mris_irn_t *highest_mi = get_mris_irn(env, highest_node);
int n_desc;
DBG((dbg, LEVEL_2, "\tlowest descendant %+F height %d\n", lowest_desc, get_irn_height(env->heights, lowest_desc)));
/* count the number of all descendants which are not the lowest descendant */
for (n_desc = 0; in[n_desc]; ++n_desc) {
}
/*
we insert a CopyKeep node to express the artificial dependencies from the lowest
descendant to all other descendants.
*/
if (n_desc > 1 && !be_is_Keep(lowest_desc)) {
ir_node *op;
int i, n;
for (i = 0, n = get_irn_ins_or_deps(lowest_desc); i < n; ++i) {
op = get_irn_in_or_dep(lowest_desc, i);
if (op == highest_node)
break;
}
assert(i < n && "could not find operand");
//replace_tuple_by_repr_proj(env, &in[1]);
if (!is_Proj(lowest_desc))
add_irn_dep(lowest_desc, in[1]);
}
obstack_free(&env->obst, in);
/* if the current lowest node is not yet in a lineage, add it to the current one. */
if (!lowest_mi->lineage_start) {
/* mark the current lowest node as the last one in the lineage. */
highest_mi->lineage_next = lowest_desc;
start_mi->lineage_end = lowest_desc;
lowest_mi->lineage_start = start;
ir_nodeset_remove(&nodes, lowest_desc);
}
/* else we cannot extend this lineage, so break. */
else
break;
highest_node = lowest_desc;
highest_mi = lowest_mi;
/* recompute the descendants array and the new lowest descendant. */
in = all_descendants(env, highest_node);
lowest_desc = put_lowest_in_front(env, in);
}
/* recompute the heights if desired. */
if (recompute_height)
heights_recompute(env->heights);
}
ir_nodeset_destroy(&nodes);
}
static int fuse_two_lineages(mris_env_t *env, mris_irn_t *u, mris_irn_t *v)
{
mris_irn_t *mi;
ir_node *irn, *last;
ir_node *u_end = u->lineage_end;
ir_node *v_start = v->lineage_start;
ir_node *start = skip_Projs(v_start);
if (be_is_Keep(start))
return 0;
/* set lineage end of nodes in u to end of v. */
irn = last = u->lineage_start;
mi = get_mris_irn(env, irn);
while (irn && irn != u_end) {
mi = get_mris_irn(env, irn);
mi->lineage_end = v->lineage_end;
last = irn;
irn = mi->lineage_next;
}
/* insert a CopyKeep to make lineage v dependent on u. */
if (get_irn_ins_or_deps(start) == 0)
return 0;
if (get_irn_mode(last) == mode_T) {
const ir_edge_t *edge = get_irn_out_edge_first(last);
last = get_edge_src_irn(edge);
}
/* irn now points to the last node in lineage u; mi has the info for the node _before_ the terminator of the lineage. */
mi->lineage_next = v_start;
/* add a dependency from the first node in v's lineage to the last in u's */
add_irn_dep(u_end, v_start);
/* set lineage start of nodes in v to start of u. */
irn = v->lineage_start;
while (irn && irn != v->lineage_end) {
mris_irn_t *mi = get_mris_irn(env, irn);
mi->lineage_start = u->lineage_start;
irn = mi->lineage_next;
}
heights_recompute(env->heights);
mi = get_mris_irn(env, v_start);
list_del(&mi->lineage_list);
return 1;
}
static void fuse_lineages(mris_env_t *env)
{
mris_irn_t *u, *v, *tmp1, *tmp2;
again:
foreach_lineage(env, u, tmp1) {
foreach_lineage(env, v, tmp2) {
if (u != v && u->lineage_start && v->lineage_start && u->lineage_end && v->lineage_end
&& get_nodes_block(u->lineage_start) == get_nodes_block(v->lineage_start)) {
int uv = heights_reachable_in_block(env->heights, u->lineage_start, v->lineage_end);
int vu = heights_reachable_in_block(env->heights, v->lineage_start, u->lineage_end);
if (uv && !vu) {
if (fuse_two_lineages(env, u, v))
goto again;
}
}
}
}
}
static mris_env_t *dump_env = NULL;
static void block_walker(ir_node *bl, void *data)
{
mris_env_t *env = (mris_env_t*)data;
env->bl = bl;
lineage_formation(env);
fuse_lineages(env);
}
static void mris_edge_hook(FILE *F, ir_node *irn)
{
mris_irn_t *mi = get_mris_irn(dump_env, irn);
if (mi->lineage_next) {
fprintf(F, "edge:{sourcename:\"");
PRINT_NODEID(mi->lineage_next);
fprintf(F, "\" targetname:\"");
PRINT_NODEID(irn);
fprintf(F, "\" color:lilac}\n");
}
}
void dump_ir_block_graph_mris(mris_env_t *env, const char *suffix)
{
dump_node_edge_func old = get_dump_node_edge_hook();
set_dump_node_edge_hook(mris_edge_hook);
dump_env = env;
dump_ir_graph(env->irg, suffix);
set_dump_node_edge_hook(old);
}
mris_env_t *be_sched_mris_preprocess(ir_graph *irg)
{
mris_env_t *env = XMALLOC(mris_env_t);
phase_init(&env->ph, irg, mris_irn_data_init);
env->irg = irg;
env->visited = 0;
env->heights = heights_new(irg);
INIT_LIST_HEAD(&env->lineage_head);
FIRM_DBG_REGISTER(env->dbg, "firm.be.sched.mris");
obstack_init(&env->obst);
irg_walk_graph(irg, firm_clear_link, NULL, NULL);
irg_block_walk_graph(irg, block_walker, NULL, env);
obstack_free(&env->obst, NULL);
// dump_ir_block_graph_mris(env, "-mris");
return env;
}
void be_sched_mris_free(mris_env_t *env)
{
phase_deinit(&env->ph);
heights_free(env->heights);
free(env);
}
/*
* 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 Implements a list scheduler for the MRIS algorithm.
* @author Sebastian Hack
* @date 04.04.2006
* @version $Id$
*
* Implements a list scheduler for the MRIS algorithm in:
* Govindarajan, Yang, Amaral, Zhang, Gao
* Minimum Register Instruction Sequencing to Reduce Register Spills
* in out-of-order issue superscalar architectures
*/
#ifndef FIRM_BE_BESCHEDMRIS_H
#define FIRM_BE_BESCHEDMRIS_H
#include "beirg.h"
typedef struct mris_env_t mris_env_t;
/**
* Preprocess the irg with the MRIS algorithm.
* @param irg The graph
* @return Private data to be kept.
*/
mris_env_t *be_sched_mris_preprocess(ir_graph *irg);
/**
* Cleanup the MRIS preprocessing.
* @param env The private data as returned by be_sched_mris_preprocess().
*/
void be_sched_mris_free(mris_env_t *env);
/**
* Dump IR graph with lineages.
*/
void dump_ir_block_graph_mris(mris_env_t *env, const char *suffix);
#endif
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 Implementation of a register saturating list scheduler.
* @author Christian Wuerdig
* @date 06.09.2006
* @version $Id$
*
* Implementation of a register saturating list scheduler
* as described in: Sid-Ahmed-Ali Touati
* Register Saturation in Superscalar and VLIW Codes
*/
#ifndef FIRM_BE_BESCHEDRSS_H
#define FIRM_BE_BESCHEDRSS_H