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
b96bebec
Commit
b96bebec
authored
May 14, 2009
by
Michael Beck
Browse files
- removed unused header attribute from node_entry
- improved move_loads_out_of_loops() by calculating the avail set [r25942]
parent
8e274ccd
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/opt/ldstopt.c
View file @
b96bebec
...
@@ -48,6 +48,7 @@
...
@@ -48,6 +48,7 @@
#include
"irmemory.h"
#include
"irmemory.h"
#include
"irphase_t.h"
#include
"irphase_t.h"
#include
"irgopt.h"
#include
"irgopt.h"
#include
"set.h"
#include
"debug.h"
#include
"debug.h"
/** The debug handle. */
/** The debug handle. */
...
@@ -1696,7 +1697,6 @@ typedef struct scc {
...
@@ -1696,7 +1697,6 @@ typedef struct scc {
typedef
struct
node_entry
{
typedef
struct
node_entry
{
unsigned
DFSnum
;
/**< the DFS number of this node */
unsigned
DFSnum
;
/**< the DFS number of this node */
unsigned
low
;
/**< the low number of this node */
unsigned
low
;
/**< the low number of this node */
ir_node
*
header
;
/**< the header of this node */
int
in_stack
;
/**< flag, set if the node is on the stack */
int
in_stack
;
/**< flag, set if the node is on the stack */
ir_node
*
next
;
/**< link to the next node the the same scc */
ir_node
*
next
;
/**< link to the next node the the same scc */
scc
*
pscc
;
/**< the scc of this node */
scc
*
pscc
;
/**< the scc of this node */
...
@@ -1783,6 +1783,32 @@ struct phi_entry {
...
@@ -1783,6 +1783,32 @@ struct phi_entry {
phi_entry
*
next
;
phi_entry
*
next
;
};
};
/**
* An entry in the avail set.
*/
typedef
struct
avail_entry_t
{
ir_node
*
ptr
;
/**< the address pointer */
ir_mode
*
mode
;
/**< the load mode */
ir_node
*
load
;
/**< the associated Load */
}
avail_entry_t
;
/**
* Compare two avail entries.
*/
static
int
cmp_avail_entry
(
const
void
*
elt
,
const
void
*
key
,
size_t
size
)
{
const
avail_entry_t
*
a
=
elt
;
const
avail_entry_t
*
b
=
key
;
return
a
->
ptr
!=
b
->
ptr
||
a
->
mode
!=
b
->
mode
;
}
/* cmp_avail_entry */
/**
* Calculate the hash value of an avail entry.
*/
static
unsigned
hash_cache_entry
(
const
avail_entry_t
*
entry
)
{
return
get_irn_idx
(
entry
->
ptr
)
*
9
+
HASH_PTR
(
entry
->
mode
);
}
/* hash_cache_entry */
/**
/**
* Move loops out of loops if possible.
* Move loops out of loops if possible.
*
*
...
@@ -1794,6 +1820,9 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
...
@@ -1794,6 +1820,9 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
ir_entity
*
ent
;
ir_entity
*
ent
;
int
j
;
int
j
;
phi_entry
*
phi_list
=
NULL
;
phi_entry
*
phi_list
=
NULL
;
set
*
avail
;
avail
=
new_set
(
cmp_avail_entry
,
8
);
/* collect all outer memories */
/* collect all outer memories */
for
(
phi
=
pscc
->
head
;
phi
!=
NULL
;
phi
=
next
)
{
for
(
phi
=
pscc
->
head
;
phi
!=
NULL
;
phi
=
next
)
{
...
@@ -1804,7 +1833,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
...
@@ -1804,7 +1833,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
if
(
!
is_Phi
(
phi
))
if
(
!
is_Phi
(
phi
))
continue
;
continue
;
assert
(
get_irn_mode
(
phi
)
==
mode_M
&&
"DFS
g
eturn non-memory Phi"
);
assert
(
get_irn_mode
(
phi
)
==
mode_M
&&
"DFS
r
eturn non-memory Phi"
);
for
(
j
=
get_irn_arity
(
phi
)
-
1
;
j
>=
0
;
--
j
)
{
for
(
j
=
get_irn_arity
(
phi
)
-
1
;
j
>=
0
;
--
j
)
{
ir_node
*
pred
=
get_irn_n
(
phi
,
j
);
ir_node
*
pred
=
get_irn_n
(
phi
,
j
);
...
@@ -1824,6 +1853,10 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
...
@@ -1824,6 +1853,10 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
/* no Phis no fun */
/* no Phis no fun */
assert
(
phi_list
!=
NULL
&&
"DFS found a loop without Phi"
);
assert
(
phi_list
!=
NULL
&&
"DFS found a loop without Phi"
);
/* for now, we cannot handle more than one input (only reducible cf) */
if
(
phi_list
->
next
!=
NULL
)
return
;
for
(
load
=
pscc
->
head
;
load
;
load
=
next
)
{
for
(
load
=
pscc
->
head
;
load
;
load
=
next
)
{
ir_mode
*
load_mode
;
ir_mode
*
load_mode
;
node_entry
*
ne
=
get_irn_ne
(
load
,
env
);
node_entry
*
ne
=
get_irn_ne
(
load
,
env
);
...
@@ -1837,10 +1870,10 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
...
@@ -1837,10 +1870,10 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
if
(
info
->
projs
[
pn_Load_res
]
==
NULL
||
info
->
projs
[
pn_Load_X_regular
]
!=
NULL
||
info
->
projs
[
pn_Load_X_except
]
!=
NULL
)
if
(
info
->
projs
[
pn_Load_res
]
==
NULL
||
info
->
projs
[
pn_Load_X_regular
]
!=
NULL
||
info
->
projs
[
pn_Load_X_except
]
!=
NULL
)
continue
;
continue
;
/* for now, we can only
handl
e Load(Global) */
/* for now, we can only
mov
e Load(Global) */
if
(
!
is_Global
(
ptr
))
if
(
!
is_Global
(
ptr
))
continue
;
continue
;
ent
=
get_Global_entity
(
ptr
);
ent
=
get_Global_entity
(
ptr
);
load_mode
=
get_Load_mode
(
load
);
load_mode
=
get_Load_mode
(
load
);
for
(
other
=
pscc
->
head
;
other
!=
NULL
;
other
=
next_other
)
{
for
(
other
=
pscc
->
head
;
other
!=
NULL
;
other
=
next_other
)
{
node_entry
*
ne
=
get_irn_ne
(
other
,
env
);
node_entry
*
ne
=
get_irn_ne
(
other
,
env
);
...
@@ -1856,17 +1889,13 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
...
@@ -1856,17 +1889,13 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
if
(
rel
!=
ir_no_alias
)
if
(
rel
!=
ir_no_alias
)
break
;
break
;
}
}
/* only pure Calls are allowed here, so ignore them */
/* only
Phis and
pure Calls are allowed here, so ignore them */
}
}
if
(
other
==
NULL
)
{
if
(
other
==
NULL
)
{
ldst_info_t
*
ninfo
;
ldst_info_t
*
ninfo
;
phi_entry
*
pe
;
phi_entry
*
pe
;
dbg_info
*
db
;
dbg_info
*
db
;
/* for now, we cannot handle more than one input */
if
(
phi_list
->
next
!=
NULL
)
return
;
/* yep, no aliasing Store found, Load can be moved */
/* yep, no aliasing Store found, Load can be moved */
DB
((
dbg
,
LEVEL_1
,
" Found a Load that could be moved: %+F
\n
"
,
load
));
DB
((
dbg
,
LEVEL_1
,
" Found a Load that could be moved: %+F
\n
"
,
load
));
...
@@ -1877,16 +1906,26 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
...
@@ -1877,16 +1906,26 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
ir_node
*
blk
=
get_nodes_block
(
phi
);
ir_node
*
blk
=
get_nodes_block
(
phi
);
ir_node
*
pred
=
get_Block_cfgpred_block
(
blk
,
pos
);
ir_node
*
pred
=
get_Block_cfgpred_block
(
blk
,
pos
);
ir_node
*
irn
,
*
mem
;
ir_node
*
irn
,
*
mem
;
avail_entry_t
entry
,
*
res
;
pe
->
load
=
irn
=
new_rd_Load
(
db
,
current_ir_graph
,
pred
,
get_Phi_pred
(
phi
,
pos
),
ptr
,
load_mode
,
0
);
entry
.
ptr
=
ptr
;
entry
.
mode
=
load_mode
;
res
=
set_find
(
avail
,
&
entry
,
sizeof
(
entry
),
hash_cache_entry
(
&
entry
));
if
(
res
!=
NULL
)
{
irn
=
res
->
load
;
}
else
{
irn
=
new_rd_Load
(
db
,
current_ir_graph
,
pred
,
get_Phi_pred
(
phi
,
pos
),
ptr
,
load_mode
,
0
);
entry
.
load
=
irn
;
set_insert
(
avail
,
&
entry
,
sizeof
(
entry
),
hash_cache_entry
(
&
entry
));
DB
((
dbg
,
LEVEL_1
,
" Created %+F in %+F
\n
"
,
irn
,
pred
));
}
pe
->
load
=
irn
;
ninfo
=
get_ldst_info
(
irn
,
phase_obst
(
&
env
->
ph
));
ninfo
=
get_ldst_info
(
irn
,
phase_obst
(
&
env
->
ph
));
ninfo
->
projs
[
pn_Load_M
]
=
mem
=
new_r_Proj
(
current_ir_graph
,
pred
,
irn
,
mode_M
,
pn_Load_M
);
ninfo
->
projs
[
pn_Load_M
]
=
mem
=
new_r_Proj
(
current_ir_graph
,
pred
,
irn
,
mode_M
,
pn_Load_M
);
set_Phi_pred
(
phi
,
pos
,
mem
);
set_Phi_pred
(
phi
,
pos
,
mem
);
ninfo
->
projs
[
pn_Load_res
]
=
new_r_Proj
(
current_ir_graph
,
pred
,
irn
,
load_mode
,
pn_Load_res
);
ninfo
->
projs
[
pn_Load_res
]
=
new_r_Proj
(
current_ir_graph
,
pred
,
irn
,
load_mode
,
pn_Load_res
);
DB
((
dbg
,
LEVEL_1
,
" Created %+F in %+F
\n
"
,
irn
,
pred
));
}
}
/* now kill the old Load */
/* now kill the old Load */
...
@@ -1897,6 +1936,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
...
@@ -1897,6 +1936,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) {
}
}
}
}
}
}
del_set
(
avail
);
}
/* move_loads_out_of_loops */
}
/* move_loads_out_of_loops */
/**
/**
...
@@ -1919,13 +1959,12 @@ static void process_loop(scc *pscc, loop_env *env) {
...
@@ -1919,13 +1959,12 @@ static void process_loop(scc *pscc, loop_env *env) {
next
=
e
->
next
;
next
=
e
->
next
;
b
=
get_irn_ne
(
block
,
env
);
b
=
get_irn_ne
(
block
,
env
);
if
(
header
)
{
if
(
header
!=
NULL
)
{
if
(
h
->
POnum
<
b
->
POnum
)
{
if
(
h
->
POnum
<
b
->
POnum
)
{
header
=
block
;
header
=
block
;
h
=
b
;
h
=
b
;
}
}
}
}
else
{
else
{
header
=
block
;
header
=
block
;
h
=
b
;
h
=
b
;
}
}
...
@@ -1980,10 +2019,12 @@ static void process_loop(scc *pscc, loop_env *env) {
...
@@ -1980,10 +2019,12 @@ static void process_loop(scc *pscc, loop_env *env) {
/* not a memory loop */
/* not a memory loop */
goto
fail
;
goto
fail
;
}
}
if
(
!
out_rc
)
{
if
(
out_rc
==
NULL
)
{
/* first region constant */
out_rc
=
pred
;
out_rc
=
pred
;
++
num_outside
;
++
num_outside
;
}
else
if
(
out_rc
!=
pred
)
{
}
else
if
(
out_rc
!=
pred
)
{
/* another region constant */
++
num_outside
;
++
num_outside
;
}
}
}
}
...
@@ -2003,22 +2044,20 @@ static void process_loop(scc *pscc, loop_env *env) {
...
@@ -2003,22 +2044,20 @@ static void process_loop(scc *pscc, loop_env *env) {
for
(
irn
=
pscc
->
head
;
irn
;
irn
=
next
)
{
for
(
irn
=
pscc
->
head
;
irn
;
irn
=
next
)
{
node_entry
*
e
=
get_irn_ne
(
irn
,
env
);
node_entry
*
e
=
get_irn_ne
(
irn
,
env
);
next
=
e
->
next
;
next
=
e
->
next
;
e
->
header
=
NULL
;
exchange
(
irn
,
out_rc
);
exchange
(
irn
,
out_rc
);
}
}
env
->
changes
|=
DF_CHANGED
;
env
->
changes
|=
DF_CHANGED
;
return
;
return
;
}
}
/* set the header for every node in this scc */
#ifdef DEBUG_libfirm
for
(
irn
=
pscc
->
head
;
irn
;
irn
=
next
)
{
for
(
irn
=
pscc
->
head
;
irn
;
irn
=
next
)
{
node_entry
*
e
=
get_irn_ne
(
irn
,
env
);
node_entry
*
e
=
get_irn_ne
(
irn
,
env
);
e
->
header
=
header
;
next
=
e
->
next
;
next
=
e
->
next
;
DB
((
dbg
,
LEVEL_2
,
" %+F,"
,
irn
));
DB
((
dbg
,
LEVEL_2
,
" %+F,"
,
irn
));
}
}
DB
((
dbg
,
LEVEL_2
,
"
\n
"
));
DB
((
dbg
,
LEVEL_2
,
"
\n
"
));
#endif
move_loads_out_of_loops
(
pscc
,
env
);
move_loads_out_of_loops
(
pscc
,
env
);
fail:
fail:
...
...
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