#include "irgwalk.h"
#include "irprintf_t.h"
#include "irbitset.h"
+#include "irdump_t.h"
#include "beutil.h"
#include "belive_t.h"
#define LV_USE_BINARY_SEARCH
#undef LV_INTESIVE_CHECKS
+static INLINE int is_liveness_node(const ir_node *irn)
+{
+ switch(get_irn_opcode(irn)) {
+ case iro_Block:
+ case iro_Bad:
+ case iro_End:
+ return 0;
+ default:;
+ }
+
+ return 1;
+}
+
int (be_lv_next_irn)(const struct _be_lv_t *lv, const ir_node *bl, unsigned flags, int i)
{
return _be_lv_next_irn(lv, bl, flags, i);
ir_node *def_block;
/* Don't compute liveness information for non-data nodes. */
- if(!is_data_node(irn))
+ if(!is_liveness_node(irn))
return;
bitset_clear_all(visited);
ir_node *use_block;
/*
- * If the usage is no data node, skip this use, since it does not
- * affect the liveness of the node.
- */
- if(!is_data_node(use))
+ * If the usage is no data node, skip this use, since it does not
+ * affect the liveness of the node.
+ */
+ if(!is_liveness_node(use))
continue;
/* Get the block where the usage is in. */
use_block = get_nodes_block(use);
/*
- * If the use is a phi function, determine the corresponding block
- * through which the value reaches the phi function and mark the
- * value as live out of that block.
- */
+ * If the use is a phi function, determine the corresponding block
+ * through which the value reaches the phi function and mark the
+ * value as live out of that block.
+ */
if(is_Phi(use)) {
ir_node *pred_block = get_Block_cfgpred_block(use_block, edge->pos);
live_end_at_block(lv, irn, pred_block, visited, 0);
}
/*
- * Else, the value is live in at this block. Mark it and call live
- * out on the predecessors.
- */
+ * Else, the value is live in at this block. Mark it and call live
+ * out on the predecessors.
+ */
else if(def_block != use_block) {
int i, n;
else if(curr) {
unsigned n_curr = curr[0].u.head.n_members;
unsigned n_fresh = fr[0].u.head.n_members;
- unsigned n = MIN(n_curr, n_fresh);
unsigned i;
*/
static void dom_check(ir_node *irn, void *data)
{
+ int *problem_found = data;
+
if(!is_Block(irn) && irn != get_irg_end(get_irn_irg(irn))) {
int i, n;
ir_node *bl = get_nodes_block(irn);
if(is_Phi(irn))
use_bl = get_Block_cfgpred_block(bl, i);
- if(!block_dominates(def_bl, use_bl)) {
- ir_fprintf(stderr, "%+F in %+F must dominate %+F for user %+F\n", op, def_bl, use_bl, irn);
- assert(0);
+ if(get_irn_opcode(use_bl) != iro_Bad
+ && get_irn_opcode(def_bl) != iro_Bad
+ && !block_dominates(def_bl, use_bl)) {
+ ir_fprintf(stderr, "Verify warning: %+F in %+F must dominate %+F for user %+F (%s)\n", op, def_bl, use_bl, irn, get_irg_dump_name(get_irn_irg(op)));
+ *problem_found = 1;
}
}
}
}
/* Check, if the SSA dominance property is fulfilled. */
-void be_check_dominance(ir_graph *irg)
+int be_check_dominance(ir_graph *irg)
{
- irg_walk_graph(irg, dom_check, NULL, NULL);
+ int problem_found = 0;
+
+ assure_doms(irg);
+ irg_walk_graph(irg, dom_check, NULL, &problem_found);
+
+ return !problem_found;
}
pset *be_liveness_transfer(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *irn, pset *live)
{
int i, n;
- ir_node *x;
FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
DEBUG_ONLY(
+ const ir_node *x;
DBG((dbg, LEVEL_1, "%+F\n", irn));
for(x = pset_first(live); x; x = pset_next(live))
DBG((dbg, LEVEL_1, "\tlive: %+F\n", x));