Commit 4a965e7a authored by Matthias Braun's avatar Matthias Braun
Browse files

merge be_add_missing_keeps() with be_spill_preapre_for_constraints()

parent 89434d4d
......@@ -26,7 +26,6 @@
#include "bemodule.h"
#include "begnuas.h"
#include "belistsched.h"
#include "bera.h"
#include "bestack.h"
#include "bespillutil.h"
......@@ -99,7 +98,7 @@ static void TEMPLATE_emit(ir_graph *irg)
static void TEMPLATE_before_ra(ir_graph *irg)
{
be_add_missing_keeps(irg);
(void)irg;
}
......
......@@ -15,7 +15,6 @@
#include "belower.h"
#include "bemodule.h"
#include "benode.h"
#include "bera.h"
#include "besched.h"
#include "bespillslots.h"
#include "bespillutil.h"
......@@ -125,8 +124,6 @@ static const arch_irn_ops_t amd64_irn_ops = {
static void amd64_before_ra(ir_graph *irg)
{
be_sched_fix_flags(irg, &amd64_reg_classes[CLASS_amd64_flags], NULL, NULL, NULL);
be_add_missing_keeps(irg);
}
static const arch_register_req_t amd64_requirement_gp = {
......
......@@ -40,7 +40,6 @@
#include "begnuas.h"
#include "belistsched.h"
#include "beflags.h"
#include "bera.h"
#include "bestack.h"
#include "betranshlp.h"
......@@ -163,8 +162,6 @@ static void arm_emit(ir_graph *irg)
static void arm_before_ra(ir_graph *irg)
{
be_sched_fix_flags(irg, &arm_reg_classes[CLASS_arm_flags], NULL, NULL, NULL);
be_add_missing_keeps(irg);
}
static ir_entity *divsi3;
......
......@@ -27,116 +27,6 @@
#include "besched.h"
#include "beutil.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
static ir_node *add_to_keep(ir_node *last_keep,
const arch_register_class_t *cls, ir_node *node)
{
if (last_keep != NULL) {
be_Keep_add_node(last_keep, cls, node);
} else {
ir_node *in[1] = { node };
ir_node *block = get_nodes_block(node);
ir_node *schedpoint;
last_keep = be_new_Keep(block, 1, in);
schedpoint = skip_Proj(node);
if (sched_is_scheduled(schedpoint)) {
sched_add_after(schedpoint, last_keep);
}
}
return last_keep;
}
/**
* Tests whether a node has a real user and is not just kept by the End or
* Anchor node
*/
static bool has_real_user(const ir_node *node)
{
foreach_out_edge(node, edge) {
ir_node *user = get_edge_src_irn(edge);
if (!is_End(user) && !is_Anchor(user))
return true;
}
return false;
}
static void add_missing_keep_walker(ir_node *node, void *data)
{
(void)data;
ir_mode *mode = get_irn_mode(node);
ir_node *last_keep;
if (mode != mode_T) {
if (!has_real_user(node)) {
const arch_register_req_t *req = arch_get_irn_register_req(node);
const arch_register_class_t *cls = req->cls;
if (cls == NULL
|| (cls->flags & arch_register_class_flag_manual_ra)) {
return;
}
add_to_keep(NULL, cls, node);
}
return;
}
unsigned n_outs = arch_get_irn_n_outs(node);
if (n_outs <= 0)
return;
unsigned *const found_projs = rbitset_alloca(n_outs);
ir_node **const existing_projs = ALLOCANZ(ir_node*, n_outs);
foreach_out_edge(node, edge) {
ir_node *succ = get_edge_src_irn(edge);
ir_mode *mode = get_irn_mode(succ);
/* The node could be kept */
if (is_End(succ) || is_Anchor(succ))
continue;
if (mode == mode_M || mode == mode_X)
continue;
unsigned pn = get_Proj_num(succ);
existing_projs[pn] = succ;
if (!has_real_user(succ))
continue;
assert(pn < n_outs);
rbitset_set(found_projs, pn);
}
/* are keeps missing? */
last_keep = NULL;
for (unsigned i = 0; i < n_outs; ++i) {
ir_node *value;
const arch_register_req_t *req;
const arch_register_class_t *cls;
if (rbitset_is_set(found_projs, i)) {
continue;
}
req = arch_get_irn_register_req_out(node, i);
cls = req->cls;
if (cls == NULL || (cls->flags & arch_register_class_flag_manual_ra)) {
continue;
}
value = existing_projs[i];
if (value == NULL)
value = new_r_Proj(node, arch_register_class_mode(cls), i);
last_keep = add_to_keep(last_keep, cls, value);
}
}
void be_add_missing_keeps(ir_graph *irg)
{
irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
}
/** The list of register allocators */
static be_module_list_entry_t *register_allocators;
static be_ra_t *selected_allocator;
......@@ -163,5 +53,4 @@ void be_init_ra(void)
be_add_module_list_opt(be_grp, "regalloc", "register allocator",
&register_allocators, (void**) &selected_allocator);
FIRM_DBG_REGISTER(dbg, "firm.be.regalloc");
}
......@@ -25,9 +25,4 @@ void be_register_allocator(const char *name, be_ra_t *allocator);
*/
void be_allocate_registers(ir_graph *irg);
/**
* Adds a X->Proj->Keep for each output value of X which has no Proj yet
*/
void be_add_missing_keeps(ir_graph *irg);
#endif
......@@ -1229,10 +1229,113 @@ static void melt_copykeeps(constraint_env_t *cenv)
obstack_free(&obst, NULL);
}
static ir_node *add_to_keep(ir_node *last_keep,
const arch_register_class_t *cls, ir_node *node)
{
if (last_keep != NULL) {
be_Keep_add_node(last_keep, cls, node);
} else {
ir_node *in[1] = { node };
ir_node *block = get_nodes_block(node);
ir_node *schedpoint;
last_keep = be_new_Keep(block, 1, in);
schedpoint = skip_Proj(node);
if (sched_is_scheduled(schedpoint)) {
sched_add_after(schedpoint, last_keep);
}
}
return last_keep;
}
/**
* Tests whether a node has a real user and is not just kept by the End or
* Anchor node
*/
static bool has_real_user(const ir_node *node)
{
foreach_out_edge(node, edge) {
ir_node *user = get_edge_src_irn(edge);
if (!is_End(user) && !is_Anchor(user))
return true;
}
return false;
}
static void add_missing_keep_walker(ir_node *node, void *data)
{
(void)data;
ir_mode *mode = get_irn_mode(node);
ir_node *last_keep;
if (mode != mode_T) {
if (!has_real_user(node)) {
const arch_register_req_t *req = arch_get_irn_register_req(node);
const arch_register_class_t *cls = req->cls;
if (cls == NULL
|| (cls->flags & arch_register_class_flag_manual_ra)) {
return;
}
add_to_keep(NULL, cls, node);
}
return;
}
unsigned n_outs = arch_get_irn_n_outs(node);
if (n_outs <= 0)
return;
unsigned *const found_projs = rbitset_alloca(n_outs);
ir_node **const existing_projs = ALLOCANZ(ir_node*, n_outs);
foreach_out_edge(node, edge) {
ir_node *succ = get_edge_src_irn(edge);
ir_mode *mode = get_irn_mode(succ);
/* The node could be kept */
if (is_End(succ) || is_Anchor(succ))
continue;
if (mode == mode_M || mode == mode_X)
continue;
unsigned pn = get_Proj_num(succ);
existing_projs[pn] = succ;
if (!has_real_user(succ))
continue;
assert(pn < n_outs);
rbitset_set(found_projs, pn);
}
/* are keeps missing? */
last_keep = NULL;
for (unsigned i = 0; i < n_outs; ++i) {
ir_node *value;
const arch_register_req_t *req;
const arch_register_class_t *cls;
if (rbitset_is_set(found_projs, i)) {
continue;
}
req = arch_get_irn_register_req_out(node, i);
cls = req->cls;
if (cls == NULL || (cls->flags & arch_register_class_flag_manual_ra)) {
continue;
}
value = existing_projs[i];
if (value == NULL)
value = new_r_Proj(node, arch_register_class_mode(cls), i);
last_keep = add_to_keep(last_keep, cls, value);
}
}
void be_spill_prepare_for_constraints(ir_graph *irg)
{
FIRM_DBG_REGISTER(dbg_constr, "firm.be.lower.constr");
irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
constraint_env_t cenv;
cenv.irg = irg;
ir_nodehashmap_init(&cenv.op_set);
......
......@@ -19,7 +19,6 @@
#include "belower.h"
#include "bemodule.h"
#include "benode.h"
#include "bera.h"
#include "besched.h"
#include "bespillslots.h"
#include "bespillutil.h"
......@@ -754,8 +753,6 @@ static void ia32_before_ra(ir_graph *irg)
be_sched_fix_flags(irg, &ia32_reg_classes[CLASS_ia32_flags],
&flags_remat, NULL, &ia32_try_replace_flags);
simplify_remat_nodes(irg);
be_add_missing_keeps(irg);
}
static ir_node *ia32_new_spill(ir_node *value, ir_node *after)
......
......@@ -43,7 +43,6 @@
#include "belistsched.h"
#include "beflags.h"
#include "beutil.h"
#include "bera.h"
#include "betranshlp.h"
#include "bearch_sparc_t.h"
......@@ -222,8 +221,6 @@ static void sparc_before_ra(ir_graph *irg)
NULL, sparc_modifies_flags, NULL);
be_sched_fix_flags(irg, &sparc_reg_classes[CLASS_sparc_fpflags_class],
NULL, sparc_modifies_fp_flags, NULL);
be_add_missing_keeps(irg);
}
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment