Commit 7c63b4d0 authored by Jonas Fietz's avatar Jonas Fietz
Browse files

rewrite vrp scanning to use a phase instead of attrs in ir_node

[r27239]
parent a8265566
......@@ -43,6 +43,22 @@ enum range_ops {
VRP_SUB /* range - range_node are the possible values */
};
/** VRP information */
typedef struct {
int valid; /**< This node has valid vrp information */
tarval *bits_set; /**< The bits which, by analysis, are definitely set.
0: may be not set, 1: definitely set*/
tarval *bits_not_set; /**< The bits which by analysis are definitely
not set, 1 for may be set, 0: definitely not set */
ir_node *bits_node; /**< The node, from which the rest of the bits
are set */
enum range_types range_type;/**< The range represented by range_top, range_bottom */
tarval *range_bottom, *range_top;
ir_node *range_node; /**< The node to which the range is relative */
enum range_ops range_op; /**< The op which describes the relation
between range_node and range */
} vrp_attr;
/**
* Set vrp data on the graph irg
* @param irg graph on which to set vrp data
......@@ -64,6 +80,15 @@ ir_graph_pass_t *set_vrp_pass(const char *name);
*
* @return the pn_Cmp, if one can be derived
*/
pn_Cmp vrp_cmp(ir_node *left, ir_node *right);
pn_Cmp vrp_cmp(const ir_node *left, const ir_node *right);
/*
* Return the vrp data for this node
*
* @param n: the node for which to return the vrp information
*
* @return a pointer to the vrp data or NULL if there is none
*/
vrp_attr *vrp_get_info(const ir_node *n);
#endif
This diff is collapsed.
......@@ -1247,22 +1247,23 @@ int dump_node_label(FILE *F, ir_node *n)
/* Dumps the vrp information of a node to a file */
int dump_vrp_info(FILE *F, ir_node *n)
{
if (!n->vrp.valid) {
vrp_attr *vrp = vrp_get_info(n);
if (!n) {
return 1;
}
fprintf(F, "range_type: %d\n", n->vrp.range_type);
if (n->vrp.range_type == VRP_RANGE || n->vrp.range_type ==
fprintf(F, "range_type: %d\n", vrp->range_type);
if (vrp->range_type == VRP_RANGE || vrp->range_type ==
VRP_ANTIRANGE) {
ir_fprintf(F, "range_bottom: %F\n",n->vrp.range_bottom);
ir_fprintf(F, "range_top: %F\n", n->vrp.range_top);
ir_fprintf(F, "range_bottom: %F\n",vrp->range_bottom);
ir_fprintf(F, "range_top: %F\n", vrp->range_top);
}
ir_fprintf(F, "bits_set: %T\n", n->vrp.bits_set);
ir_fprintf(F, "bits_not_set: %T\n", n->vrp.bits_not_set);
if (n->vrp.bits_node == NULL) {
ir_fprintf(F, "bits_set: %T\n", vrp->bits_set);
ir_fprintf(F, "bits_not_set: %T\n", vrp->bits_not_set);
if (vrp->bits_node == NULL) {
fprintf(F, "bits_node: None");
} else {
fprintf(F, "bits_node: #%ld\n", get_irn_node_nr(n->vrp.bits_node));
fprintf(F, "bits_node: #%ld\n", get_irn_node_nr(vrp->bits_node));
}
return 0;
......
......@@ -395,7 +395,8 @@ int dump_irnode_to_file(FILE *F, ir_node *n)
default: ;
}
if (n->vrp.valid) {
vrp_attr *vrp_info = vrp_get_info(n);
if (vrp_info) {
dump_vrp_info(F, n);
}
......
......@@ -199,26 +199,6 @@ ir_node *new_ir_node(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op,
if (get_irg_phase_state(irg) == phase_backend) {
be_info_new_node(res);
}
/* Init the VRP structures */
res->vrp.range_type = VRP_UNDEFINED;
res->vrp.valid = 0;
if (mode_is_int(mode)) {
/* We are assuming that 0 is always represented by this modes 0 */
res->vrp.bits_set =
res->vrp.bits_not_set = get_mode_null(mode);
res->vrp.range_bottom =
res->vrp.range_top = get_tarval_top();
} else {
res->vrp.bits_set =
res->vrp.bits_not_set =
res->vrp.range_bottom =
res->vrp.range_top = get_tarval_bad();
}
res->vrp.bits_node = NULL;
res->vrp.range_node = NULL;
res->vrp.range_op = VRP_NONE;
return res;
}
......
......@@ -696,9 +696,10 @@ static tarval *computed_value_Proj(const ir_node *proj)
*/
tarval *computed_value(const ir_node *n)
{
if (mode_is_int(get_irn_mode(n)) && n->vrp.valid && tarval_is_all_one(
tarval_or(n->vrp.bits_set, n->vrp.bits_not_set))) {
return n->vrp.bits_set;
vrp_attr *vrp = vrp_get_info(n);
if (vrp && tarval_is_all_one(
tarval_or(vrp->bits_set, vrp->bits_not_set))) {
return vrp->bits_set;
}
if (n->op->ops.computed_value)
return n->op->ops.computed_value(n);
......@@ -2410,10 +2411,16 @@ static ir_node *transform_node_Add(ir_node *n)
}
}
}
if (mode_is_int(mode) && a->vrp.valid && b->vrp.valid) {
vrp_attr *a_vrp, *b_vrp;
a_vrp = vrp_get_info(a);
b_vrp = vrp_get_info(b);
if (a_vrp && b_vrp) {
tarval *c = tarval_and(
tarval_not(a->vrp.bits_not_set),
tarval_not(b->vrp.bits_not_set)
tarval_not(a_vrp->bits_not_set),
tarval_not(b_vrp->bits_not_set)
);
if (tarval_is_null(c)) {
......@@ -3583,15 +3590,19 @@ static ir_node *transform_node_And(ir_node *n)
return n;
}
if (is_Const(a) && b->vrp.valid && (tarval_is_all_one(tarval_or(get_Const_tarval(a),
b->vrp.bits_not_set)))) {
vrp_attr *a_vrp, *b_vrp;
a_vrp = vrp_get_info(a);
b_vrp = vrp_get_info(b);
if (is_Const(a) && b_vrp && (tarval_is_all_one(tarval_or(get_Const_tarval(a),
b_vrp->bits_not_set)))) {
return new_rd_Id(get_irn_dbg_info(n), get_nodes_block(n),
b, get_irn_mode(n));
}
if (is_Const(b) && a->vrp.valid && (tarval_is_all_one(tarval_or(get_Const_tarval(b),
a->vrp.bits_not_set)))) {
if (is_Const(b) && a_vrp && (tarval_is_all_one(tarval_or(get_Const_tarval(b),
a_vrp->bits_not_set)))) {
return new_rd_Id(get_irn_dbg_info(n), get_nodes_block(n),
a, get_irn_mode(n));
......@@ -4085,21 +4096,22 @@ static ir_node *transform_node_Proj_Cond(ir_node *proj)
}
} else {
long num = get_Proj_proj(proj);
if (num != get_Cond_default_proj(n) && b->vrp.valid) {
vrp_attr *b_vrp = vrp_get_info(b);
if (num != get_Cond_default_proj(n) && b_vrp) {
/* Try handling with vrp data. We only remove dead parts. */
tarval *tp = new_tarval_from_long(num, get_irn_mode(b));
if (b->vrp.range_type == VRP_RANGE) {
pn_Cmp cmp_result = tarval_cmp(b->vrp.range_bottom, tp);
pn_Cmp cmp_result2 = tarval_cmp(b->vrp.range_top, tp);
if (b_vrp->range_type == VRP_RANGE) {
pn_Cmp cmp_result = tarval_cmp(b_vrp->range_bottom, tp);
pn_Cmp cmp_result2 = tarval_cmp(b_vrp->range_top, tp);
if ((cmp_result & pn_Cmp_Lt) == cmp_result && (cmp_result2
& pn_Cmp_Gt) == cmp_result2) {
return get_irg_bad(current_ir_graph);
}
} else if (b->vrp.range_type == VRP_ANTIRANGE) {
pn_Cmp cmp_result = tarval_cmp(b->vrp.range_bottom, tp);
pn_Cmp cmp_result2 = tarval_cmp(b->vrp.range_top, tp);
} else if (b_vrp->range_type == VRP_ANTIRANGE) {
pn_Cmp cmp_result = tarval_cmp(b_vrp->range_bottom, tp);
pn_Cmp cmp_result2 = tarval_cmp(b_vrp->range_top, tp);
if ((cmp_result & pn_Cmp_Ge) == cmp_result && (cmp_result2
& pn_Cmp_Le) == cmp_result2) {
......@@ -4108,8 +4120,8 @@ static ir_node *transform_node_Proj_Cond(ir_node *proj)
}
if (!(tarval_cmp(
tarval_and( b->vrp.bits_set, tp),
b->vrp.bits_set
tarval_and( b_vrp->bits_set, tp),
b_vrp->bits_set
) == pn_Cmp_Eq)) {
return get_irg_bad(current_ir_graph);
......@@ -4118,8 +4130,8 @@ static ir_node *transform_node_Proj_Cond(ir_node *proj)
if (!(tarval_cmp(
tarval_and(
tarval_not(tp),
b->vrp.bits_not_set),
b->vrp.bits_not_set)
b_vrp->bits_not_set),
b_vrp->bits_not_set)
== pn_Cmp_Eq)) {
return get_irg_bad(current_ir_graph);
......
......@@ -7,6 +7,7 @@ PH(NOT_IRG_MANAGED, "A phase not managed by an IRG")
PH(BE_ARCH, "Backend architecture abstraction")
PH(BE_SCHED, "Scheduler")
PH(BE_REG_ALLOC, "Register allocation")
PH(VRP, "Value Range Propagation")
/* END Enter your phases here */
......
......@@ -305,21 +305,6 @@ typedef struct {
ident **clobber; /**< List of clobbered registers. */
} asm_attr;
/** VRP information */
typedef struct {
int valid; /**< 0: VRP info invalid, 1: VRP info valid (not
neccessarily updated) */
tarval *bits_set; /**< The bits which, by analysis, are definitely set */
tarval *bits_not_set; /**< The bits which by analysis are definitely not set */
ir_node *bits_node; /**< The node, from which the rest of the bits
are set */
enum range_types range_type;/**< The range represented by range_top, range_bottom */
tarval *range_bottom, *range_top;
ir_node *range_node; /**< The node to which the range is relative */
enum range_ops range_op; /**< The op which describes the relation
between range_node and range */
} vrp_attr;
/** Some IR-nodes just have one attribute, these are stored here,
some have more. Their name is 'irnodename_attr' */
typedef union {
......@@ -398,7 +383,6 @@ struct ir_node {
struct ir_node **deps; /**< Additional dependencies induced by state. */
void *backend_info;
irn_edges_info_t edge_info; /**< Everlasting out edges. */
vrp_attr vrp; /**< Information supplied by VRP */
/* ------- Opcode depending fields -------- */
attr attr; /**< The set of attributes of this node. Depends on opcode.
......
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