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
e2ff51a6
Commit
e2ff51a6
authored
Jul 28, 2014
by
Matthias Braun
Browse files
cfopt: cleanups
parent
f9e0ba48
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/opt/cfopt.c
View file @
e2ff51a6
...
@@ -58,7 +58,7 @@ static bool is_Block_removable(const ir_node *block)
...
@@ -58,7 +58,7 @@ static bool is_Block_removable(const ir_node *block)
/** Walker: clear link fields and mark all blocks as removable. */
/** Walker: clear link fields and mark all blocks as removable. */
static
void
clear_link_and_mark_blocks_removable
(
ir_node
*
node
,
void
*
ctx
)
static
void
clear_link_and_mark_blocks_removable
(
ir_node
*
node
,
void
*
ctx
)
{
{
(
void
)
ctx
;
(
void
)
ctx
;
set_irn_link
(
node
,
NULL
);
set_irn_link
(
node
,
NULL
);
if
(
is_Block
(
node
))
{
if
(
is_Block
(
node
))
{
set_Block_removable
(
node
,
true
);
set_Block_removable
(
node
,
true
);
...
@@ -77,7 +77,7 @@ static void clear_link_and_mark_blocks_removable(ir_node *node, void *ctx)
...
@@ -77,7 +77,7 @@ static void clear_link_and_mark_blocks_removable(ir_node *node, void *ctx)
*/
*/
static
void
collect_nodes
(
ir_node
*
n
,
void
*
ctx
)
static
void
collect_nodes
(
ir_node
*
n
,
void
*
ctx
)
{
{
(
void
)
ctx
;
(
void
)
ctx
;
if
(
is_Phi
(
n
))
{
if
(
is_Phi
(
n
))
{
/* Collect Phi nodes to compact ins along with block's ins. */
/* Collect Phi nodes to compact ins along with block's ins. */
ir_node
*
block
=
get_nodes_block
(
n
);
ir_node
*
block
=
get_nodes_block
(
n
);
...
@@ -108,9 +108,7 @@ static void collect_nodes(ir_node *n, void *ctx)
...
@@ -108,9 +108,7 @@ static void collect_nodes(ir_node *n, void *ctx)
/** Returns true if pred is predecessor of block b. */
/** Returns true if pred is predecessor of block b. */
static
bool
is_pred_of
(
const
ir_node
*
pred
,
const
ir_node
*
b
)
static
bool
is_pred_of
(
const
ir_node
*
pred
,
const
ir_node
*
b
)
{
{
int
i
;
for
(
int
i
=
get_Block_n_cfgpreds
(
b
);
i
--
>
0
;
)
{
for
(
i
=
get_Block_n_cfgpreds
(
b
)
-
1
;
i
>=
0
;
--
i
)
{
ir_node
*
b_pred
=
get_Block_cfgpred_block
(
b
,
i
);
ir_node
*
b_pred
=
get_Block_cfgpred_block
(
b
,
i
);
if
(
b_pred
==
pred
)
if
(
b_pred
==
pred
)
return
true
;
return
true
;
...
@@ -207,16 +205,16 @@ non_dispensable:
...
@@ -207,16 +205,16 @@ non_dispensable:
*/
*/
static
void
merge_blocks
(
ir_node
*
b
,
void
*
env
)
static
void
merge_blocks
(
ir_node
*
b
,
void
*
env
)
{
{
(
void
)
env
;
(
void
)
env
;
if
(
get_Block_n_cfgpreds
(
b
)
=
=
1
)
{
if
(
get_Block_n_cfgpreds
(
b
)
!
=
1
)
ir_node
*
pred
=
get_Block_cfgpred
(
b
,
0
)
;
return
;
i
f
(
is_Jmp
(
pred
))
{
i
r_node
*
pred
=
get_Block_cfgpred
(
b
,
0
);
ir_node
*
pred_block
=
get_nodes_block
(
pred
)
;
if
(
!
is_Jmp
(
pred
)
)
if
(
get_Block_phis
(
b
)
==
NULL
)
{
return
;
exchange
(
b
,
pred_block
);
ir_node
*
pred_block
=
get_nodes_block
(
pred
);
}
if
(
get_Block_phis
(
b
)
==
NULL
)
{
}
exchange
(
b
,
pred_block
);
}
}
}
}
...
@@ -352,9 +350,9 @@ static void optimize_blocks(ir_node *b, void *ctx)
...
@@ -352,9 +350,9 @@ static void optimize_blocks(ir_node *b, void *ctx)
/* we found a predecessor block at position k that will be removed */
/* we found a predecessor block at position k that will be removed */
for
(
ir_node
*
phi
=
get_Block_phis
(
predb
),
*
next_phi
;
phi
!=
NULL
;
for
(
ir_node
*
phi
=
get_Block_phis
(
predb
),
*
next_phi
;
phi
!=
NULL
;
phi
=
next_phi
)
{
phi
=
next_phi
)
{
int
q_preds
=
0
;
next_phi
=
get_Phi_next
(
phi
);
next_phi
=
get_Phi_next
(
phi
);
int
q_preds
=
0
;
if
(
get_Block_idom
(
b
)
!=
predb
)
{
if
(
get_Block_idom
(
b
)
!=
predb
)
{
/* predb is not the dominator. There can't be uses of
/* predb is not the dominator. There can't be uses of
* pred's Phi nodes, kill them .*/
* pred's Phi nodes, kill them .*/
...
@@ -485,8 +483,8 @@ static void optimize_blocks(ir_node *b, void *ctx)
...
@@ -485,8 +483,8 @@ static void optimize_blocks(ir_node *b, void *ctx)
}
}
/**
/**
* Optimize boolean Conds, where true and false jump to the same block into a
Jmp
* Optimize boolean Conds, where true and false jump to the same block into a
* Block must contain no Phi nodes.
*
Jmp.
Block must contain no Phi nodes.
*
*
* Cond
* Cond
* / \
* / \
...
@@ -527,9 +525,9 @@ typedef enum block_flags_t {
...
@@ -527,9 +525,9 @@ typedef enum block_flags_t {
}
block_flags_t
;
}
block_flags_t
;
static
bool
get_block_flag
(
const
ir_nodehashmap_t
*
infos
,
const
ir_node
*
block
,
static
bool
get_block_flag
(
const
ir_nodehashmap_t
*
infos
,
const
ir_node
*
block
,
in
t
flag
)
block_flags_
t
flag
)
{
{
return
PTR_TO_INT
(
ir_nodehashmap_get
(
void
,
infos
,
block
))
&
flag
;
return
PTR_TO_INT
(
ir_nodehashmap_get
(
void
,
infos
,
block
))
&
(
int
)
flag
;
}
}
static
void
set_block_flag
(
ir_nodehashmap_t
*
infos
,
ir_node
*
block
,
static
void
set_block_flag
(
ir_nodehashmap_t
*
infos
,
ir_node
*
block
,
...
@@ -576,7 +574,7 @@ static void set_is_unknown_jump_target(ir_nodehashmap_t *infos, ir_node *block)
...
@@ -576,7 +574,7 @@ static void set_is_unknown_jump_target(ir_nodehashmap_t *infos, ir_node *block)
}
}
/**
/**
*
Pre-Walker: f
ill block info information.
*
F
ill block info information.
*/
*/
static
void
compute_block_info
(
ir_node
*
n
,
void
*
x
)
static
void
compute_block_info
(
ir_node
*
n
,
void
*
x
)
{
{
...
@@ -590,10 +588,16 @@ static void compute_block_info(ir_node *n, void *x)
...
@@ -590,10 +588,16 @@ static void compute_block_info(ir_node *n, void *x)
set_is_unknown_jump_target
(
infos
,
n
);
set_is_unknown_jump_target
(
infos
,
n
);
}
}
}
}
}
else
if
(
is_Phi
(
n
))
{
return
;
}
if
(
is_Phi
(
n
))
{
ir_node
*
block
=
get_nodes_block
(
n
);
ir_node
*
block
=
get_nodes_block
(
n
);
set_has_phis
(
infos
,
block
);
set_has_phis
(
infos
,
block
);
}
else
if
(
is_Jmp
(
n
)
||
is_Cond
(
n
)
||
is_Proj
(
n
))
{
return
;
}
n
=
skip_Proj
(
n
);
if
(
is_cfop
(
n
))
{
/* ignore */
/* ignore */
}
else
{
}
else
{
ir_node
*
block
=
get_nodes_block
(
n
);
ir_node
*
block
=
get_nodes_block
(
n
);
...
@@ -672,8 +676,8 @@ static void remove_empty_blocks(ir_node *block, void *x)
...
@@ -672,8 +676,8 @@ static void remove_empty_blocks(ir_node *block, void *x)
* if block has no Phis.
* if block has no Phis.
*/
*/
if
(
n_jpreds
==
1
)
{
if
(
n_jpreds
==
1
)
{
ir_node
*
pred
=
get_Block_cfgpred
(
jmp_block
,
0
);
ir_node
*
pred
=
get_Block_cfgpred
(
jmp_block
,
0
);
ir_node
*
pred_block
=
get_nodes_block
(
pred
);
ir_node
*
pred_block
=
get_nodes_block
(
pred
);
if
(
has_operations
(
&
env
->
block_infos
,
jmp_block
))
{
if
(
has_operations
(
&
env
->
block_infos
,
jmp_block
))
{
if
(
!
is_Jmp
(
pred
))
if
(
!
is_Jmp
(
pred
))
continue
;
/* must not create partially dead code, especially when it is mode_M */
continue
;
/* must not create partially dead code, especially when it is mode_M */
...
@@ -737,14 +741,13 @@ static void remove_empty_blocks(ir_node *block, void *x)
...
@@ -737,14 +741,13 @@ static void remove_empty_blocks(ir_node *block, void *x)
static
void
cfgopt_ignoring_phis
(
ir_graph
*
irg
)
static
void
cfgopt_ignoring_phis
(
ir_graph
*
irg
)
{
{
skip_env
env
;
skip_env
env
;
env
.
changed
=
true
;
ir_nodehashmap_init
(
&
env
.
block_infos
);
ir_nodehashmap_init
(
&
env
.
block_infos
);
while
(
env
.
changed
)
{
do
{
irg_walk_graph
(
irg
,
compute_block_info
,
NULL
,
&
env
.
block_infos
);
irg_walk_graph
(
irg
,
compute_block_info
,
NULL
,
&
env
.
block_infos
);
env
.
changed
=
false
;
/* Remove blocks, which only consist of a Jmp */
/* Remove blocks, which only consist of a Jmp */
env
.
changed
=
false
;
irg_block_walk_graph
(
irg
,
remove_empty_blocks
,
NULL
,
&
env
);
irg_block_walk_graph
(
irg
,
remove_empty_blocks
,
NULL
,
&
env
);
/* Optimize Cond->Jmp, where then- and else-block are the same. */
/* Optimize Cond->Jmp, where then- and else-block are the same. */
...
@@ -760,7 +763,7 @@ static void cfgopt_ignoring_phis(ir_graph *irg)
...
@@ -760,7 +763,7 @@ static void cfgopt_ignoring_phis(ir_graph *irg)
confirm_irg_properties
(
irg
,
IR_GRAPH_PROPERTIES_ALL
);
confirm_irg_properties
(
irg
,
IR_GRAPH_PROPERTIES_ALL
);
break
;
break
;
}
}
}
}
while
(
env
.
changed
);
ir_nodehashmap_destroy
(
&
env
.
block_infos
);
ir_nodehashmap_destroy
(
&
env
.
block_infos
);
}
}
...
@@ -784,24 +787,20 @@ void optimize_cf(ir_graph *irg)
...
@@ -784,24 +787,20 @@ void optimize_cf(ir_graph *irg)
ir_reserve_resources
(
irg
,
IR_RESOURCE_BLOCK_MARK
|
IR_RESOURCE_IRN_LINK
ir_reserve_resources
(
irg
,
IR_RESOURCE_BLOCK_MARK
|
IR_RESOURCE_IRN_LINK
|
IR_RESOURCE_PHI_LIST
);
|
IR_RESOURCE_PHI_LIST
);
/*
/* This pass collects all Phi nodes in a link list in the block
* This pass collects all Phi nodes in a link list in the block
* nodes. Further it performs simple control flow optimizations.
* nodes. Further it performs simple control flow optimizations.
* Finally it marks all blocks that do not contain useful computations,
* Finally it marks all blocks that do not contain useful
* i.e., these blocks might be removed. */
* computations, i.e., these blocks might be removed.
*/
ir_node
*
end
=
get_irg_end
(
irg
);
ir_node
*
end
=
get_irg_end
(
irg
);
irg_walk
(
end
,
clear_link_and_mark_blocks_removable
,
collect_nodes
,
NULL
);
irg_walk
(
end
,
clear_link_and_mark_blocks_removable
,
collect_nodes
,
NULL
);
/* assert due to collect_nodes:
/* assert due to collect_nodes:
* 1. removable blocks are now marked as such
* 1. removable blocks are now marked as such
* 2. phi lists are up to date
* 2. phi lists are up to date */
*/
/* Optimize the standard code.
/* Optimize the standard code.
* It walks only over block nodes and adapts these and the Phi nodes in
* It walks only over block nodes and adapts these and the Phi nodes in
* these blocks, which it finds in a linked list computed before.
* these blocks, which it finds in a linked list computed before. */
*/
assure_irg_properties
(
irg
,
IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE
);
assure_irg_properties
(
irg
,
IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE
);
irg_block_walk_graph
(
irg
,
optimize_blocks
,
merge_blocks
,
&
env
);
irg_block_walk_graph
(
irg
,
optimize_blocks
,
merge_blocks
,
&
env
);
...
@@ -818,9 +817,8 @@ void optimize_cf(ir_graph *irg)
...
@@ -818,9 +817,8 @@ void optimize_cf(ir_graph *irg)
if
(
env
.
phis_moved
)
{
if
(
env
.
phis_moved
)
{
/* Bad: when we moved Phi's, we might produce dead Phi nodes
/* Bad: when we moved Phi's, we might produce dead Phi nodes
that are kept-alive.
* that are kept-alive.
Some other phases cannot copy with this, so kill them.
* Some other phases cannot copy with this, so kill them. */
*/
int
n
=
get_End_n_keepalives
(
end
);
int
n
=
get_End_n_keepalives
(
end
);
if
(
n
>
0
)
{
if
(
n
>
0
)
{
ir_node
**
in
=
ALLOCAN
(
ir_node
*
,
n
);
ir_node
**
in
=
ALLOCAN
(
ir_node
*
,
n
);
...
...
Write
Preview
Markdown
is supported
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