Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
7c63b4d0
Commit
7c63b4d0
authored
Feb 27, 2010
by
Jonas Fietz
Browse files
rewrite vrp scanning to use a phase instead of attrs in ir_node
[r27239]
parent
a8265566
Changes
8
Hide whitespace changes
Inline
Side-by-side
include/libfirm/vrp.h
View file @
7c63b4d0
...
...
@@ -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
ir/ana/vrp.c
View file @
7c63b4d0
...
...
@@ -30,12 +30,14 @@
#include "vrp.h"
#include "irouts.h"
#include "irgraph_t.h"
#include "irgopt.h"
#include "irpass.h"
#include "irgwalk.h"
#include "iredges.h"
#include "tv.h"
#include "irop.h"
#include "pdeq.h"
#include "irphase_t.h"
static
char
v
;
...
...
@@ -45,9 +47,8 @@ struct vrp_env_t {
waitq
*
workqueue
;
};
static
int
update_
vrp_data
(
ir_node
*
node
)
static
int
vrp_
update_
node
(
ir_node
*
node
)
{
tarval
*
new_bits_set
=
get_tarval_bad
();
tarval
*
new_bits_not_set
=
get_tarval_bad
();
tarval
*
new_range_bottom
=
get_tarval_bad
();
...
...
@@ -57,15 +58,21 @@ static int update_vrp_data(ir_node *node)
enum
range_types
new_range_type
=
VRP_UNDEFINED
;
enum
range_ops
new_range_op
=
VRP_NONE
;
int
something_changed
=
0
;
vrp_attr
*
vrp
;
ir_phase
*
phase
;
if
(
!
mode_is_int
(
get_irn_mode
(
node
)))
{
return
0
;
/* we don't optimize for non-int-nodes*/
}
phase
=
get_irg_phase
(
get_irn_irg
(
node
),
PHASE_VRP
);
ir_printf
(
"update_vrp for %d called
\n
"
,
get_irn_node_nr
(
node
));
vrp
=
phase_get_or_set_irn_data
(
phase
,
node
);
node
->
vrp
.
valid
=
1
;
/* TODO: Check if all predecessors have valid VRP information*/
if
(
!
mode_is_int
(
get_irn_mode
(
node
)))
{
return
0
;
/* we don't optimize for non-int-nodes*/
}
switch
(
get_irn_opcode
(
node
))
{
case
iro_Const
:
{
...
...
@@ -79,24 +86,28 @@ static int update_vrp_data(ir_node *node)
}
case
iro_And
:
{
vrp_attr
*
vrp_left
,
*
vrp_right
;
ir_node
*
left
,
*
right
;
tarval
*
tmp_tv
;
left
=
get_And_left
(
node
);
right
=
get_And_right
(
node
);
vrp_left
=
phase_get_or_set_irn_data
(
phase
,
left
);
vrp_right
=
phase_get_or_set_irn_data
(
phase
,
right
);
new_bits_set
=
tarval_and
(
left
->
vrp
.
bits_set
,
right
->
vrp
.
bits_set
);
new_bits_not_set
=
tarval_or
(
left
->
vrp
.
bits_not_set
,
right
->
vrp
.
bits_not_set
);
tmp_tv
=
tarval_not
(
left
->
vrp
.
bits_set
);
tmp_tv
=
tarval_eor
(
left
->
vrp
.
bits_not_set
,
tmp_tv
);
new_bits_set
=
tarval_and
(
vrp_left
->
bits_set
,
vrp_right
->
bits_set
);
new_bits_not_set
=
tarval_or
(
vrp_left
->
bits_not_set
,
vrp_right
->
bits_not_set
);
tmp_tv
=
tarval_not
(
vrp_left
->
bits_set
);
tmp_tv
=
tarval_eor
(
vrp_left
->
bits_not_set
,
tmp_tv
);
/*check if one of the predecessors is completely determined*/
if
(
tarval_is_null
(
tmp_tv
))
{
new_bits_node
=
right
;
}
tmp_tv
=
tarval_not
(
right
->
vrp
.
bits_set
);
tmp_tv
=
tarval_eor
(
right
->
vrp
.
bits_not_set
,
tmp_tv
);
tmp_tv
=
tarval_not
(
vrp_
right
->
bits_set
);
tmp_tv
=
tarval_eor
(
vrp_
right
->
bits_not_set
,
tmp_tv
);
if
(
tarval_is_null
(
tmp_tv
))
{
new_bits_node
=
left
;
}
...
...
@@ -104,25 +115,25 @@ static int update_vrp_data(ir_node *node)
}
case
iro_Add
:
{
ir_node
*
left
,
*
right
;
left
=
get_Add_left
(
node
);
right
=
get_Add_right
(
node
);
vrp_attr
*
vrp_
left
,
*
vrp_
right
;
vrp_
left
=
phase_get_or_set_irn_data
(
phase
,
get_Add_left
(
node
)
)
;
vrp_
right
=
phase_get_or_set_irn_data
(
phase
,
get_Add_right
(
node
)
)
;
int
overflow_top
,
overflow_bottom
;
tarval
*
new_top
,
*
new_bottom
;
if
(
left
->
vrp
.
range_type
==
VRP_UNDEFINED
||
right
->
vrp
.
range_type
==
VRP_UNDEFINED
||
left
->
vrp
.
range_type
==
VRP_VARYING
||
right
->
vrp
.
range_type
==
VRP_VARYING
)
{
if
(
vrp_
left
->
range_type
==
VRP_UNDEFINED
||
vrp_
right
->
range_type
==
VRP_UNDEFINED
||
vrp_
left
->
range_type
==
VRP_VARYING
||
vrp_
right
->
range_type
==
VRP_VARYING
)
{
return
0
;
}
new_top
=
tarval_add
(
left
->
vrp
.
range_top
,
right
->
vrp
.
range_top
);
new_top
=
tarval_add
(
vrp_
left
->
range_top
,
vrp_
right
->
range_top
);
overflow_top
=
tarval_carry
();
new_bottom
=
tarval_add
(
left
->
vrp
.
range_bottom
,
right
->
vrp
.
range_bottom
);
new_bottom
=
tarval_add
(
vrp_
left
->
range_bottom
,
vrp_
right
->
range_bottom
);
overflow_bottom
=
tarval_carry
();
if
(
!
overflow_top
&&
!
overflow_bottom
&&
left
->
vrp
.
range_type
==
VRP_RANGE
&&
right
->
vrp
.
range_type
==
VRP_RANGE
)
{
if
(
!
overflow_top
&&
!
overflow_bottom
&&
vrp_
left
->
range_type
==
VRP_RANGE
&&
vrp_
right
->
range_type
==
VRP_RANGE
)
{
new_range_bottom
=
new_bottom
;
new_range_top
=
new_top
;
new_range_type
=
VRP_RANGE
;
...
...
@@ -136,24 +147,24 @@ static int update_vrp_data(ir_node *node)
}
case
iro_Sub
:
{
ir_node
*
left
,
*
right
;
left
=
get_Sub_left
(
node
);
right
=
get_Sub_right
(
node
);
vrp_attr
*
vrp_
left
,
*
vrp_
right
;
vrp_
left
=
phase_get_or_set_irn_data
(
phase
,
get_Sub_left
(
node
)
)
;
vrp_
right
=
phase_get_or_set_irn_data
(
phase
,
get_Sub_right
(
node
)
)
;
int
overflow_top
,
overflow_bottom
;
tarval
*
new_top
,
*
new_bottom
;
if
(
left
->
vrp
.
range_type
==
VRP_UNDEFINED
||
right
->
vrp
.
range_type
==
if
(
vrp_
left
->
range_type
==
VRP_UNDEFINED
||
vrp_
right
->
range_type
==
VRP_UNDEFINED
)
{
return
0
;
}
new_top
=
tarval_sub
(
left
->
vrp
.
range_top
,
right
->
vrp
.
range_top
,
NULL
);
new_top
=
tarval_sub
(
vrp_
left
->
range_top
,
vrp_
right
->
range_top
,
NULL
);
overflow_top
=
tarval_carry
();
new_bottom
=
tarval_sub
(
left
->
vrp
.
range_bottom
,
right
->
vrp
.
range_bottom
,
NULL
);
new_bottom
=
tarval_sub
(
vrp_
left
->
range_bottom
,
vrp_
right
->
range_bottom
,
NULL
);
overflow_bottom
=
tarval_carry
();
if
(
!
overflow_top
&&
!
overflow_bottom
&&
left
->
vrp
.
range_type
==
VRP_RANGE
&&
right
->
vrp
.
range_type
==
VRP_RANGE
)
{
if
(
!
overflow_top
&&
!
overflow_bottom
&&
vrp_
left
->
range_type
==
VRP_RANGE
&&
vrp_
right
->
range_type
==
VRP_RANGE
)
{
new_range_bottom
=
new_bottom
;
new_range_top
=
new_top
;
new_range_type
=
VRP_RANGE
;
...
...
@@ -166,24 +177,28 @@ static int update_vrp_data(ir_node *node)
}
case
iro_Or
:
{
vrp_attr
*
vrp_left
,
*
vrp_right
;
ir_node
*
left
,
*
right
;
tarval
*
tmp_tv
;
left
=
get_Or_left
(
node
);
right
=
get_Or_right
(
node
);
new_bits_set
=
tarval_or
(
left
->
vrp
.
bits_
se
t
,
right
->
vrp
.
bits_set
);
new_bits_not_set
=
tarval_and
(
left
->
vrp
.
bits_not_
se
t
,
right
->
vrp
.
bits_not_set
);
vrp_left
=
phase_get_or_set_irn_data
(
pha
se
,
get_Or_left
(
node
)
);
vrp_right
=
phase_get_or_set_irn_data
(
pha
se
,
get_Or_right
(
node
)
);
tmp_tv
=
tarval_not
(
left
->
vrp
.
bits_set
);
tmp_tv
=
tarval_eor
(
left
->
vrp
.
bits_not_set
,
tmp_tv
);
new_bits_set
=
tarval_or
(
vrp_left
->
bits_set
,
vrp_right
->
bits_set
);
new_bits_not_set
=
tarval_and
(
vrp_left
->
bits_not_set
,
vrp_right
->
bits_not_set
);
tmp_tv
=
tarval_not
(
vrp_left
->
bits_set
);
tmp_tv
=
tarval_eor
(
vrp_left
->
bits_not_set
,
tmp_tv
);
/*check if one of the predecessors is completely determined*/
if
(
tarval_is_null
(
tmp_tv
))
{
new_bits_node
=
right
;
}
tmp_tv
=
tarval_not
(
right
->
vrp
.
bits_set
);
tmp_tv
=
tarval_eor
(
right
->
vrp
.
bits_not_set
,
tmp_tv
);
tmp_tv
=
tarval_not
(
vrp_
right
->
bits_set
);
tmp_tv
=
tarval_eor
(
vrp_
right
->
bits_not_set
,
tmp_tv
);
if
(
tarval_is_null
(
tmp_tv
))
{
new_bits_node
=
left
;
}
...
...
@@ -191,37 +206,39 @@ static int update_vrp_data(ir_node *node)
}
case
iro_Rotl
:
{
ir_node
*
left
,
*
right
;
vrp_attr
*
vrp_left
,
*
vrp_right
;
ir_node
*
right
=
get_Rotl_right
(
node
);
left
=
get_Rotl_left
(
node
);
right
=
get_Rotl_right
(
node
);
vrp_
left
=
phase_get_or_set_irn_data
(
phase
,
get_Rotl_left
(
node
)
)
;
vrp_
right
=
phase_get_or_set_irn_data
(
phase
,
get_Rotl_right
(
node
)
)
;
/* We can only compute this if the right value is a constant*/
if
(
is_Const
(
right
))
{
tarval
*
bits_set
,
*
bits_not_set
;
bits_set
=
tarval_rotl
(
left
->
vrp
.
bits_set
,
get_Const_tarval
(
right
));
bits_not_set
=
tarval_rotl
(
left
->
vrp
.
bits_not_set
,
get_Const_tarval
(
right
));
bits_set
=
tarval_rotl
(
vrp_
left
->
bits_set
,
get_Const_tarval
(
right
));
bits_not_set
=
tarval_rotl
(
vrp_
left
->
bits_not_set
,
get_Const_tarval
(
right
));
new_bits_set
=
tarval_or
(
bits_set
,
node
->
vrp
.
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
node
->
vrp
.
bits_not_set
);
new_bits_set
=
tarval_or
(
bits_set
,
vrp
->
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
vrp
->
bits_not_set
);
}
break
;
}
case
iro_Shl
:
{
ir_node
*
left
,
*
right
;
left
=
get_Shl_left
(
node
);
right
=
get_Shl_right
(
node
);
vrp_attr
*
vrp_left
,
*
vrp_right
;
ir_node
*
right
=
get_Shl_right
(
node
);
vrp_left
=
phase_get_or_set_irn_data
(
phase
,
get_Shl_left
(
node
));
vrp_right
=
phase_get_or_set_irn_data
(
phase
,
get_Shl_right
(
node
));
/* We can only compute this if the right value is a constant*/
if
(
is_Const
(
right
))
{
tarval
*
bits_set
,
*
bits_not_set
;
ir_mode
*
m
=
get_tarval_mode
(
node
->
vrp
.
bits_not_set
);
bits_set
=
tarval_shl
(
left
->
vrp
.
bits_set
,
get_Const_tarval
(
right
));
bits_not_set
=
tarval_shl
(
left
->
vrp
.
bits_not_set
,
get_Const_tarval
(
right
));
ir_mode
*
m
=
get_tarval_mode
(
vrp
->
bits_not_set
);
bits_set
=
tarval_shl
(
vrp_
left
->
bits_set
,
get_Const_tarval
(
right
));
bits_not_set
=
tarval_shl
(
vrp_
left
->
bits_not_set
,
get_Const_tarval
(
right
));
new_bits_set
=
tarval_or
(
bits_set
,
node
->
vrp
.
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
node
->
vrp
.
bits_not_set
);
new_bits_set
=
tarval_or
(
bits_set
,
vrp
->
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
vrp
->
bits_not_set
);
bits_not_set
=
tarval_not
(
tarval_shl
(
get_mode_all_one
(
m
),
...
...
@@ -233,20 +250,21 @@ static int update_vrp_data(ir_node *node)
}
case
iro_Shr
:
{
ir_node
*
left
,
*
right
;
vrp_attr
*
vrp_left
,
*
vrp_right
;
ir_node
*
right
=
get_Shr_right
(
node
);
left
=
get_Shr_left
(
node
);
right
=
get_Shr_right
(
node
);
vrp_
left
=
phase_get_or_set_irn_data
(
phase
,
get_Shr_left
(
node
)
)
;
vrp_
right
=
phase_get_or_set_irn_data
(
phase
,
get_Shr_right
(
node
)
)
;
/* We can only compute this if the right value is a constant*/
if
(
is_Const
(
right
))
{
tarval
*
bits_set
,
*
bits_not_set
;
ir_mode
*
m
=
get_tarval_mode
(
node
->
vrp
.
bits_not_set
);
bits_set
=
tarval_shr
(
left
->
vrp
.
bits_set
,
get_Const_tarval
(
right
));
bits_not_set
=
tarval_shr
(
left
->
vrp
.
bits_not_set
,
get_Const_tarval
(
right
));
ir_mode
*
m
=
get_tarval_mode
(
vrp
->
bits_not_set
);
bits_set
=
tarval_shr
(
vrp_
left
->
bits_set
,
get_Const_tarval
(
right
));
bits_not_set
=
tarval_shr
(
vrp_
left
->
bits_not_set
,
get_Const_tarval
(
right
));
new_bits_set
=
tarval_or
(
bits_set
,
node
->
vrp
.
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
node
->
vrp
.
bits_not_set
);
new_bits_set
=
tarval_or
(
bits_set
,
vrp
->
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
vrp
->
bits_not_set
);
bits_not_set
=
tarval_not
(
tarval_shr
(
get_mode_all_one
(
m
),
...
...
@@ -257,20 +275,21 @@ static int update_vrp_data(ir_node *node)
}
case
iro_Shrs
:
{
ir_node
*
left
,
*
right
;
vrp_attr
*
vrp_left
,
*
vrp_right
;
ir_node
*
right
=
get_Shrs_right
(
node
);
left
=
get_Shrs_left
(
node
);
right
=
get_Shrs_right
(
node
);
vrp_
left
=
phase_get_or_set_irn_data
(
phase
,
get_Shrs_left
(
node
)
)
;
vrp_
right
=
phase_get_or_set_irn_data
(
phase
,
get_Shrs_right
(
node
)
)
;
/* We can only compute this if the right value is a constant*/
if
(
is_Const
(
right
))
{
tarval
*
bits_set
,
*
bits_not_set
;
ir_mode
*
m
=
get_tarval_mode
(
node
->
vrp
.
bits_not_set
);
bits_set
=
tarval_shrs
(
left
->
vrp
.
bits_set
,
get_Const_tarval
(
right
));
bits_not_set
=
tarval_shrs
(
left
->
vrp
.
bits_not_set
,
get_Const_tarval
(
right
));
ir_mode
*
m
=
get_tarval_mode
(
vrp
->
bits_not_set
);
bits_set
=
tarval_shrs
(
vrp_
left
->
bits_set
,
get_Const_tarval
(
right
));
bits_not_set
=
tarval_shrs
(
vrp_
left
->
bits_not_set
,
get_Const_tarval
(
right
));
new_bits_set
=
tarval_or
(
bits_set
,
node
->
vrp
.
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
node
->
vrp
.
bits_not_set
);
new_bits_set
=
tarval_or
(
bits_set
,
vrp
->
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
vrp
->
bits_not_set
);
bits_not_set
=
tarval_not
(
tarval_shrs
(
get_mode_all_one
(
m
),
...
...
@@ -281,46 +300,47 @@ static int update_vrp_data(ir_node *node)
}
case
iro_Eor
:
{
ir_node
*
left
,
*
right
;
vrp_attr
*
vrp_
left
,
*
vrp_
right
;
left
=
get_Eor_left
(
node
);
right
=
get_Eor_right
(
node
);
vrp_
left
=
phase_get_or_set_irn_data
(
phase
,
get_Eor_left
(
node
)
)
;
vrp_
right
=
phase_get_or_set_irn_data
(
phase
,
get_Eor_right
(
node
)
)
;
tarval
*
bits_set
,
*
bits_not_set
;
bits_not_set
=
tarval_or
(
tarval_and
(
left
->
vrp
.
bits_set
,
right
->
vrp
.
bits_set
),
tarval_and
(
left
->
vrp
.
bits_not_set
,
right
->
vrp
.
bits_not_set
));
tarval_and
(
vrp_
left
->
bits_set
,
vrp_
right
->
bits_set
),
tarval_and
(
vrp_
left
->
bits_not_set
,
vrp_
right
->
bits_not_set
));
bits_set
=
tarval_or
(
tarval_and
(
left
->
vrp
.
bits_set
,
right
->
vrp
.
bits_not_set
),
tarval_and
(
left
->
vrp
.
bits_not_set
,
right
->
vrp
.
bits_set
));
tarval_and
(
vrp_
left
->
bits_set
,
vrp_
right
->
bits_not_set
),
tarval_and
(
vrp_
left
->
bits_not_set
,
vrp_
right
->
bits_set
));
new_bits_set
=
tarval_or
(
bits_set
,
node
->
vrp
.
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
node
->
vrp
.
bits_not_set
);
new_bits_set
=
tarval_or
(
bits_set
,
vrp
->
bits_set
);
new_bits_not_set
=
tarval_or
(
bits_not_set
,
vrp
->
bits_not_set
);
break
;
}
case
iro_Id
:
{
ir_node
*
pred
=
get_Id_pred
(
node
);
new_bits_set
=
pred
->
vrp
.
bits_set
;
new_bits_not_set
=
pred
->
vrp
.
bits_not_set
;
new_range_top
=
pred
->
vrp
.
range_top
;
new_range_bottom
=
pred
->
vrp
.
range_bottom
;
new_range_type
=
pred
->
vrp
.
range_type
;
vrp_attr
*
vrp_pred
=
phase_get_or_set_irn_data
(
phase
,
get_Id_pred
(
node
)
)
;
new_bits_set
=
vrp_
pred
->
bits_set
;
new_bits_not_set
=
vrp_
pred
->
bits_not_set
;
new_range_top
=
vrp_
pred
->
range_top
;
new_range_bottom
=
vrp_
pred
->
range_bottom
;
new_range_type
=
vrp_
pred
->
range_type
;
break
;
}
case
iro_Not
:
{
ir_node
*
pred
=
get_Not_op
(
node
);
new_bits_set
=
tarval_or
(
pred
->
vrp
.
bits_not_set
,
node
->
vrp
.
bits_set
);
new_bits_not_set
=
tarval_or
(
pred
->
vrp
.
bits_set
,
node
->
vrp
.
bits_not_set
);
vrp_attr
*
vrp_pred
=
phase_get_or_set_irn_data
(
phase
,
get_Not_op
(
node
)
)
;
new_bits_set
=
tarval_or
(
vrp_
pred
->
bits_not_set
,
vrp
->
bits_set
);
new_bits_not_set
=
tarval_or
(
vrp_
pred
->
bits_set
,
vrp
->
bits_not_set
);
break
;
}
case
iro_Conv
:
{
ir_node
*
pred
=
get_Conv_op
(
node
);
ir_mode
*
old_mode
=
get_irn_mode
(
pred
);
vrp_attr
*
vrp_pred
=
phase_get_or_set_irn_data
(
phase
,
pred
);
ir_mode
*
new_mode
;
tarval
*
bits_not_set
;
...
...
@@ -335,17 +355,17 @@ static int update_vrp_data(ir_node *node)
tarval_convert_to
(
get_mode_all_one
(
old_mode
),
new_mode
));
bits_not_set
=
tarval_or
(
bits_not_set
,
tarval_convert_to
(
pred
->
vrp
.
bits_not_set
,
new_mode
));
new_bits_not_set
=
tarval_or
(
bits_not_set
,
node
->
vrp
.
bits_not_set
);
bits_not_set
=
tarval_or
(
bits_not_set
,
tarval_convert_to
(
vrp_
pred
->
bits_not_set
,
new_mode
));
new_bits_not_set
=
tarval_or
(
bits_not_set
,
vrp
->
bits_not_set
);
new_bits_set
=
tarval_and
(
tarval_not
(
bits_not_set
),
tarval_convert_to
(
pred
->
vrp
.
bits_set
,
new_mode
));
tarval_not
(
bits_not_set
),
tarval_convert_to
(
vrp_
pred
->
bits_set
,
new_mode
));
if
(
tarval_cmp
(
pred
->
vrp
.
range_top
,
get_mode_max
(
new_mode
))
==
pn_Cmp_Le
)
{
node
->
vrp
.
range_top
=
pred
->
vrp
.
range_top
;
if
(
tarval_cmp
(
vrp_
pred
->
range_top
,
get_mode_max
(
new_mode
))
==
pn_Cmp_Le
)
{
vrp
->
range_top
=
vrp_
pred
->
range_top
;
}
if
(
tarval_cmp
(
pred
->
vrp
.
range_bottom
,
get_mode_min
(
new_mode
))
==
pn_Cmp_Ge
)
{
node
->
vrp
.
range_bottom
=
pred
->
vrp
.
range_bottom
;
if
(
tarval_cmp
(
vrp_
pred
->
range_bottom
,
get_mode_min
(
new_mode
))
==
pn_Cmp_Ge
)
{
vrp
->
range_bottom
=
vrp_
pred
->
range_bottom
;
}
break
;
}
...
...
@@ -364,21 +384,21 @@ static int update_vrp_data(ir_node *node)
new_range_bottom
=
get_Const_tarval
(
bound
);
}
}
else
if
(
cmp
==
pn_Cmp_Le
)
{
if
(
node
->
vrp
.
range_type
==
VRP_UNDEFINED
)
{
if
(
vrp
->
range_type
==
VRP_UNDEFINED
)
{
new_range_type
=
VRP_RANGE
;
if
(
is_Const
(
bound
))
{
new_range_top
=
get_Const_tarval
(
bound
);
}
new_range_bottom
=
get_tarval_min
(
get_irn_mode
(
node
));
}
else
if
(
node
->
vrp
.
range_type
==
VRP_RANGE
)
{
}
else
if
(
vrp
->
range_type
==
VRP_RANGE
)
{
if
(
is_Const
(
bound
))
{
if
(
tarval_cmp
(
node
->
vrp
.
range_top
,
if
(
tarval_cmp
(
vrp
->
range_top
,
get_Const_tarval
(
bound
))
==
pn_Cmp_Le
)
{
new_range_top
=
get_Const_tarval
(
bound
);
}
new_range_bottom
=
get_tarval_min
(
get_irn_mode
(
node
));
}
else
if
(
node
->
vrp
.
range_type
==
VRP_ANTIRANGE
)
{
}
else
if
(
vrp
->
range_type
==
VRP_ANTIRANGE
)
{
/** @todo: How do we manage not to get a never ending loop? */
}
}
...
...
@@ -390,11 +410,12 @@ static int update_vrp_data(ir_node *node)
/* combine all ranges*/
ir_node
*
pred
=
get_Phi_pred
(
node
,
0
);
new_range_top
=
pred
->
vrp
.
range_top
;
new_range_bottom
=
pred
->
vrp
.
range_bottom
;
new_range_type
=
pred
->
vrp
.
range_type
;
new_bits_set
=
pred
->
vrp
.
bits_set
;
new_bits_not_set
=
pred
->
vrp
.
bits_not_set
;
vrp_attr
*
vrp_pred
=
phase_get_or_set_irn_data
(
phase
,
pred
);
new_range_top
=
vrp_pred
->
range_top
;
new_range_bottom
=
vrp_pred
->
range_bottom
;
new_range_type
=
vrp_pred
->
range_type
;
new_bits_set
=
vrp_pred
->
bits_set
;
new_bits_not_set
=
vrp_pred
->
bits_not_set
;
int
num
=
get_Phi_n_preds
(
node
);
pn_Cmp
cmp
;
...
...
@@ -405,15 +426,16 @@ static int update_vrp_data(ir_node *node)
for
(
i
=
1
;
i
<
num
;
i
++
)
{
pred
=
get_Phi_pred
(
node
,
i
);
if
(
new_range_type
==
VRP_RANGE
&&
pred
->
vrp
.
range_type
==
vrp_pred
=
phase_get_or_set_irn_data
(
phase
,
pred
);
if
(
new_range_type
==
VRP_RANGE
&&
vrp_pred
->
range_type
==
VRP_RANGE
)
{
cmp
=
tarval_cmp
(
new_range_top
,
pred
->
vrp
.
range_top
);
cmp
=
tarval_cmp
(
new_range_top
,
vrp_
pred
->
range_top
);
if
(
cmp
==
pn_Cmp_Lt
)
{
new_range_top
=
pred
->
vrp
.
range_top
;
new_range_top
=
vrp_
pred
->
range_top
;
}
cmp
=
tarval_cmp
(
new_range_bottom
,
pred
->
vrp
.
range_bottom
);
cmp
=
tarval_cmp
(
new_range_bottom
,
vrp_
pred
->
range_bottom
);
if
(
cmp
==
pn_Cmp_Gt
)
{
new_range_bottom
=
pred
->
vrp
.
range_bottom
;
new_range_bottom
=
vrp_
pred
->
range_bottom
;
}
}
else
{
new_range_type
=
VRP_VARYING
;
...
...
@@ -423,7 +445,6 @@ static int update_vrp_data(ir_node *node)
break
;
}
default:
/* unhandled, therefore never updated */
break
;
...
...
@@ -445,75 +466,74 @@ static int update_vrp_data(ir_node *node)
*/
/* Merge the newly calculated values with those that might already exist*/
if
(
new_bits_set
!=
tarval_bad
)
{
new_bits_set
=
tarval_or
(
new_bits_set
,
node
->
vrp
.
bits_set
);
if
(
tarval_cmp
(
new_bits_set
,
node
->
vrp
.
bits_set
)
!=
pn_Cmp_Eq
)
{
new_bits_set
=
tarval_or
(
new_bits_set
,
vrp
->
bits_set
);
if
(
tarval_cmp
(
new_bits_set
,
vrp
->
bits_set
)
!=
pn_Cmp_Eq
)
{
something_changed
=
1
;
node
->
vrp
.
bits_set
=
new_bits_set
;
vrp
->
bits_set
=
new_bits_set
;
}
}
if
(
new_bits_not_set
!=
tarval_bad
)
{
new_bits_not_set
=
tarval_or
(
new_bits_not_set
,
node
->
vrp
.
bits_not_set
);
new_bits_not_set
=
tarval_or
(
new_bits_not_set
,
vrp
->
bits_not_set
);
if
(
tarval_cmp
(
new_bits_not_set
,
node
->
vrp
.
bits_not_set
)
!=
pn_Cmp_Eq
)
{
if
(
tarval_cmp
(
new_bits_not_set
,
vrp
->
bits_not_set
)
!=
pn_Cmp_Eq
)
{
something_changed
=
1
;
node
->
vrp
.
bits_not_set
=
new_bits_not_set
;
vrp
->
bits_not_set
=
new_bits_not_set
;
}
}
if
(
node
->
vrp
.
bits_node
==
NULL
&&
new_bits_node
!=
NULL
)
{
if
(
vrp
->
bits_node
==
NULL
&&
new_bits_node
!=
NULL
)
{
something_changed
=
1
;
node
->
vrp
.
bits_node
=
new_bits_node
;
vrp
->
bits_node
=
new_bits_node
;
}
if
(
node
->
vrp
.
range_type
==
VRP_UNDEFINED
&&
if
(
vrp
->
range_type
==
VRP_UNDEFINED
&&
new_range_type
!=
VRP_UNDEFINED
)
{
something_changed
=
1
;
node
->
vrp
.
range_type
=
new_range_type
;
node
->
vrp
.
range_bottom
=
new_range_bottom
;
node
->
vrp
.
range_top
=
new_range_top
;
node
->
vrp
.
range_op
=
new_range_op
;
node
->
vrp
.
range_node
=
new_range_node
;
vrp
->
range_type
=
new_range_type
;
vrp
->
range_bottom
=
new_range_bottom
;
vrp
->
range_top
=
new_range_top
;
vrp
->
range_op
=
new_range_op
;
vrp
->
range_node
=
new_range_node
;
}
else
if
(
node
->
vrp
.
range_type
==
VRP_RANGE
)
{
}
else
if
(
vrp
->
range_type
==
VRP_RANGE
)
{
if
(
new_range_type
==
VRP_RANGE
)
{
if
((
new_range_node
==
NULL
&&
node
->
vrp
.
range_node
==
NULL
)
||
(
new_range_node
==
node
->
vrp
.
range_node
&&
new_range_op
==
node
->
vrp
.
range_op
))
{
if
(
tarval_cmp
(
node
->
vrp
.
range_bottom
,
new_range_bottom
)
==
pn_Cmp_Lt
)
{
if
((
new_range_node
==
NULL
&&
vrp
->
range_node
==
NULL
)
||
(
new_range_node
==
vrp
->
range_node
&&
new_range_op
==
vrp
->
range_op
))
{
if
(
tarval_cmp
(
vrp
->
range_bottom
,
new_range_bottom
)
==
pn_Cmp_Lt
)
{
something_changed
=
1
;
node
->
vrp
.
range_bottom
=
new_range_bottom
;
vrp
->
range_bottom
=
new_range_bottom
;
}
if
(
tarval_cmp
(
node
->
vrp
.
range_top
,
new_range_top
)
==
pn_Cmp_Gt
)
{
if
(
tarval_cmp
(
vrp
->
range_top
,
new_range_top
)
==
pn_Cmp_Gt
)
{
something_changed
=
1
;
node
->
vrp
.
range_top
=
new_range_top
;
vrp
->
range_top
=
new_range_top
;
}
}
/* prefer the absolute value*/
if
(
new_range_node
==
NULL
&&
node
->
vrp
.
range_node
!=
NULL
)
{
if
(
new_range_node
==
NULL
&&
vrp
->
range_node
!=
NULL
)
{
something_changed
=
1
;
node
->
vrp
.
range_node
=
NULL
;
node
->
vrp
.
range_top
=
new_range_top
;
node
->
vrp
.
range_bottom
=
new_range_bottom
;
vrp
->
range_node
=
NULL
;
vrp
->
range_top
=
new_range_top
;
vrp
->
range_bottom
=
new_range_bottom
;
}
}
if
(
new_range_type
==
VRP_ANTIRANGE
)
{
/* if they are overlapping, cut the range.*/
/* TODO: Maybe we can preserve more information here*/
if
(
new_range_node
==
NULL
&&
node
->
vrp
.
range_node
==
NULL
)
{
if
(
tarval_cmp
(
node
->
vrp
.
range_bottom
,
new_range_top
)
==
pn_Cmp_Gt
&&
tarval_cmp
(
node
->
vrp
.
range_bottom
,
new_range_bottom
)
==
pn_Cmp_Gt
)
{
if
(
new_range_node
==
NULL
&&
vrp
->
range_node
==
NULL
)
{
if
(
tarval_cmp
(
vrp
->
range_bottom
,
new_range_top
)
==
pn_Cmp_Gt
&&
tarval_cmp
(
vrp
->
range_bottom
,
new_range_bottom
)
==
pn_Cmp_Gt
)
{
something_changed
=
1
;