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
e9af0bc9
Commit
e9af0bc9
authored
Sep 11, 2006
by
Matthias Braun
Browse files
first version of condeval optimisation
[r8215]
parent
a73cb395
Changes
1
Show whitespace changes
Inline
Side-by-side
ir/opt/condeval.c
View file @
e9af0bc9
...
@@ -11,7 +11,9 @@
...
@@ -11,7 +11,9 @@
#include
"irgopt.h"
#include
"irgopt.h"
#include
"irgwalk.h"
#include
"irgwalk.h"
#include
"irnode.h"
#include
"irnode.h"
#include
"irnode_t.h"
#include
"iredges.h"
#include
"iredges.h"
#include
"irtools.h"
#include
"tv.h"
#include
"tv.h"
DEBUG_ONLY
(
static
firm_dbg_module_t
*
dbg
);
DEBUG_ONLY
(
static
firm_dbg_module_t
*
dbg
);
...
@@ -50,8 +52,13 @@ static int remove_pred(ir_node* node, int j)
...
@@ -50,8 +52,13 @@ static int remove_pred(ir_node* node, int j)
if
(
n
==
2
)
{
if
(
n
==
2
)
{
ir_node
*
pred
=
get_irn_n
(
node
,
1
-
j
);
ir_node
*
pred
=
get_irn_n
(
node
,
1
-
j
);
if
(
is_Block
(
node
))
pred
=
get_nodes_block
(
pred
);
if
(
is_Block
(
node
))
{
pred
=
get_nodes_block
(
pred
);
set_irn_in
(
node
,
get_irn_arity
(
pred
),
get_irn_in
(
pred
)
+
1
);
exchange
(
pred
,
node
);
}
else
{
exchange
(
node
,
pred
);
exchange
(
node
,
pred
);
}
return
1
;
return
1
;
}
else
{
}
else
{
ir_node
**
ins
;
ir_node
**
ins
;
...
@@ -120,7 +127,7 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode)
...
@@ -120,7 +127,7 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode)
* Given a set of values this function constructs SSA-form for all users of the
* Given a set of values this function constructs SSA-form for all users of the
* values (the user are determined through the out-edges of the values).
* values (the user are determined through the out-edges of the values).
*/
*/
static
void
construct_ssa
(
ir_node
*
const
*
vals
,
int
n_vals
)
static
void
construct_ssa
(
ir_node
*
const
*
blocks
,
ir_node
*
const
*
vals
,
int
n_vals
)
{
{
int
i
;
int
i
;
ir_graph
*
irg
;
ir_graph
*
irg
;
...
@@ -134,7 +141,7 @@ static void construct_ssa(ir_node * const *vals, int n_vals)
...
@@ -134,7 +141,7 @@ static void construct_ssa(ir_node * const *vals, int n_vals)
mode
=
get_irn_mode
(
vals
[
0
]);
mode
=
get_irn_mode
(
vals
[
0
]);
for
(
i
=
0
;
i
<
n_vals
;
++
i
)
{
for
(
i
=
0
;
i
<
n_vals
;
++
i
)
{
ir_node
*
value
=
vals
[
i
];
ir_node
*
value
=
vals
[
i
];
ir_node
*
value_block
=
get_nodes_block
(
value
)
;
ir_node
*
value_block
=
blocks
[
i
]
;
assert
(
get_irn_mode
(
value
)
==
mode
);
assert
(
get_irn_mode
(
value
)
==
mode
);
...
@@ -143,16 +150,34 @@ static void construct_ssa(ir_node * const *vals, int n_vals)
...
@@ -143,16 +150,34 @@ static void construct_ssa(ir_node * const *vals, int n_vals)
}
}
for
(
i
=
0
;
i
<
n_vals
;
++
i
)
{
for
(
i
=
0
;
i
<
n_vals
;
++
i
)
{
const
ir_edge_t
*
edge
;
const
ir_edge_t
*
edge
,
*
next
;
ir_node
*
value
=
vals
[
i
];
ir_node
*
value
=
vals
[
i
];
foreach_out_edge
(
value
,
edge
)
{
// this can happen when fixing phi preds, we mustn't fix the users
if
(
get_nodes_block
(
value
)
!=
blocks
[
i
])
{
continue
;
}
foreach_out_edge_safe
(
value
,
edge
,
next
)
{
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
*
user_block
=
get_nodes_block
(
user
);
ir_node
*
newval
;
ir_node
*
newval
;
// ignore keeps
if
(
get_irn_op
(
user
)
==
op_End
)
continue
;
if
(
is_Phi
(
user
))
{
ir_node
*
pred_block
=
get_Block_cfgpred_block
(
user_block
,
j
);
newval
=
search_def_and_create_phis
(
pred_block
,
mode
);
}
else
{
newval
=
search_def_and_create_phis
(
user_block
,
mode
);
newval
=
search_def_and_create_phis
(
user_block
,
mode
);
set_irn_n
(
user
,
get_edge_src_pos
(
edge
),
newval
);
}
// don't fix newly created phis from the SSA construction
if
(
newval
!=
user
)
set_irn_n
(
user
,
j
,
newval
);
}
}
}
}
}
}
...
@@ -173,8 +198,10 @@ static int handle_const_const(ir_node* cnst_left, cnst_right, pn_Cmp pnc)
...
@@ -173,8 +198,10 @@ static int handle_const_const(ir_node* cnst_left, cnst_right, pn_Cmp pnc)
/**
/**
*
*
*/
*/
static
void
handle_phi_const
(
ir_node
*
block
,
ir_node
*
cond_block
,
ir_node
*
phi
,
ir_node
*
cnst
,
pn_Cmp
pnc
)
static
int
handle_phi_const
(
ir_node
*
block
,
ir_node
*
cond_block
,
ir_node
*
phi
,
ir_node
*
cnst
,
pn_Cmp
pnc
)
{
{
int
changed
=
0
;
ir_graph
*
irg
;
tarval
*
tv_cnst
;
tarval
*
tv_cnst
;
int
n_phi
;
int
n_phi
;
int
j
;
int
j
;
...
@@ -182,13 +209,16 @@ static void handle_phi_const(ir_node* block, ir_node* cond_block, ir_node* phi,
...
@@ -182,13 +209,16 @@ static void handle_phi_const(ir_node* block, ir_node* cond_block, ir_node* phi,
tv_cnst
=
get_Const_tarval
(
cnst
);
tv_cnst
=
get_Const_tarval
(
cnst
);
n_phi
=
get_Phi_n_preds
(
phi
);
n_phi
=
get_Phi_n_preds
(
phi
);
for
(
j
=
0
;
j
<
n_phi
;
j
++
)
{
for
(
j
=
0
;
j
<
n_phi
;
j
++
)
{
ir_node
*
pred
;
const
ir_edge_t
*
edge
,
*
next
;
tarval
*
tv_phi
;
ir_node
*
pred
;
ir_node
*
pred_block
;
tarval
*
tv_phi
;
pn_Cmp
cmp_val
;
pn_Cmp
cmp_val
;
pred
=
get_Phi_pred
(
phi
,
j
);
pred
=
get_Phi_pred
(
phi
,
j
);
// TODO handle Phi cascades
// TODO handle Phi cascades
if
(
!
is_Const
(
pred
))
continue
;
if
(
!
is_Const
(
pred
))
continue
;
tv_phi
=
get_Const_tarval
(
pred
);
tv_phi
=
get_Const_tarval
(
pred
);
...
@@ -202,13 +232,85 @@ static void handle_phi_const(ir_node* block, ir_node* cond_block, ir_node* phi,
...
@@ -202,13 +232,85 @@ static void handle_phi_const(ir_node* block, ir_node* cond_block, ir_node* phi,
block
,
cond_block
,
j
block
,
cond_block
,
j
));
));
#if 0 // TODO repair data flow and dominance
add_pred
(
block
,
get_Block_cfgpred
(
cond_block
,
j
));
add_pred
(
block
,
get_Block_cfgpred
(
cond_block
,
j
));
// split critical edges
/*if(get_irn_arity(block) == 2)*/
{
ir_node
*
in
[
1
];
ir_node
*
new_block
;
ir_node
*
new_jmp
;
in
[
0
]
=
get_Block_cfgpred
(
block
,
0
);
new_block
=
new_r_Block
(
current_ir_graph
,
1
,
in
);
new_jmp
=
new_r_Jmp
(
current_ir_graph
,
new_block
);
set_Block_cfgpred
(
block
,
0
,
new_jmp
);
}
pred_block
=
get_Block_cfgpred_block
(
cond_block
,
j
);
/* Look at all nodes in the cond_block and copy them into pred */
foreach_out_edge
(
cond_block
,
edge
)
{
ir_node
*
node
=
get_edge_src_irn
(
edge
);
ir_node
*
copy
;
// ignore these as SSA construction would fail on ProjX
if
(
is_Proj
(
node
)
&&
get_irn_mode
(
node
)
==
mode_X
)
continue
;
// we can evaluate Phis right now, all other nodes get copied
if
(
is_Phi
(
node
))
{
copy
=
get_Phi_pred
(
node
,
j
);
}
else
{
copy
=
exact_copy
(
node
);
set_nodes_block
(
copy
,
pred_block
);
}
set_irn_link
(
node
,
copy
);
}
/* fix data-flow (and reconstruct SSA if needed) */
foreach_out_edge
(
cond_block
,
edge
)
{
ir_node
*
vals
[
2
];
ir_node
*
blocks
[
2
];
ir_node
*
node
=
get_edge_src_irn
(
edge
);
assert
(
get_nodes_block
(
node
)
==
cond_block
);
if
(
is_Proj
(
node
)
&&
get_irn_mode
(
node
)
==
mode_X
)
continue
;
blocks
[
0
]
=
cond_block
;
vals
[
0
]
=
node
;
blocks
[
1
]
=
pred_block
;
vals
[
1
]
=
get_irn_link
(
node
);
construct_ssa
(
blocks
,
vals
,
2
);
}
/* shorten phis */
foreach_out_edge_safe
(
cond_block
,
edge
,
next
)
{
ir_node
*
node
=
get_edge_src_irn
(
edge
);
if
(
is_Phi
(
node
))
remove_pred
(
node
,
j
);
}
remove_pred(phi, j);
changed
=
1
;
if (remove_pred(cond_block, j)) break;
remove_pred
(
cond_block
,
j
);
#if 0
if (remove_pred(cond_block, j))
break;
// the phi got shortened
n_phi--;
j--;
#endif
#endif
break
;
}
if
(
changed
)
{
irg
=
get_irn_irg
(
block
);
set_irg_doms_inconsistent
(
irg
);
set_irg_extblk_inconsistent
(
irg
);
set_irg_loopinfo_inconsistent
(
irg
);
}
}
return
changed
;
}
}
...
@@ -217,9 +319,10 @@ static void handle_phi_const(ir_node* block, ir_node* cond_block, ir_node* phi,
...
@@ -217,9 +319,10 @@ static void handle_phi_const(ir_node* block, ir_node* cond_block, ir_node* phi,
*/
*/
static
void
cond_eval
(
ir_node
*
block
,
void
*
env
)
static
void
cond_eval
(
ir_node
*
block
,
void
*
env
)
{
{
int
n_block
=
get_Block_n_cfgpreds
(
block
)
;
int
n_block
;
int
i
;
int
i
;
n_block
=
get_Block_n_cfgpreds
(
block
);
for
(
i
=
0
;
i
<
n_block
;
i
++
)
{
for
(
i
=
0
;
i
<
n_block
;
i
++
)
{
ir_node
*
pred
;
ir_node
*
pred
;
ir_node
*
projx
;
ir_node
*
projx
;
...
@@ -291,7 +394,17 @@ void opt_cond_eval(ir_graph* irg)
...
@@ -291,7 +394,17 @@ void opt_cond_eval(ir_graph* irg)
DB
((
dbg
,
LEVEL_1
,
"===> Performing condition evaluation on %+F
\n
"
,
irg
));
DB
((
dbg
,
LEVEL_1
,
"===> Performing condition evaluation on %+F
\n
"
,
irg
));
if
(
edges_activated
(
irg
))
edges_deactivate
(
irg
);
edges_assure
(
irg
);
remove_critical_cf_edges
(
irg
);
remove_critical_cf_edges
(
irg
);
normalize_proj_nodes
(
irg
);
irg_block_walk_graph
(
irg
,
cond_eval
,
NULL
,
NULL
);
#if 0
irg_block_walk_graph(irg, NULL, cond_eval, NULL);
irg_block_walk_graph(irg, NULL, cond_eval, NULL);
irg_block_walk_graph(irg, NULL, cond_eval, NULL);
irg_block_walk_graph(irg, NULL, cond_eval, NULL);
#endif
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment