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
c56025f3
Commit
c56025f3
authored
Oct 30, 2013
by
Matthias Braun
Browse files
cleanup, use C99
parent
dc38d853
Changes
1
Show whitespace changes
Inline
Side-by-side
ir/opt/jumpthreading.c
View file @
c56025f3
...
@@ -51,14 +51,8 @@ static ir_node *ssa_second_def;
...
@@ -51,14 +51,8 @@ static ir_node *ssa_second_def;
static
ir_node
*
ssa_second_def_block
;
static
ir_node
*
ssa_second_def_block
;
static
ir_node
*
search_def_and_create_phis
(
ir_node
*
block
,
ir_mode
*
mode
,
static
ir_node
*
search_def_and_create_phis
(
ir_node
*
block
,
ir_mode
*
mode
,
int
first
)
bool
first
)
{
{
int
i
;
int
n_cfgpreds
;
ir_graph
*
irg
;
ir_node
*
phi
;
ir_node
*
dummy
;
/* In case of a bad input to a block we need to return the bad value */
/* In case of a bad input to a block we need to return the bad value */
if
(
is_Bad
(
block
))
{
if
(
is_Bad
(
block
))
{
ir_graph
*
irg
=
get_irn_irg
(
block
);
ir_graph
*
irg
=
get_irn_irg
(
block
);
...
@@ -80,15 +74,15 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
...
@@ -80,15 +74,15 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
return
value
;
return
value
;
}
}
irg
=
get_irn_irg
(
block
);
ir_graph
*
irg
=
get_irn_irg
(
block
);
assert
(
block
!=
get_irg_start_block
(
irg
));
assert
(
block
!=
get_irg_start_block
(
irg
));
/* a Block with only 1 predecessor needs no Phi */
/* a Block with only 1 predecessor needs no Phi */
n_cfgpreds
=
get_Block_n_cfgpreds
(
block
);
int
n_cfgpreds
=
get_Block_n_cfgpreds
(
block
);
if
(
n_cfgpreds
==
1
)
{
if
(
n_cfgpreds
==
1
)
{
ir_node
*
pred_block
=
get_Block_cfgpred_block
(
block
,
0
);
ir_node
*
pred_block
=
get_Block_cfgpred_block
(
block
,
0
);
ir_node
*
value
=
search_def_and_create_phis
(
pred_block
,
mode
,
0
);
ir_node
*
value
=
search_def_and_create_phis
(
pred_block
,
mode
,
false
);
set_irn_link
(
block
,
value
);
set_irn_link
(
block
,
value
);
mark_irn_visited
(
block
);
mark_irn_visited
(
block
);
return
value
;
return
value
;
...
@@ -96,19 +90,19 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
...
@@ -96,19 +90,19 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
/* create a new Phi */
/* create a new Phi */
ir_node
**
in
=
ALLOCAN
(
ir_node
*
,
n_cfgpreds
);
ir_node
**
in
=
ALLOCAN
(
ir_node
*
,
n_cfgpreds
);
dummy
=
new_r_Dummy
(
irg
,
mode
);
ir_node
*
dummy
=
new_r_Dummy
(
irg
,
mode
);
for
(
i
=
0
;
i
<
n_cfgpreds
;
++
i
)
for
(
int
i
=
0
;
i
<
n_cfgpreds
;
++
i
)
in
[
i
]
=
dummy
;
in
[
i
]
=
dummy
;
phi
=
new_r_Phi
(
block
,
n_cfgpreds
,
in
,
mode
);
ir_node
*
phi
=
new_r_Phi
(
block
,
n_cfgpreds
,
in
,
mode
);
set_irn_link
(
block
,
phi
);
set_irn_link
(
block
,
phi
);
mark_irn_visited
(
block
);
mark_irn_visited
(
block
);
/* set Phi predecessors */
/* set Phi predecessors */
for
(
i
=
0
;
i
<
n_cfgpreds
;
++
i
)
{
for
(
int
i
=
0
;
i
<
n_cfgpreds
;
++
i
)
{
ir_node
*
pred_block
=
get_Block_cfgpred_block
(
block
,
i
);
ir_node
*
pred_block
=
get_Block_cfgpred_block
(
block
,
i
);
ir_node
*
pred_val
=
search_def_and_create_phis
(
pred_block
,
mode
,
0
);
ir_node
*
pred_val
=
search_def_and_create_phis
(
pred_block
,
mode
,
false
);
set_irn_n
(
phi
,
i
,
pred_val
);
set_irn_n
(
phi
,
i
,
pred_val
);
}
}
...
@@ -123,17 +117,14 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
...
@@ -123,17 +117,14 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
static
void
construct_ssa
(
ir_node
*
orig_block
,
ir_node
*
orig_val
,
static
void
construct_ssa
(
ir_node
*
orig_block
,
ir_node
*
orig_val
,
ir_node
*
second_block
,
ir_node
*
second_val
)
ir_node
*
second_block
,
ir_node
*
second_val
)
{
{
ir_graph
*
irg
;
ir_mode
*
mode
;
/* no need to do anything */
/* no need to do anything */
if
(
orig_val
==
second_val
)
if
(
orig_val
==
second_val
)
return
;
return
;
irg
=
get_irn_irg
(
orig_val
);
ir_graph
*
irg
=
get_irn_irg
(
orig_val
);
inc_irg_visited
(
irg
);
inc_irg_visited
(
irg
);
mode
=
get_irn_mode
(
orig_val
);
ir_mode
*
mode
=
get_irn_mode
(
orig_val
);
set_irn_link
(
orig_block
,
orig_val
);
set_irn_link
(
orig_block
,
orig_val
);
mark_irn_visited
(
orig_block
);
mark_irn_visited
(
orig_block
);
...
@@ -143,26 +134,27 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
...
@@ -143,26 +134,27 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
/* Only fix the users of the first, i.e. the original node */
/* Only fix the users of the first, i.e. the original node */
foreach_out_edge_safe
(
orig_val
,
edge
)
{
foreach_out_edge_safe
(
orig_val
,
edge
)
{
ir_node
*
user
=
get_edge_src_irn
(
edge
);
ir_node
*
user
=
get_edge_src_irn
(
edge
);
int
j
=
get_edge_src_pos
(
edge
);
ir_node
*
user_block
=
get_nodes_block
(
user
);
ir_node
*
newval
;
/* ignore keeps */
/* ignore keeps */
if
(
is_End
(
user
))
if
(
is_End
(
user
))
continue
;
continue
;
DB
((
dbg
,
LEVEL_3
,
">>> Fixing user %+F (pred %d == %+F)
\n
"
,
user
,
j
,
get_irn_n
(
user
,
j
)));
int
j
=
get_edge_src_pos
(
edge
);
DB
((
dbg
,
LEVEL_3
,
">>> Fixing user %+F (pred %d == %+F)
\n
"
,
user
,
j
,
get_irn_n
(
user
,
j
)));
ir_node
*
user_block
=
get_nodes_block
(
user
);
ir_node
*
newval
;
if
(
is_Phi
(
user
))
{
if
(
is_Phi
(
user
))
{
ir_node
*
pred_block
=
get_Block_cfgpred_block
(
user_block
,
j
);
ir_node
*
pred_block
=
get_Block_cfgpred_block
(
user_block
,
j
);
newval
=
search_def_and_create_phis
(
pred_block
,
mode
,
1
);
newval
=
search_def_and_create_phis
(
pred_block
,
mode
,
true
);
}
else
{
}
else
{
newval
=
search_def_and_create_phis
(
user_block
,
mode
,
1
);
newval
=
search_def_and_create_phis
(
user_block
,
mode
,
true
);
}
}
/* don't fix newly created Phis from the SSA construction */
/* don't fix newly created Phis from the SSA construction */
if
(
newval
!=
user
)
{
if
(
newval
!=
user
)
{
DB
((
dbg
,
LEVEL_4
,
">>>> Setting input %d of %+F to %+F
\n
"
,
j
,
user
,
newval
));
DB
((
dbg
,
LEVEL_4
,
">>>> Setting input %d of %+F to %+F
\n
"
,
j
,
user
,
newval
));
set_irn_n
(
user
,
j
,
newval
);
set_irn_n
(
user
,
j
,
newval
);
}
}
}
}
...
@@ -181,24 +173,20 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
...
@@ -181,24 +173,20 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
static
void
split_critical_edge
(
ir_node
*
block
,
int
pos
)
static
void
split_critical_edge
(
ir_node
*
block
,
int
pos
)
{
{
ir_graph
*
irg
=
get_irn_irg
(
block
);
ir_graph
*
irg
=
get_irn_irg
(
block
);
ir_node
*
in
[
1
];
ir_node
*
in
[]
=
{
get_Block_cfgpred
(
block
,
pos
)
};
ir_node
*
new_block
;
ir_node
*
new_block
=
new_r_Block
(
irg
,
ARRAY_SIZE
(
in
),
in
);
ir_node
*
new_jmp
;
ir_node
*
new_jmp
=
new_r_Jmp
(
new_block
);
in
[
0
]
=
get_Block_cfgpred
(
block
,
pos
);
new_block
=
new_r_Block
(
irg
,
1
,
in
);
new_jmp
=
new_r_Jmp
(
new_block
);
set_Block_cfgpred
(
block
,
pos
,
new_jmp
);
set_Block_cfgpred
(
block
,
pos
,
new_jmp
);
}
}
typedef
struct
jumpthreading_env_t
{
typedef
struct
jumpthreading_env_t
{
ir_node
*
true_block
;
ir_node
*
true_block
;
ir_node
*
cmp
;
/**< The Compare node that might be partial evaluated */
ir_node
*
cmp
;
/**< The Compare node that might be partial
evaluated */
ir_relation
relation
;
/**< The Compare mode of the Compare node. */
ir_relation
relation
;
/**< The Compare mode of the Compare node. */
ir_node
*
cnst
;
ir_node
*
cnst
;
ir_tarval
*
tv
;
ir_tarval
*
tv
;
ir_visited_t
visited_nr
;
ir_visited_t
visited_nr
;
ir_node
*
cnst_pred
;
/**< the block before the constant */
ir_node
*
cnst_pred
;
/**< the block before the constant */
int
cnst_pos
;
/**< the pos to the constant block (needed to
int
cnst_pos
;
/**< the pos to the constant block (needed to
kill that edge later) */
kill that edge later) */
...
@@ -208,10 +196,8 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
...
@@ -208,10 +196,8 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
ir_node
*
block
,
ir_node
*
copy_block
,
int
j
,
ir_node
*
block
,
ir_node
*
copy_block
,
int
j
,
ir_node
*
node
)
ir_node
*
node
)
{
{
int
i
,
arity
;
ir_node
*
copy
;
/* we can evaluate Phis right now, all other nodes get copied */
/* we can evaluate Phis right now, all other nodes get copied */
ir_node
*
copy
;
if
(
is_Phi
(
node
))
{
if
(
is_Phi
(
node
))
{
copy
=
get_Phi_pred
(
node
,
j
);
copy
=
get_Phi_pred
(
node
,
j
);
/* we might have to evaluate a Phi-cascade */
/* we might have to evaluate a Phi-cascade */
...
@@ -221,17 +207,14 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
...
@@ -221,17 +207,14 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
}
else
{
}
else
{
copy
=
exact_copy
(
node
);
copy
=
exact_copy
(
node
);
set_nodes_block
(
copy
,
copy_block
);
set_nodes_block
(
copy
,
copy_block
);
assert
(
get_irn_mode
(
copy
)
!=
mode_X
);
assert
(
get_irn_mode
(
copy
)
!=
mode_X
);
arity
=
get_irn_arity
(
copy
);
for
(
int
i
=
0
,
arity
=
get_irn_arity
(
copy
);
i
<
arity
;
++
i
)
{
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
pred
=
get_irn_n
(
copy
,
i
);
ir_node
*
pred
=
get_irn_n
(
copy
,
i
);
ir_node
*
new_pred
;
if
(
get_nodes_block
(
pred
)
!=
block
)
if
(
get_nodes_block
(
pred
)
!=
block
)
continue
;
continue
;
ir_node
*
new_pred
;
if
(
get_irn_visited
(
pred
)
>=
env
->
visited_nr
)
{
if
(
get_irn_visited
(
pred
)
>=
env
->
visited_nr
)
{
new_pred
=
(
ir_node
*
)
get_irn_link
(
pred
);
new_pred
=
(
ir_node
*
)
get_irn_link
(
pred
);
}
else
{
}
else
{
...
@@ -254,18 +237,14 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
...
@@ -254,18 +237,14 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
/* Look at all nodes in the cond_block and copy them into pred */
/* Look at all nodes in the cond_block and copy them into pred */
foreach_out_edge
(
block
,
edge
)
{
foreach_out_edge
(
block
,
edge
)
{
ir_node
*
node
=
get_edge_src_irn
(
edge
);
ir_node
*
node
=
get_edge_src_irn
(
edge
);
ir_node
*
copy
;
ir_mode
*
mode
;
if
(
is_End
(
node
))
{
if
(
is_End
(
node
))
{
/* edge is a Keep edge. If the end block is unreachable via normal
/* edge is a Keep edge. If the end block is unreachable via normal
* control flow, we must maintain end's reachability with Keeps.
* control flow, we must maintain end's reachability with Keeps. */
*/
keep_alive
(
copy_block
);
keep_alive
(
copy_block
);
continue
;
continue
;
}
}
/* ignore control flow */
/* ignore control flow */
mode
=
get_irn_mode
(
node
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
if
(
mode
==
mode_X
||
is_Cond
(
node
)
||
is_Switch
(
node
))
if
(
mode
==
mode_X
||
is_Cond
(
node
)
||
is_Switch
(
node
))
continue
;
continue
;
#ifdef AVOID_PHIB
#ifdef AVOID_PHIB
...
@@ -287,14 +266,13 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
...
@@ -287,14 +266,13 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
cmp_copy
=
exact_copy
(
pred
);
cmp_copy
=
exact_copy
(
pred
);
set_nodes_block
(
cmp_copy
,
user_block
);
set_nodes_block
(
cmp_copy
,
user_block
);
copy
=
new_r_Proj
(
cmp_copy
,
mode_b
,
pn
);
ir_node
*
copy
=
new_r_Proj
(
cmp_copy
,
mode_b
,
pn
);
set_irn_n
(
user
,
pos
,
copy
);
set_irn_n
(
user
,
pos
,
copy
);
}
}
continue
;
continue
;
}
}
#endif
#endif
ir_node
*
copy
=
copy_and_fix_node
(
env
,
block
,
copy_block
,
j
,
node
);
copy
=
copy_and_fix_node
(
env
,
block
,
copy_block
,
j
,
node
);
/* we might hit values in blocks that have already been processed by a
/* we might hit values in blocks that have already been processed by a
* recursive find_phi_with_const() call */
* recursive find_phi_with_const() call */
...
@@ -309,10 +287,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
...
@@ -309,10 +287,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
/* fix data-flow (and reconstruct SSA if needed) */
/* fix data-flow (and reconstruct SSA if needed) */
foreach_out_edge
(
block
,
edge
)
{
foreach_out_edge
(
block
,
edge
)
{
ir_node
*
node
=
get_edge_src_irn
(
edge
);
ir_node
*
node
=
get_edge_src_irn
(
edge
);
ir_node
*
copy_node
;
ir_mode
*
mode
=
get_irn_mode
(
node
);
ir_mode
*
mode
;
mode
=
get_irn_mode
(
node
);
if
(
mode
==
mode_X
||
is_Cond
(
node
)
||
is_Switch
(
node
))
if
(
mode
==
mode_X
||
is_Cond
(
node
)
||
is_Switch
(
node
))
continue
;
continue
;
#ifdef AVOID_PHIB
#ifdef AVOID_PHIB
...
@@ -322,7 +297,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
...
@@ -322,7 +297,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
DB
((
dbg
,
LEVEL_2
,
">> Fixing users of %+F
\n
"
,
node
));
DB
((
dbg
,
LEVEL_2
,
">> Fixing users of %+F
\n
"
,
node
));
copy_node
=
(
ir_node
*
)
get_irn_link
(
node
);
ir_node
*
copy_node
=
(
ir_node
*
)
get_irn_link
(
node
);
construct_ssa
(
block
,
node
,
copy_block
,
copy_node
);
construct_ssa
(
block
,
node
,
copy_block
,
copy_node
);
}
}
...
@@ -339,12 +314,12 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
...
@@ -339,12 +314,12 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
}
}
/**
/**
* returns whether the cmp evaluates to true or false, or can't be evaluated!
* Returns whether the cmp evaluates to true or false, or can't be evaluated!
* 1: true, 0: false, -1: can't evaluate
*
*
* @param relation the compare mode of the Compare
* @param relation the compare mode of the Compare
* @param tv_left the left tarval
* @param tv_left the left tarval
* @param tv_right the right tarval
* @param tv_right the right tarval
* @returns 1: true, 0: false, -1: can't evaluate
*/
*/
static
int
eval_cmp_tv
(
ir_relation
relation
,
ir_tarval
*
tv_left
,
static
int
eval_cmp_tv
(
ir_relation
relation
,
ir_tarval
*
tv_left
,
ir_tarval
*
tv_right
)
ir_tarval
*
tv_right
)
...
@@ -361,22 +336,22 @@ static int eval_cmp_tv(ir_relation relation, ir_tarval *tv_left,
...
@@ -361,22 +336,22 @@ static int eval_cmp_tv(ir_relation relation, ir_tarval *tv_left,
}
}
/**
/**
* returns whether the cmp evaluates to true or false, or can't be evaluated!
* Returns whether the cmp evaluates to true or false, or can't be evaluated!
* 1: true, 0: false, -1: can't evaluate
*
*
* @param env the environment
* @param env the environment
* @param cand the candidate node, either a Const or a Confirm
* @param cand the candidate node, either a Const or a Confirm
* @returns 1: true, 0: false, -1: can't evaluate
*/
*/
static
int
eval_cmp
(
jumpthreading_env_t
*
env
,
ir_node
*
cand
)
static
int
eval_cmp
(
jumpthreading_env_t
*
env
,
ir_node
*
cand
)
{
{
if
(
is_Const
(
cand
))
{
if
(
is_Const
(
cand
))
{
ir_tarval
*
tv_cand
=
get_Const_tarval
(
cand
);
ir_tarval
*
tv_cand
=
get_Const_tarval
(
cand
);
ir_tarval
*
tv_cmp
=
get_Const_tarval
(
env
->
cnst
);
ir_tarval
*
tv_cmp
=
get_Const_tarval
(
env
->
cnst
);
return
eval_cmp_tv
(
env
->
relation
,
tv_cand
,
tv_cmp
);
return
eval_cmp_tv
(
env
->
relation
,
tv_cand
,
tv_cmp
);
}
else
{
/* a Confirm */
}
else
{
ir_tarval
*
res
=
computed_value_Cmp_Confirm
(
env
->
cmp
,
cand
,
env
->
cnst
,
env
->
relation
);
assert
(
is_Confirm
(
cand
));
ir_tarval
*
res
=
computed_value_Cmp_Confirm
(
env
->
cmp
,
cand
,
env
->
cnst
,
env
->
relation
);
if
(
res
==
tarval_bad
)
if
(
res
==
tarval_bad
)
return
-
1
;
return
-
1
;
return
res
==
tarval_b_true
;
return
res
==
tarval_b_true
;
...
@@ -386,7 +361,7 @@ static int eval_cmp(jumpthreading_env_t *env, ir_node *cand)
...
@@ -386,7 +361,7 @@ static int eval_cmp(jumpthreading_env_t *env, ir_node *cand)
/**
/**
* Check for Const or Confirm with Const.
* Check for Const or Confirm with Const.
*/
*/
static
int
is_Const_or_Confirm
(
const
ir_node
*
node
)
static
bool
is_Const_or_Confirm
(
const
ir_node
*
node
)
{
{
if
(
is_Confirm
(
node
))
if
(
is_Confirm
(
node
))
node
=
get_Confirm_bound
(
node
);
node
=
get_Confirm_bound
(
node
);
...
@@ -398,30 +373,24 @@ static int is_Const_or_Confirm(const ir_node *node)
...
@@ -398,30 +373,24 @@ static int is_Const_or_Confirm(const ir_node *node)
*/
*/
static
ir_tarval
*
get_Const_or_Confirm_tarval
(
const
ir_node
*
node
)
static
ir_tarval
*
get_Const_or_Confirm_tarval
(
const
ir_node
*
node
)
{
{
if
(
is_Confirm
(
node
))
{
if
(
is_Confirm
(
node
))
if
(
get_Confirm_bound
(
node
))
node
=
get_Confirm_bound
(
node
);
node
=
get_Confirm_bound
(
node
);
}
return
get_Const_tarval
(
node
);
return
get_Const_tarval
(
node
);
}
}
static
ir_node
*
find_const_or_confirm
(
jumpthreading_env_t
*
env
,
ir_node
*
jump
,
static
ir_node
*
find_const_or_confirm
(
jumpthreading_env_t
*
env
,
ir_node
*
jump
,
ir_node
*
value
)
ir_node
*
value
)
{
{
ir_node
*
block
=
get_nodes_block
(
jump
);
if
(
irn_visited_else_mark
(
value
))
if
(
irn_visited_else_mark
(
value
))
return
NULL
;
return
NULL
;
ir_node
*
block
=
get_nodes_block
(
jump
);
if
(
is_Const_or_Confirm
(
value
))
{
if
(
is_Const_or_Confirm
(
value
))
{
if
(
eval_cmp
(
env
,
value
)
<=
0
)
if
(
eval_cmp
(
env
,
value
)
<=
0
)
return
NULL
;
return
NULL
;
DB
((
DB
((
dbg
,
LEVEL_1
,
"> Found jump threading candidate %+F->%+F
\n
"
,
dbg
,
LEVEL_1
,
block
,
env
->
true_block
));
"> Found jump threading candidate %+F->%+F
\n
"
,
block
,
env
->
true_block
));
/* adjust true_block to point directly towards our jump */
/* adjust true_block to point directly towards our jump */
add_pred
(
env
->
true_block
,
jump
);
add_pred
(
env
->
true_block
,
jump
);
...
@@ -430,30 +399,23 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
...
@@ -430,30 +399,23 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
/* we need a bigger visited nr when going back */
/* we need a bigger visited nr when going back */
env
->
visited_nr
++
;
env
->
visited_nr
++
;
return
block
;
return
block
;
}
}
if
(
is_Phi
(
value
))
{
if
(
is_Phi
(
value
))
{
int
i
,
arity
;
/* the Phi has to be in the same Block as the Jmp */
/* the Phi has to be in the same Block as the Jmp */
if
(
get_nodes_block
(
value
)
!=
block
)
if
(
get_nodes_block
(
value
)
!=
block
)
return
NULL
;
return
NULL
;
arity
=
get_irn_arity
(
value
);
for
(
int
i
=
0
,
arity
=
get_irn_arity
(
value
);
i
<
arity
;
++
i
)
{
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
copy_block
;
ir_node
*
phi_pred
=
get_Phi_pred
(
value
,
i
);
ir_node
*
phi_pred
=
get_Phi_pred
(
value
,
i
);
ir_node
*
cfgpred
=
get_Block_cfgpred
(
block
,
i
);
ir_node
*
cfgpred
=
get_Block_cfgpred
(
block
,
i
);
ir_node
*
copy_block
=
find_const_or_confirm
(
env
,
cfgpred
,
phi_pred
);
copy_block
=
find_const_or_confirm
(
env
,
cfgpred
,
phi_pred
);
if
(
copy_block
==
NULL
)
if
(
copy_block
==
NULL
)
continue
;
continue
;
/* copy duplicated nodes in copy_block and fix SSA */
/* copy duplicated nodes in copy_block and fix SSA */
copy_and_fix
(
env
,
block
,
copy_block
,
i
);
copy_and_fix
(
env
,
block
,
copy_block
,
i
);
if
(
copy_block
==
get_nodes_block
(
cfgpred
))
{
if
(
copy_block
==
get_nodes_block
(
cfgpred
))
{
env
->
cnst_pred
=
block
;
env
->
cnst_pred
=
block
;
env
->
cnst_pos
=
i
;
env
->
cnst_pos
=
i
;
...
@@ -470,23 +432,17 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
...
@@ -470,23 +432,17 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
static
ir_node
*
find_candidate
(
jumpthreading_env_t
*
env
,
ir_node
*
jump
,
static
ir_node
*
find_candidate
(
jumpthreading_env_t
*
env
,
ir_node
*
jump
,
ir_node
*
value
)
ir_node
*
value
)
{
{
ir_node
*
block
=
get_nodes_block
(
jump
);
if
(
irn_visited_else_mark
(
value
))
if
(
irn_visited_else_mark
(
value
))
{
return
NULL
;
return
NULL
;
}
ir_node
*
block
=
get_nodes_block
(
jump
);
if
(
is_Const_or_Confirm
(
value
))
{
if
(
is_Const_or_Confirm
(
value
))
{
ir_tarval
*
tv
=
get_Const_or_Confirm_tarval
(
value
);
ir_tarval
*
tv
=
get_Const_or_Confirm_tarval
(
value
);
if
(
tv
!=
env
->
tv
)
if
(
tv
!=
env
->
tv
)
return
NULL
;
return
NULL
;
DB
((
DB
((
dbg
,
LEVEL_1
,
"> Found jump threading candidate %+F->%+F
\n
"
,
dbg
,
LEVEL_1
,
block
,
env
->
true_block
));
"> Found jump threading candidate %+F->%+F
\n
"
,
block
,
env
->
true_block
));
/* adjust true_block to point directly towards our jump */
/* adjust true_block to point directly towards our jump */
add_pred
(
env
->
true_block
,
jump
);
add_pred
(
env
->
true_block
,
jump
);
...
@@ -495,29 +451,22 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
...
@@ -495,29 +451,22 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
/* we need a bigger visited nr when going back */
/* we need a bigger visited nr when going back */
env
->
visited_nr
++
;
env
->
visited_nr
++
;
return
block
;
return
block
;
}
}
if
(
is_Phi
(
value
))
{
if
(
is_Phi
(
value
))
{
int
i
,
arity
;
/* the Phi has to be in the same Block as the Jmp */
/* the Phi has to be in the same Block as the Jmp */
if
(
get_nodes_block
(
value
)
!=
block
)
if
(
get_nodes_block
(
value
)
!=
block
)
return
NULL
;
return
NULL
;
arity
=
get_irn_arity
(
value
);
for
(
int
i
=
0
,
arity
=
get_irn_arity
(
value
);
i
<
arity
;
++
i
)
{
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
copy_block
;
ir_node
*
phi_pred
=
get_Phi_pred
(
value
,
i
);
ir_node
*
phi_pred
=
get_Phi_pred
(
value
,
i
);
ir_node
*
cfgpred
=
get_Block_cfgpred
(
block
,
i
);
ir_node
*
cfgpred
=
get_Block_cfgpred
(
block
,
i
);
ir_node
*
copy_block
=
find_candidate
(
env
,
cfgpred
,
phi_pred
);
copy_block
=
find_candidate
(
env
,
cfgpred
,
phi_pred
);
if
(
copy_block
==
NULL
)
if
(
copy_block
==
NULL
)
continue
;
continue
;
/* copy duplicated nodes in copy_block and fix SSA */
/* copy duplicated nodes in copy_block and fix SSA */
copy_and_fix
(
env
,
block
,
copy_block
,
i
);
copy_and_fix
(
env
,
block
,
copy_block
,
i
);
if
(
copy_block
==
get_nodes_block
(
cfgpred
))
{
if
(
copy_block
==
get_nodes_block
(
cfgpred
))
{
env
->
cnst_pred
=
block
;
env
->
cnst_pred
=
block
;
env
->
cnst_pos
=
i
;
env
->
cnst_pos
=
i
;
...
@@ -550,15 +499,13 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
...
@@ -550,15 +499,13 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
return
NULL
;
return
NULL
;
/* negate condition when we're looking for the false block */
/* negate condition when we're looking for the false block */
if
(
env
->
tv
==
tarval_b_false
)
{
if
(
env
->
tv
==
tarval_b_false
)
relation
=
get_negated_relation
(
relation
);
relation
=
get_negated_relation
(
relation
);
}
/* (recursively) look if a pred of a Phi is a constant or a Confirm */
/* (recursively) look if a pred of a Phi is a constant or a Confirm */
env
->
cmp
=
cmp
;
env
->
cmp
=
cmp
;
env
->
relation
=
relation
;
env
->
relation
=
relation
;
env
->
cnst
=
right
;
env
->
cnst
=
right
;
return
find_const_or_confirm
(
env
,
jump
,
left
);
return
find_const_or_confirm
(
env
,
jump
,
left
);
}
}
...
@@ -580,34 +527,24 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
...
@@ -580,34 +527,24 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
*/
*/
static
void
thread_jumps
(
ir_node
*
block
,
void
*
data
)