Commit 8cb87306 authored by Matthias Braun's avatar Matthias Braun
Browse files

differentiate between Bad and Deleted (because of exchange) nodes, this avoid...

differentiate between Bad and Deleted (because of exchange) nodes, this avoid some invalid memory accesses when trying to get irg from a Bad node

[r28019]
parent 50b4ecce
......@@ -29,8 +29,12 @@
#include "firm_types.h"
#include "begin.h"
/** Exchanges two nodes by conserving edges leaving old (i.e.,
pointers pointing to old). Turns the old node into an Id. */
/**
* Exchanges two nodes by conserving edges leaving old (i.e.,
* pointers pointing to old).
* The nodes op will be changed to op_Deleted and you must not do anything with
* the node anymore except testing its op.
*/
FIRM_API void exchange(ir_node *old, ir_node *nw);
/** Turns a node into a "useless" Tuple.
......
......@@ -234,6 +234,8 @@ FIRM_API int is_Const(const ir_node *node);
FIRM_API int is_Conv(const ir_node *node);
/** Return true of the node is a CopyB node. */
FIRM_API int is_CopyB(const ir_node *node);
/** Return true of the node is a Deleted node. */
FIRM_API int is_Deleted(const ir_node *node);
/** Return true of the node is a Div node. */
FIRM_API int is_Div(const ir_node *node);
/** Return true of the node is a DivMod node. */
......@@ -417,6 +419,7 @@ void set_CopyB_src(ir_node *node, ir_node *src);
FIRM_API ir_type* get_CopyB_type(const ir_node *node);
FIRM_API void set_CopyB_type(ir_node *node, ir_type* type);
FIRM_API ir_node *get_Div_mem(const ir_node *node);
void set_Div_mem(ir_node *node, ir_node *mem);
FIRM_API ir_node *get_Div_left(const ir_node *node);
......
......@@ -24,6 +24,7 @@ typedef enum ir_opcode {
iro_Const,
iro_Conv,
iro_CopyB,
iro_Deleted,
iro_Div,
iro_DivMod,
iro_Dummy,
......@@ -106,6 +107,7 @@ FIRM_API ir_op *op_Confirm;
FIRM_API ir_op *op_Const;
FIRM_API ir_op *op_Conv;
FIRM_API ir_op *op_CopyB;
FIRM_API ir_op *op_Deleted;
FIRM_API ir_op *op_Div;
FIRM_API ir_op *op_DivMod;
FIRM_API ir_op *op_Dummy;
......@@ -164,6 +166,7 @@ FIRM_API ir_op *get_op_Confirm(void);
FIRM_API ir_op *get_op_Const(void);
FIRM_API ir_op *get_op_Conv(void);
FIRM_API ir_op *get_op_CopyB(void);
FIRM_API ir_op *get_op_Deleted(void);
FIRM_API ir_op *get_op_Div(void);
FIRM_API ir_op *get_op_DivMod(void);
FIRM_API ir_op *get_op_Dummy(void);
......
......@@ -161,9 +161,9 @@ static void my_irg_walk_2_both(ir_node *node, irg_walk_func *pre, irg_walk_func
pre(node, env);
if (node->op != op_Block) {
if (!is_Block(node)) {
ir_node *pred;
if (node->op == op_Proj)
if (is_Proj(node))
pred = get_irn_n(node, 0);
else
pred = get_irn_n(node, -1);
......@@ -179,7 +179,7 @@ static void my_irg_walk_2_both(ir_node *node, irg_walk_func *pre, irg_walk_func
}
}
if (node->op == op_End) {
if (is_End(node)) {
for (i = get_irn_arity(node) - 1; i >= 0; --i) {
ir_node *pred = get_irn_n(node, i);
if ((pred->op == op_Block) && (pred->visited < current_ir_graph->visited))
......
......@@ -941,11 +941,7 @@ found_front:
arch_set_irn_register(node, arch_get_irn_register(proj));
/* reroute all users of the proj to the moved node. */
edges_reroute(proj, node, irg);
/* and kill it */
set_Proj_pred(proj, new_Bad());
kill_node(proj);
exchange(proj, node);
bitset_set(moved, input);
n_moved++;
......
......@@ -149,7 +149,7 @@ static ir_node *new_bd_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
{
ir_node *res;
assert(arg->op == op_Cond);
assert(is_Cond(arg));
arg->attr.cond.default_proj = max_proj;
res = new_rd_Proj(db, arg, mode_X, max_proj);
return res;
......@@ -880,7 +880,7 @@ ir_node *new_d_Const_type(dbg_info *db, tarval *con, ir_type *tp)
ir_node *new_d_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
{
ir_node *res;
assert(arg->op == op_Cond);
assert(is_Cond(arg));
arg->attr.cond.default_proj = max_proj;
res = new_d_Proj(db, arg, mode_X, max_proj);
return res;
......
......@@ -622,6 +622,9 @@ static void visitor(ir_node *irn, void *data)
{
visitor_info_t *info = data;
if (is_Deleted(irn))
return;
if (!irn_visited_else_mark(irn)) {
info->visit(irn, info->data);
}
......
......@@ -85,7 +85,8 @@ void exchange(ir_node *old, ir_node *nw)
edges_reroute(old, nw, irg);
edges_reroute_kind(old, nw, EDGE_KIND_DEP, irg);
edges_node_deleted(old, irg);
old->op = op_Bad;
/* noone is allowed to reference this node anymore */
set_irn_op(old, op_Deleted);
} else {
/* Else, do it the old-fashioned way. */
ir_node *block;
......
......@@ -285,7 +285,7 @@ static void collect_walk(ir_node *node, blk_collect_data_t *env)
mark_irn_visited(node);
if (node->op == op_Block) {
if (is_Block(node)) {
/* predecessors of a block are control flow nodes */
for (i = _get_walk_arity(env, node) - 1; i >= 0; --i) {
ir_node *pred = _get_walk_irn_n(env, node, i);
......
......@@ -508,11 +508,9 @@ int get_irn_pred_pos(ir_node *node, ir_node *arg)
/** manipulate fields of individual nodes **/
/* this works for all except Block */
ir_node *get_nodes_block(const ir_node *node)
ir_node *(get_nodes_block)(const ir_node *node)
{
assert(node->op != op_Block);
return get_irn_n(node, -1);
return _get_nodes_block(node);
}
void set_nodes_block(ir_node *node, ir_node *block)
......@@ -1302,7 +1300,7 @@ int is_Phi0(const ir_node *n)
ir_node **get_Phi_preds_arr(ir_node *node)
{
assert(node->op == op_Phi);
assert(is_Phi(node));
return (ir_node **)&(get_irn_in(node)[1]);
}
......@@ -1312,13 +1310,6 @@ int get_Phi_n_preds(const ir_node *node)
return (get_irn_arity(node));
}
/*
void set_Phi_n_preds(ir_node *node, int n_preds)
{
assert(node->op == op_Phi);
}
*/
ir_node *get_Phi_pred(const ir_node *node, int pos)
{
assert(is_Phi(node) || is_Phi0(node));
......@@ -1591,25 +1582,19 @@ skip_Proj_const(const ir_node *node)
ir_node *skip_Tuple(ir_node *node)
{
ir_node *pred;
ir_op *op;
restart:
if (is_Proj(node)) {
pred = get_Proj_pred(node);
op = get_irn_op(pred);
/*
* Looks strange but calls get_irn_op() only once
* in most often cases.
*/
if (op == op_Proj) { /* nested Tuple ? */
if (is_Proj(pred)) { /* nested Tuple ? */
pred = skip_Tuple(pred);
if (is_Tuple(pred)) {
node = get_Tuple_pred(pred, get_Proj_proj(node));
goto restart;
}
} else if (op == op_Tuple) {
} else if (is_Tuple(pred)) {
node = get_Tuple_pred(pred, get_Proj_proj(node));
goto restart;
}
......@@ -1691,7 +1676,7 @@ ir_node *skip_Id(ir_node *node)
node->in[0+1] = node; /* turn us into a self referencing Id: shorten Id cycles. */
res = skip_Id(rem_pred);
if (res->op == op_Id) /* self-loop */ return node;
if (is_Id(res)) /* self-loop */ return node;
node->in[0+1] = res; /* Turn Id chain into Ids all referencing the chain end. */
return res;
......
......@@ -161,7 +161,7 @@ static inline ir_node *_get_irn_n(const ir_node *node, int n)
nn = node->in[n + 1];
if (nn == NULL) {
/* only block and Anchor inputs are allowed to be NULL */
assert((node->op == op_Anchor || n == -1) && "NULL input of a node");
assert((is_Anchor(node) || n == -1) && "NULL input of a node");
return NULL;
}
if (nn->op != op_Id) return nn;
......@@ -233,18 +233,28 @@ static inline void _set_irn_mode(ir_node *node, ir_mode *mode)
node->mode = mode;
}
static inline int ir_has_irg_ref(const ir_node *node)
{
return is_Block(node) || is_Bad(node) || is_Anchor(node);
}
static inline ir_graph *_get_irn_irg(const ir_node *node)
{
/*
* Do not use get_nodes_Block() here, because this
* Do not use get_nodes_block() here, because this
* will check the pinned state.
* However even a 'wrong' block is always in the proper
* irg.
* However even a 'wrong' block is always in the proper irg.
*/
if (! is_Block(node))
node = get_irn_n(node, -1);
/* note that get_Block_irg() can handle Bad nodes */
return get_Block_irg(node);
assert(ir_has_irg_ref(node));
return node->attr.irg.irg;
}
static inline ir_node *_get_nodes_block(const ir_node *node)
{
assert(!is_Block(node));
return get_irn_n(node, -1);
}
/**
......@@ -399,13 +409,13 @@ static inline ir_node *_get_Block_cfgpred_block(const ir_node *node, int pos)
static inline ir_visited_t _get_Block_block_visited(const ir_node *node)
{
assert(node->op == op_Block);
assert(is_Block(node));
return node->attr.block.block_visited;
}
static inline void _set_Block_block_visited(ir_node *node, ir_visited_t visit)
{
assert(node->op == op_Block);
assert(is_Block(node));
node->attr.block.block_visited = visit;
}
......@@ -443,7 +453,7 @@ static inline int _is_Block_dead(const ir_node *block)
static inline ir_graph *_get_Block_irg(const ir_node *block)
{
assert(is_Block(block) || is_Bad(block) || is_Anchor(block));
assert(is_Block(block));
return block->attr.irg.irg;
}
......@@ -616,6 +626,7 @@ void init_irnode(void);
#define get_irn_mode(node) _get_irn_mode(node)
#define set_irn_mode(node, mode) _set_irn_mode(node, mode)
#define get_irn_irg(node) _get_irn_irg(node)
#define get_nodes_block(node) _get_nodes_block(node)
#define get_irn_op(node) _get_irn_op(node)
#define set_irn_op(node, op) _set_irn_op(node, op)
#define get_irn_opcode(node) _get_irn_opcode(node)
......
......@@ -6849,6 +6849,9 @@ ir_node *optimize_in_place_2(ir_node *n)
if (!get_opt_optimize() && !is_Phi(n)) return n;
if (iro == iro_Deleted)
return n;
/* constant expression evaluation / constant folding */
if (get_opt_constant_folding()) {
/* neither constants nor Tuple values can be evaluated */
......
......@@ -130,6 +130,10 @@ typedef struct {
ir_graph *irg; /**< The graph this block like node belongs to. */
} irg_attr;
typedef struct {
irg_attr irg;
} bad_attr;
/** Block attributes */
typedef struct {
/* General attributes */
......@@ -303,6 +307,7 @@ typedef struct {
some have more. Their name is 'irnodename_attr' */
typedef union {
irg_attr irg; /**< For Blocks and Bad: its belonging irg */
bad_attr bad; /**< for Bads: irg reference */
block_attr block; /**< For Block: Fields needed to construct it */
cond_attr cond; /**< For Cond. */
const_attr con; /**< For Const: contains the value of the constant and a type */
......
......@@ -231,7 +231,7 @@ def main(argv):
# these nodes don't work correctly yet for some reasons...
niynodes = [ "ASM" ]
# these have custom im-/export code
customcode = [ "Start", "End", "Anchor", "SymConst", "Block" ]
customcode = [ "Start", "End", "Anchor", "SymConst", "Block", "Deleted" ]
real_nodes = []
for node in ir_spec.nodes:
......
......@@ -101,11 +101,18 @@ class Bad(Op):
pinned = "yes"
knownBlock = True
singleton = True
attr_struct = "irg_attr"
attr_struct = "bad_attr"
init = '''
res->attr.irg.irg = irg;
'''
class Deleted(Op):
mode = "mode_Bad"
flags = [ ]
pinned = "yes"
knownBlock = True
singleton = True
class Block(Op):
mode = "mode_BB"
knownBlock = True
......
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