Commit 0632abc1 authored by Matthias Braun's avatar Matthias Braun
Browse files

merge beirgmod.* into beutil.*

parent e353af9a
......@@ -38,9 +38,9 @@
#include "irtools.h"
#include "debug.h"
#include "bearch.h"
#include "beirgmod.h"
#include "bemodule.h"
#include "besched.h"
#include "beutil.h"
#include "be.h"
#include "panic.h"
......
......@@ -17,9 +17,9 @@
#include "bechordal.h"
#include "bechordal_t.h"
#include "beirg.h"
#include "beirgmod.h"
#include "beinsn_t.h"
#include "besched.h"
#include "beutil.h"
#include "statev_t.h"
#include "benode.h"
#include "bemodule.h"
......
......@@ -33,8 +33,8 @@
#include "beflags.h"
#include "bearch.h"
#include "beirg.h"
#include "beirgmod.h"
#include "besched.h"
#include "beutil.h"
#include "benode.h"
#include "belive.h"
#include "beabihelper.h"
......
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Backend IRG modification routines.
* @author Sebastian Hack, Daniel Grund, Matthias Braun, Christian Wuerdig
* @date 04.05.2005
*
* This file contains the following IRG modifications for be routines:
* - insertion of Perm nodes
* - empty block elimination
* - a simple dead node elimination (set inputs of unreachable nodes to BAD)
*/
#include <stdlib.h>
#include "../../adt/util.h"
#include "hashptr.h"
#include "debug.h"
#include "panic.h"
#include "xmalloc.h"
#include "irflag_t.h"
#include "ircons_t.h"
#include "irnode_t.h"
#include "ircons_t.h"
#include "irmode_t.h"
#include "irdom_t.h"
#include "iredges_t.h"
#include "irgraph_t.h"
#include "irgopt.h"
#include "irgmod.h"
#include "irgwalk.h"
#include "be_t.h"
#include "bechordal_t.h"
#include "bearch.h"
#include "besched.h"
#include "belive.h"
#include "benode.h"
#include "beutil.h"
#include "beinsn_t.h"
#include "bessaconstr.h"
#include "beirg.h"
#include "beirgmod.h"
#include "bemodule.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
static int cmp_node_nr(const void *a, const void *b)
{
ir_node **p1 = (ir_node**)a;
ir_node **p2 = (ir_node**)b;
long n1 = get_irn_node_nr(*p1);
long n2 = get_irn_node_nr(*p2);
return (n1>n2) - (n1<n2);
}
ir_node *insert_Perm_before(ir_graph *irg, const arch_register_class_t *cls,
ir_node *const pos)
{
DBG((dbg, LEVEL_1, "Insert Perm before: %+F\n", pos));
ir_nodeset_t live;
ir_nodeset_init(&live);
be_lv_t *lv = be_get_irg_liveness(irg);
be_liveness_nodes_live_before(lv, cls, pos, &live);
size_t n = ir_nodeset_size(&live);
if (n == 0) {
ir_nodeset_destroy(&live);
return NULL;
}
DBG((dbg, LEVEL_1, "live:\n"));
ir_node **nodes = XMALLOCN(ir_node*, n);
size_t p = 0;
foreach_ir_nodeset(&live, irn, iter) {
DBG((dbg, LEVEL_1, "\t%+F\n", irn));
nodes[p++] = irn;
}
ir_nodeset_destroy(&live);
/* make the input order deterministic */
QSORT(nodes, n, cmp_node_nr);
ir_node *const block = get_nodes_block(pos);
ir_node *const perm = be_new_Perm(cls, block, n, nodes);
sched_add_before(pos, perm);
free(nodes);
for (size_t i = 0; i < n; ++i) {
ir_node *perm_op = get_irn_n(perm, i);
ir_mode *mode = get_irn_mode(perm_op);
ir_node *proj = new_r_Proj(perm, mode, i);
be_ssa_construction_env_t senv;
be_ssa_construction_init(&senv, irg);
be_ssa_construction_add_copy(&senv, perm_op);
be_ssa_construction_add_copy(&senv, proj);
be_ssa_construction_fix_users(&senv, perm_op);
be_ssa_construction_update_liveness_phis(&senv, lv);
be_liveness_update(lv, perm_op);
be_liveness_update(lv, proj);
be_ssa_construction_destroy(&senv);
}
return perm;
}
//---------------------------------------------------------------------------
typedef struct remove_dead_nodes_env_t_ {
bitset_t *reachable;
be_lv_t *lv;
} remove_dead_nodes_env_t;
/**
* Post-walker: remember all visited nodes in a bitset.
*/
static void mark_dead_nodes_walker(ir_node *node, void *data)
{
remove_dead_nodes_env_t *env = (remove_dead_nodes_env_t*) data;
bitset_set(env->reachable, get_irn_idx(node));
}
/**
* Post-block-walker:
* Walk through the schedule of every block and remove all dead nodes from it.
*/
static void remove_dead_nodes_walker(ir_node *block, void *data)
{
remove_dead_nodes_env_t *env = (remove_dead_nodes_env_t*) data;
sched_foreach_safe(block, node) {
if (bitset_is_set(env->reachable, get_irn_idx(node)))
continue;
if (env->lv != NULL)
be_liveness_remove(env->lv, node);
sched_remove(node);
/* kill projs */
if (get_irn_mode(node) == mode_T) {
foreach_out_edge_safe(node, edge) {
ir_node *proj = get_edge_src_irn(edge);
if (!is_Proj(proj))
continue;
if (env->lv != NULL)
be_liveness_remove(env->lv, proj);
kill_node(proj);
}
}
kill_node(node);
}
}
void be_remove_dead_nodes_from_schedule(ir_graph *irg)
{
remove_dead_nodes_env_t env;
env.reachable = bitset_alloca(get_irg_last_idx(irg));
env.lv = be_get_irg_liveness(irg);
/* mark all reachable nodes */
irg_walk_graph(irg, mark_dead_nodes_walker, NULL, &env);
/* walk schedule and remove non-marked nodes */
irg_block_walk_graph(irg, remove_dead_nodes_walker, NULL, &env);
}
BE_REGISTER_MODULE_CONSTRUCTOR(be_init_irgmod)
void be_init_irgmod(void)
{
FIRM_DBG_REGISTER(dbg, "firm.be.irgmod");
}
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Backend IRG modification routines.
* @author Sebastian Hack, Daniel Grund, Matthias Braun, Christian Wuerdig
* @date 04.05.2005
*
* This file contains the following IRG modifications for be routines:
* - insertion of Perm nodes
* - empty block elimination
* - a simple dead node elimination (set inputs of unreachable nodes to BAD)
*/
#ifndef FIRM_BE_BEIRGMOD_H
#define FIRM_BE_BEIRGMOD_H
#include "be_types.h"
#include "firm_types.h"
/**
* Insert a Perm which permutes all (non-ignore) live values of a given register class
* before a certain instruction.
* @param lv Liveness Information.
* @param irn The node to insert the Perm before.
* @return The Perm or NULL if nothing was live before @p irn.
*/
ir_node *insert_Perm_before(ir_graph *irg, const arch_register_class_t *cls,
ir_node *irn);
/**
* Removes dead nodes from schedule
* @param irg the graph
*/
void be_remove_dead_nodes_from_schedule(ir_graph *irg);
#endif
......@@ -38,7 +38,6 @@
#include "bemodule.h"
#include "beutil.h"
#include "benode.h"
#include "beirgmod.h"
#include "besched.h"
#include "belistsched.h"
#include "belive.h"
......
......@@ -50,7 +50,6 @@ void be_init_ra(void);
void be_init_spillbelady(void);
void be_init_ssaconstr(void);
void be_init_pref_alloc(void);
void be_init_irgmod(void);
void be_init_loopana(void);
void be_init_spillslots(void);
void be_init_live(void);
......@@ -73,7 +72,6 @@ void be_init_modules(void)
run_once = true;
be_init_abi();
be_init_irgmod();
be_init_loopana();
be_init_live();
be_init_spillslots();
......
......@@ -43,8 +43,6 @@
#include "benode.h"
#include "bearch.h"
#include "beirgmod.h"
typedef struct be_node_attr_t {
except_attr exc;
} be_node_attr_t;
......
......@@ -26,7 +26,6 @@
#include "bearch.h"
#include "beuses.h"
#include "besched.h"
#include "beirgmod.h"
#include "belive.h"
#include "benode.h"
#include "bechordal_t.h"
......
......@@ -35,7 +35,7 @@
#include "statev_t.h"
#include "bessaconstr.h"
#include "beirg.h"
#include "beirgmod.h"
#include "beutil.h"
#include "bemodule.h"
#include "be_t.h"
......
......@@ -30,9 +30,9 @@
#include "belive.h"
#include "bemodule.h"
#include "benode.h"
#include "beirgmod.h"
#include "bespillutil.h"
#include "bessaconstr.h"
#include "beutil.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
......
......@@ -29,7 +29,6 @@
#include "belive.h"
#include "benode.h"
#include "besched.h"
#include "beirgmod.h"
#include "bearch.h"
#include "beuses.h"
......
......@@ -10,17 +10,23 @@
*/
#include <stdio.h>
#include "irgwalk.h"
#include "irdom_t.h"
#include "bearch.h"
#include "beirg.h"
#include "belive.h"
#include "benode.h"
#include "besched.h"
#include "bessaconstr.h"
#include "beutil.h"
#include "ircons.h"
#include "iropt.h"
#include "irdom_t.h"
#include "iredges_t.h"
#include "irgmod.h"
#include "irgopt.h"
#include "irgwalk.h"
#include "irnodeset.h"
#include "iropt.h"
#include "irtools.h"
#include "iredges_t.h"
#include "beutil.h"
#include "besched.h"
#include "bearch.h"
#include "util.h"
/**
* Gets the Proj with number pn from irn.
......@@ -62,3 +68,118 @@ ir_node **be_get_cfgpostorder(ir_graph *irg)
return list;
}
static int cmp_node_nr(const void *a, const void *b)
{
ir_node **p1 = (ir_node**)a;
ir_node **p2 = (ir_node**)b;
long n1 = get_irn_node_nr(*p1);
long n2 = get_irn_node_nr(*p2);
return (n1>n2) - (n1<n2);
}
ir_node *insert_Perm_before(ir_graph *irg, const arch_register_class_t *cls,
ir_node *const pos)
{
ir_nodeset_t live;
ir_nodeset_init(&live);
be_lv_t *lv = be_get_irg_liveness(irg);
be_liveness_nodes_live_before(lv, cls, pos, &live);
size_t n = ir_nodeset_size(&live);
if (n == 0) {
ir_nodeset_destroy(&live);
return NULL;
}
ir_node **nodes = XMALLOCN(ir_node*, n);
size_t p = 0;
foreach_ir_nodeset(&live, irn, iter) {
nodes[p++] = irn;
}
ir_nodeset_destroy(&live);
/* make the input order deterministic */
QSORT(nodes, n, cmp_node_nr);
ir_node *const block = get_nodes_block(pos);
ir_node *const perm = be_new_Perm(cls, block, n, nodes);
sched_add_before(pos, perm);
free(nodes);
for (size_t i = 0; i < n; ++i) {
ir_node *perm_op = get_irn_n(perm, i);
ir_mode *mode = get_irn_mode(perm_op);
ir_node *proj = new_r_Proj(perm, mode, i);
be_ssa_construction_env_t senv;
be_ssa_construction_init(&senv, irg);
be_ssa_construction_add_copy(&senv, perm_op);
be_ssa_construction_add_copy(&senv, proj);
be_ssa_construction_fix_users(&senv, perm_op);
be_ssa_construction_update_liveness_phis(&senv, lv);
be_liveness_update(lv, perm_op);
be_liveness_update(lv, proj);
be_ssa_construction_destroy(&senv);
}
return perm;
}
//---------------------------------------------------------------------------
typedef struct remove_dead_nodes_env_t_ {
bitset_t *reachable;
be_lv_t *lv;
} remove_dead_nodes_env_t;
/**
* Post-walker: remember all visited nodes in a bitset.
*/
static void mark_dead_nodes_walker(ir_node *node, void *data)
{
remove_dead_nodes_env_t *env = (remove_dead_nodes_env_t*) data;
bitset_set(env->reachable, get_irn_idx(node));
}
/**
* Post-block-walker:
* Walk through the schedule of every block and remove all dead nodes from it.
*/
static void remove_dead_nodes_walker(ir_node *block, void *data)
{
remove_dead_nodes_env_t *env = (remove_dead_nodes_env_t*) data;
sched_foreach_safe(block, node) {
if (bitset_is_set(env->reachable, get_irn_idx(node)))
continue;
if (env->lv != NULL)
be_liveness_remove(env->lv, node);
sched_remove(node);
/* kill projs */
if (get_irn_mode(node) == mode_T) {
foreach_out_edge_safe(node, edge) {
ir_node *proj = get_edge_src_irn(edge);
if (!is_Proj(proj))
continue;
if (env->lv != NULL)
be_liveness_remove(env->lv, proj);
kill_node(proj);
}
}
kill_node(node);
}
}
void be_remove_dead_nodes_from_schedule(ir_graph *irg)
{
remove_dead_nodes_env_t env;
env.reachable = bitset_alloca(get_irg_last_idx(irg));
env.lv = be_get_irg_liveness(irg);
/* mark all reachable nodes */
irg_walk_graph(irg, mark_dead_nodes_walker, NULL, &env);
/* walk schedule and remove non-marked nodes */
irg_block_walk_graph(irg, remove_dead_nodes_walker, NULL, &env);
}
......@@ -15,6 +15,8 @@
#include "firm_types.h"
#include "irprog_t.h"
#include "be_types.h"
/**
* Convenient block getter.
* Works also, if the given node is a block.
......@@ -49,4 +51,20 @@ static inline bool is_tls_entity(ir_entity *const ent)
return get_entity_owner(ent) == get_tls_type();
}
/**
* Insert a Perm which permutes all (non-ignore) live values of a given register class
* before a certain instruction.
* @param lv Liveness Information.
* @param irn The node to insert the Perm before.
* @return The Perm or NULL if nothing was live before @p irn.
*/
ir_node *insert_Perm_before(ir_graph *irg, const arch_register_class_t *cls,
ir_node *irn);
/**
* Removes dead nodes from schedule
* @param irg the graph
*/
void be_remove_dead_nodes_from_schedule(ir_graph *irg);
#endif
......@@ -40,7 +40,6 @@
#include "besched.h"
#include "be.h"
#include "be_t.h"
#include "beirgmod.h"
#include "belive.h"
#include "beblocksched.h"
#include "bespillutil.h"
......
......@@ -24,7 +24,6 @@
#include "tv.h"
#include "array.h"
#include "beirgmod.h"
#include "bearch.h"
#include "besched.h"
#include "beabi.h"
......
......@@ -37,7 +37,7 @@
#include "besched.h"
#include "bespillslots.h"
#include "bestack.h"
#include "beirgmod.h"
#include "beutil.h"
#include "panic.h"
static int get_first_same(const arch_register_req_t *req)
......
Markdown is supported
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