Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
4891442b
Commit
4891442b
authored
Dec 22, 2001
by
Richard Kenner
Committed by
Richard Kenner
Dec 22, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* cfg.c, cfganal.c, cfgbuild.c: Reformatting and minor cleanups.
From-SVN: r48270
parent
bfdade77
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
192 additions
and
166 deletions
+192
-166
gcc/ChangeLog
+1
-0
gcc/cfg.c
+37
-19
gcc/cfganal.c
+97
-91
gcc/cfgbuild.c
+57
-56
No files found.
gcc/ChangeLog
View file @
4891442b
Sat
Dec
22
08
:
59
:
50
2001
Richard
Kenner
<
kenner
@vlsi1
.
ultra
.
nyu
.
edu
>
Sat
Dec
22
08
:
59
:
50
2001
Richard
Kenner
<
kenner
@vlsi1
.
ultra
.
nyu
.
edu
>
*
predict
.
c
:
Reformatting
and
minor
cleanups
.
*
predict
.
c
:
Reformatting
and
minor
cleanups
.
*
cfg
.
c
,
cfganal
.
c
,
cfgbuild
.
c
:
Likewise
.
*
expr
.
c
(
expand_expr
,
case
ADDR_EXPR
):
Handling
taking
address
of
*
expr
.
c
(
expand_expr
,
case
ADDR_EXPR
):
Handling
taking
address
of
SAVE_EXPR
.
SAVE_EXPR
.
...
...
gcc/cfg.c
View file @
4891442b
...
@@ -152,7 +152,7 @@ free_edge (e)
...
@@ -152,7 +152,7 @@ free_edge (e)
edge
e
;
edge
e
;
{
{
n_edges
--
;
n_edges
--
;
memset
(
e
,
0
,
sizeof
(
*
e
)
);
memset
(
e
,
0
,
sizeof
*
e
);
e
->
succ_next
=
first_deleted_edge
;
e
->
succ_next
=
first_deleted_edge
;
first_deleted_edge
=
e
;
first_deleted_edge
=
e
;
}
}
...
@@ -177,6 +177,7 @@ clear_edges ()
...
@@ -177,6 +177,7 @@ clear_edges ()
free_edge
(
e
);
free_edge
(
e
);
e
=
next
;
e
=
next
;
}
}
bb
->
succ
=
NULL
;
bb
->
succ
=
NULL
;
bb
->
pred
=
NULL
;
bb
->
pred
=
NULL
;
}
}
...
@@ -189,6 +190,7 @@ clear_edges ()
...
@@ -189,6 +190,7 @@ clear_edges ()
free_edge
(
e
);
free_edge
(
e
);
e
=
next
;
e
=
next
;
}
}
EXIT_BLOCK_PTR
->
pred
=
NULL
;
EXIT_BLOCK_PTR
->
pred
=
NULL
;
ENTRY_BLOCK_PTR
->
succ
=
NULL
;
ENTRY_BLOCK_PTR
->
succ
=
NULL
;
...
@@ -211,8 +213,8 @@ alloc_block ()
...
@@ -211,8 +213,8 @@ alloc_block ()
}
}
else
else
{
{
bb
=
(
basic_block
)
obstack_alloc
(
&
flow_obstack
,
sizeof
(
*
bb
)
);
bb
=
(
basic_block
)
obstack_alloc
(
&
flow_obstack
,
sizeof
*
bb
);
memset
(
bb
,
0
,
sizeof
(
*
bb
)
);
memset
(
bb
,
0
,
sizeof
*
bb
);
}
}
return
bb
;
return
bb
;
}
}
...
@@ -233,7 +235,7 @@ expunge_block (b)
...
@@ -233,7 +235,7 @@ expunge_block (b)
}
}
/* Invalidate data to make bughunting easier. */
/* Invalidate data to make bughunting easier. */
memset
(
b
,
0
,
sizeof
(
*
b
)
);
memset
(
b
,
0
,
sizeof
*
b
);
b
->
index
=
-
3
;
b
->
index
=
-
3
;
basic_block_info
->
num_elements
--
;
basic_block_info
->
num_elements
--
;
n_basic_blocks
--
;
n_basic_blocks
--
;
...
@@ -253,11 +255,10 @@ cached_make_edge (edge_cache, src, dst, flags)
...
@@ -253,11 +255,10 @@ cached_make_edge (edge_cache, src, dst, flags)
int
use_edge_cache
;
int
use_edge_cache
;
edge
e
;
edge
e
;
/* Don't bother with edge cache for ENTRY or EXIT
;
there aren't that
/* Don't bother with edge cache for ENTRY or EXIT
, if
there aren't that
many edges to them,
and
we didn't allocate memory for it. */
many edges to them,
or
we didn't allocate memory for it. */
use_edge_cache
=
(
edge_cache
use_edge_cache
=
(
edge_cache
&&
src
!=
ENTRY_BLOCK_PTR
&&
src
!=
ENTRY_BLOCK_PTR
&&
dst
!=
EXIT_BLOCK_PTR
);
&&
dst
!=
EXIT_BLOCK_PTR
);
/* Make sure we don't add duplicate edges. */
/* Make sure we don't add duplicate edges. */
switch
(
use_edge_cache
)
switch
(
use_edge_cache
)
...
@@ -289,8 +290,8 @@ cached_make_edge (edge_cache, src, dst, flags)
...
@@ -289,8 +290,8 @@ cached_make_edge (edge_cache, src, dst, flags)
}
}
else
else
{
{
e
=
(
edge
)
obstack_alloc
(
&
flow_obstack
,
sizeof
(
*
e
)
);
e
=
(
edge
)
obstack_alloc
(
&
flow_obstack
,
sizeof
*
e
);
memset
(
e
,
0
,
sizeof
(
*
e
)
);
memset
(
e
,
0
,
sizeof
*
e
);
}
}
n_edges
++
;
n_edges
++
;
...
@@ -345,6 +346,7 @@ remove_edge (e)
...
@@ -345,6 +346,7 @@ remove_edge (e)
edge
last_succ
=
NULL
;
edge
last_succ
=
NULL
;
edge
tmp
;
edge
tmp
;
basic_block
src
,
dest
;
basic_block
src
,
dest
;
src
=
e
->
src
;
src
=
e
->
src
;
dest
=
e
->
dest
;
dest
=
e
->
dest
;
for
(
tmp
=
src
->
succ
;
tmp
&&
tmp
!=
e
;
tmp
=
tmp
->
succ_next
)
for
(
tmp
=
src
->
succ
;
tmp
&&
tmp
!=
e
;
tmp
=
tmp
->
succ_next
)
...
@@ -398,10 +400,12 @@ redirect_edge_succ_nodup (e, new_succ)
...
@@ -398,10 +400,12 @@ redirect_edge_succ_nodup (e, new_succ)
basic_block
new_succ
;
basic_block
new_succ
;
{
{
edge
s
;
edge
s
;
/* Check whether the edge is already present. */
/* Check whether the edge is already present. */
for
(
s
=
e
->
src
->
succ
;
s
;
s
=
s
->
succ_next
)
for
(
s
=
e
->
src
->
succ
;
s
;
s
=
s
->
succ_next
)
if
(
s
->
dest
==
new_succ
&&
s
!=
e
)
if
(
s
->
dest
==
new_succ
&&
s
!=
e
)
break
;
break
;
if
(
s
)
if
(
s
)
{
{
s
->
flags
|=
e
->
flags
;
s
->
flags
|=
e
->
flags
;
...
@@ -412,6 +416,7 @@ redirect_edge_succ_nodup (e, new_succ)
...
@@ -412,6 +416,7 @@ redirect_edge_succ_nodup (e, new_succ)
}
}
else
else
redirect_edge_succ
(
e
,
new_succ
);
redirect_edge_succ
(
e
,
new_succ
);
return
e
;
return
e
;
}
}
...
@@ -427,6 +432,7 @@ redirect_edge_pred (e, new_pred)
...
@@ -427,6 +432,7 @@ redirect_edge_pred (e, new_pred)
/* Disconnect the edge from the old predecessor block. */
/* Disconnect the edge from the old predecessor block. */
for
(
pe
=
&
e
->
src
->
succ
;
*
pe
!=
e
;
pe
=
&
(
*
pe
)
->
succ_next
)
for
(
pe
=
&
e
->
src
->
succ
;
*
pe
!=
e
;
pe
=
&
(
*
pe
)
->
succ_next
)
continue
;
continue
;
*
pe
=
(
*
pe
)
->
succ_next
;
*
pe
=
(
*
pe
)
->
succ_next
;
/* Reconnect the edge to the new predecessor block. */
/* Reconnect the edge to the new predecessor block. */
...
@@ -447,6 +453,7 @@ dump_flow_info (file)
...
@@ -447,6 +453,7 @@ dump_flow_info (file)
if
(
REG_N_REFS
(
i
))
if
(
REG_N_REFS
(
i
))
{
{
enum
reg_class
class
,
altclass
;
enum
reg_class
class
,
altclass
;
fprintf
(
file
,
"
\n
Register %d used %d times across %d insns"
,
fprintf
(
file
,
"
\n
Register %d used %d times across %d insns"
,
i
,
REG_N_REFS
(
i
),
REG_LIVE_LENGTH
(
i
));
i
,
REG_N_REFS
(
i
),
REG_LIVE_LENGTH
(
i
));
if
(
REG_BASIC_BLOCK
(
i
)
>=
0
)
if
(
REG_BASIC_BLOCK
(
i
)
>=
0
)
...
@@ -464,6 +471,7 @@ dump_flow_info (file)
...
@@ -464,6 +471,7 @@ dump_flow_info (file)
fprintf
(
file
,
"; crosses %d calls"
,
REG_N_CALLS_CROSSED
(
i
));
fprintf
(
file
,
"; crosses %d calls"
,
REG_N_CALLS_CROSSED
(
i
));
if
(
PSEUDO_REGNO_BYTES
(
i
)
!=
UNITS_PER_WORD
)
if
(
PSEUDO_REGNO_BYTES
(
i
)
!=
UNITS_PER_WORD
)
fprintf
(
file
,
"; %d bytes"
,
PSEUDO_REGNO_BYTES
(
i
));
fprintf
(
file
,
"; %d bytes"
,
PSEUDO_REGNO_BYTES
(
i
));
class
=
reg_preferred_class
(
i
);
class
=
reg_preferred_class
(
i
);
altclass
=
reg_alternate_class
(
i
);
altclass
=
reg_alternate_class
(
i
);
if
(
class
!=
GENERAL_REGS
||
altclass
!=
ALL_REGS
)
if
(
class
!=
GENERAL_REGS
||
altclass
!=
ALL_REGS
)
...
@@ -477,6 +485,7 @@ dump_flow_info (file)
...
@@ -477,6 +485,7 @@ dump_flow_info (file)
reg_class_names
[(
int
)
class
],
reg_class_names
[(
int
)
class
],
reg_class_names
[(
int
)
altclass
]);
reg_class_names
[(
int
)
altclass
]);
}
}
if
(
REG_POINTER
(
regno_reg_rtx
[
i
]))
if
(
REG_POINTER
(
regno_reg_rtx
[
i
]))
fprintf
(
file
,
"; pointer"
);
fprintf
(
file
,
"; pointer"
);
fprintf
(
file
,
".
\n
"
);
fprintf
(
file
,
".
\n
"
);
...
@@ -488,9 +497,10 @@ dump_flow_info (file)
...
@@ -488,9 +497,10 @@ dump_flow_info (file)
basic_block
bb
=
BASIC_BLOCK
(
i
);
basic_block
bb
=
BASIC_BLOCK
(
i
);
edge
e
;
edge
e
;
fprintf
(
file
,
"
\n
Basic block %d: first insn %d, last %d, loop_depth %d, count "
,
fprintf
(
file
,
"
\n
Basic block %d: first insn %d, last %d, "
,
i
,
INSN_UID
(
bb
->
head
),
INSN_UID
(
bb
->
end
),
bb
->
loop_depth
);
i
,
INSN_UID
(
bb
->
head
),
INSN_UID
(
bb
->
end
));
fprintf
(
file
,
HOST_WIDEST_INT_PRINT_DEC
,
(
HOST_WIDEST_INT
)
bb
->
count
);
fprintf
(
file
,
"loop_depth %d, count "
,
bb
->
loop_depth
);
fprintf
(
file
,
HOST_WIDEST_INT_PRINT_DEC
,
bb
->
count
);
fprintf
(
file
,
", freq %i.
\n
"
,
bb
->
frequency
);
fprintf
(
file
,
", freq %i.
\n
"
,
bb
->
frequency
);
fprintf
(
file
,
"Predecessors: "
);
fprintf
(
file
,
"Predecessors: "
);
...
@@ -540,19 +550,17 @@ dump_edge_info (file, e, do_succ)
...
@@ -540,19 +550,17 @@ dump_edge_info (file, e, do_succ)
if
(
e
->
count
)
if
(
e
->
count
)
{
{
fprintf
(
file
,
" count:"
);
fprintf
(
file
,
" count:"
);
fprintf
(
file
,
HOST_WIDEST_INT_PRINT_DEC
,
(
HOST_WIDEST_INT
)
e
->
count
);
fprintf
(
file
,
HOST_WIDEST_INT_PRINT_DEC
,
e
->
count
);
}
}
if
(
e
->
flags
)
if
(
e
->
flags
)
{
{
static
const
char
*
const
bitnames
[]
=
{
static
const
char
*
const
bitnames
[]
"fallthru"
,
"ab"
,
"abcall"
,
"eh"
,
"fake"
,
"dfs_back"
=
{
"fallthru"
,
"ab"
,
"abcall"
,
"eh"
,
"fake"
,
"dfs_back"
};
};
int
comma
=
0
;
int
comma
=
0
;
int
i
,
flags
=
e
->
flags
;
int
i
,
flags
=
e
->
flags
;
fputc
(
' '
,
file
);
fputs
(
" ("
,
file
);
fputc
(
'('
,
file
);
for
(
i
=
0
;
flags
;
i
++
)
for
(
i
=
0
;
flags
;
i
++
)
if
(
flags
&
(
1
<<
i
))
if
(
flags
&
(
1
<<
i
))
{
{
...
@@ -566,11 +574,13 @@ dump_edge_info (file, e, do_succ)
...
@@ -566,11 +574,13 @@ dump_edge_info (file, e, do_succ)
fprintf
(
file
,
"%d"
,
i
);
fprintf
(
file
,
"%d"
,
i
);
comma
=
1
;
comma
=
1
;
}
}
fputc
(
')'
,
file
);
fputc
(
')'
,
file
);
}
}
}
}
/* Simple routines to easily allocate AUX fields of basic blocks. */
/* Simple routines to easily allocate AUX fields of basic blocks. */
static
struct
obstack
block_aux_obstack
;
static
struct
obstack
block_aux_obstack
;
static
void
*
first_block_aux_obj
=
0
;
static
void
*
first_block_aux_obj
=
0
;
static
struct
obstack
edge_aux_obstack
;
static
struct
obstack
edge_aux_obstack
;
...
@@ -605,6 +615,7 @@ alloc_aux_for_blocks (size)
...
@@ -605,6 +615,7 @@ alloc_aux_for_blocks (size)
gcc_obstack_init
(
&
block_aux_obstack
);
gcc_obstack_init
(
&
block_aux_obstack
);
initialized
=
1
;
initialized
=
1
;
}
}
/* Check whether AUX data are still allocated. */
/* Check whether AUX data are still allocated. */
else
if
(
first_block_aux_obj
)
else
if
(
first_block_aux_obj
)
abort
();
abort
();
...
@@ -612,8 +623,10 @@ alloc_aux_for_blocks (size)
...
@@ -612,8 +623,10 @@ alloc_aux_for_blocks (size)
if
(
size
)
if
(
size
)
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
alloc_aux_for_block
(
BASIC_BLOCK
(
i
),
size
);
alloc_aux_for_block
(
BASIC_BLOCK
(
i
),
size
);
alloc_aux_for_block
(
ENTRY_BLOCK_PTR
,
size
);
alloc_aux_for_block
(
ENTRY_BLOCK_PTR
,
size
);
alloc_aux_for_block
(
EXIT_BLOCK_PTR
,
size
);
alloc_aux_for_block
(
EXIT_BLOCK_PTR
,
size
);
}
}
...
@@ -628,6 +641,7 @@ clear_aux_for_blocks ()
...
@@ -628,6 +641,7 @@ clear_aux_for_blocks ()
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
BASIC_BLOCK
(
i
)
->
aux
=
NULL
;
BASIC_BLOCK
(
i
)
->
aux
=
NULL
;
ENTRY_BLOCK_PTR
->
aux
=
NULL
;
ENTRY_BLOCK_PTR
->
aux
=
NULL
;
EXIT_BLOCK_PTR
->
aux
=
NULL
;
EXIT_BLOCK_PTR
->
aux
=
NULL
;
}
}
...
@@ -675,9 +689,11 @@ alloc_aux_for_edges (size)
...
@@ -675,9 +689,11 @@ alloc_aux_for_edges (size)
gcc_obstack_init
(
&
edge_aux_obstack
);
gcc_obstack_init
(
&
edge_aux_obstack
);
initialized
=
1
;
initialized
=
1
;
}
}
/* Check whether AUX data are still allocated. */
/* Check whether AUX data are still allocated. */
else
if
(
first_edge_aux_obj
)
else
if
(
first_edge_aux_obj
)
abort
();
abort
();
first_edge_aux_obj
=
(
char
*
)
obstack_alloc
(
&
edge_aux_obstack
,
0
);
first_edge_aux_obj
=
(
char
*
)
obstack_alloc
(
&
edge_aux_obstack
,
0
);
if
(
size
)
if
(
size
)
{
{
...
@@ -691,6 +707,7 @@ alloc_aux_for_edges (size)
...
@@ -691,6 +707,7 @@ alloc_aux_for_edges (size)
bb
=
BASIC_BLOCK
(
i
);
bb
=
BASIC_BLOCK
(
i
);
else
else
bb
=
ENTRY_BLOCK_PTR
;
bb
=
ENTRY_BLOCK_PTR
;
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
alloc_aux_for_edge
(
e
,
size
);
alloc_aux_for_edge
(
e
,
size
);
}
}
...
@@ -713,6 +730,7 @@ clear_aux_for_edges ()
...
@@ -713,6 +730,7 @@ clear_aux_for_edges ()
bb
=
BASIC_BLOCK
(
i
);
bb
=
BASIC_BLOCK
(
i
);
else
else
bb
=
ENTRY_BLOCK_PTR
;
bb
=
ENTRY_BLOCK_PTR
;
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
e
->
aux
=
NULL
;
e
->
aux
=
NULL
;
}
}
...
...
gcc/cfganal.c
View file @
4891442b
...
@@ -56,27 +56,28 @@ static bool need_fake_edge_p PARAMS ((rtx));
...
@@ -56,27 +56,28 @@ static bool need_fake_edge_p PARAMS ((rtx));
/* Return true if the block has no effect and only forwards control flow to
/* Return true if the block has no effect and only forwards control flow to
its single destination. */
its single destination. */
bool
bool
forwarder_block_p
(
bb
)
forwarder_block_p
(
bb
)
basic_block
bb
;
basic_block
bb
;
{
{
rtx
insn
=
bb
->
head
;
rtx
insn
;
if
(
bb
==
EXIT_BLOCK_PTR
||
bb
==
ENTRY_BLOCK_PTR
if
(
bb
==
EXIT_BLOCK_PTR
||
bb
==
ENTRY_BLOCK_PTR
||
!
bb
->
succ
||
bb
->
succ
->
succ_next
)
||
!
bb
->
succ
||
bb
->
succ
->
succ_next
)
return
false
;
return
false
;
while
(
insn
!=
bb
->
end
)
for
(
insn
=
bb
->
head
;
insn
!=
bb
->
end
;
insn
=
NEXT_INSN
(
insn
))
{
if
(
INSN_P
(
insn
)
&&
active_insn_p
(
insn
))
if
(
INSN_P
(
insn
)
&&
active_insn_p
(
insn
))
return
false
;
return
false
;
insn
=
NEXT_INSN
(
insn
);
}
return
(
!
INSN_P
(
insn
)
return
(
!
INSN_P
(
insn
)
||
(
GET_CODE
(
insn
)
==
JUMP_INSN
&&
simplejump_p
(
insn
))
||
(
GET_CODE
(
insn
)
==
JUMP_INSN
&&
simplejump_p
(
insn
))
||
!
active_insn_p
(
insn
));
||
!
active_insn_p
(
insn
));
}
}
/* Return nonzero if we can reach target from src by falling through. */
/* Return nonzero if we can reach target from src by falling through. */
bool
bool
can_fallthru
(
src
,
target
)
can_fallthru
(
src
,
target
)
basic_block
src
,
target
;
basic_block
src
,
target
;
...
@@ -86,6 +87,7 @@ can_fallthru (src, target)
...
@@ -86,6 +87,7 @@ can_fallthru (src, target)
if
(
src
->
index
+
1
==
target
->
index
&&
!
active_insn_p
(
insn2
))
if
(
src
->
index
+
1
==
target
->
index
&&
!
active_insn_p
(
insn2
))
insn2
=
next_active_insn
(
insn2
);
insn2
=
next_active_insn
(
insn2
);
/* ??? Later we may add code to move jump tables offline. */
/* ??? Later we may add code to move jump tables offline. */
return
next_active_insn
(
insn
)
==
insn2
;
return
next_active_insn
(
insn
)
==
insn2
;
}
}
...
@@ -148,7 +150,6 @@ mark_dfs_back_edges ()
...
@@ -148,7 +150,6 @@ mark_dfs_back_edges ()
SET_BIT
(
visited
,
dest
->
index
);
SET_BIT
(
visited
,
dest
->
index
);
pre
[
dest
->
index
]
=
prenum
++
;
pre
[
dest
->
index
]
=
prenum
++
;
if
(
dest
->
succ
)
if
(
dest
->
succ
)
{
{
/* Since the DEST node has been visited for the first
/* Since the DEST node has been visited for the first
...
@@ -235,17 +236,17 @@ flow_call_edges_add (blocks)
...
@@ -235,17 +236,17 @@ flow_call_edges_add (blocks)
{
{
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
bbs
[
bb_num
++
]
=
BASIC_BLOCK
(
i
);
bbs
[
bb_num
++
]
=
BASIC_BLOCK
(
i
);
check_last_block
=
true
;
check_last_block
=
true
;
}
}
else
else
{
EXECUTE_IF_SET_IN_SBITMAP
(
blocks
,
0
,
i
,
EXECUTE_IF_SET_IN_SBITMAP
(
blocks
,
0
,
i
,
{
{
bbs
[
bb_num
++
]
=
BASIC_BLOCK
(
i
);
bbs
[
bb_num
++
]
=
BASIC_BLOCK
(
i
);
if
(
i
==
n_basic_blocks
-
1
)
if
(
i
==
n_basic_blocks
-
1
)
check_last_block
=
true
;
check_last_block
=
true
;
});
});
}
/* In the last basic block, before epilogue generation, there will be
/* In the last basic block, before epilogue generation, there will be
a fallthru edge to EXIT. Special care is required if the last insn
a fallthru edge to EXIT. Special care is required if the last insn
...
@@ -263,14 +264,15 @@ flow_call_edges_add (blocks)
...
@@ -263,14 +264,15 @@ flow_call_edges_add (blocks)
&&
need_fake_edge_p
(
BASIC_BLOCK
(
n_basic_blocks
-
1
)
->
end
))
&&
need_fake_edge_p
(
BASIC_BLOCK
(
n_basic_blocks
-
1
)
->
end
))
{
{
edge
e
;
edge
e
;
for
(
e
=
BASIC_BLOCK
(
n_basic_blocks
-
1
)
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
BASIC_BLOCK
(
n_basic_blocks
-
1
)
->
succ
;
e
;
e
=
e
->
succ_next
)
if
(
e
->
dest
==
EXIT_BLOCK_PTR
)
if
(
e
->
dest
==
EXIT_BLOCK_PTR
)
break
;
break
;
insert_insn_on_edge
(
gen_rtx_USE
(
VOIDmode
,
const0_rtx
),
e
);
insert_insn_on_edge
(
gen_rtx_USE
(
VOIDmode
,
const0_rtx
),
e
);
commit_edge_insertions
();
commit_edge_insertions
();
}
}
/* Now add fake edges to the function exit for any non constant
/* Now add fake edges to the function exit for any non constant
calls since there is no way that we can determine if they will
calls since there is no way that we can determine if they will
return or not... */
return or not... */
...
@@ -289,9 +291,10 @@ flow_call_edges_add (blocks)
...
@@ -289,9 +291,10 @@ flow_call_edges_add (blocks)
edge
e
;
edge
e
;
/* The above condition should be enough to verify that there is
/* The above condition should be enough to verify that there is
no edge to the exit block in CFG already. Calling make_edge in
no edge to the exit block in CFG already. Calling make_edge
such case would make us to mark that edge as fake and remove it
in such case would make us to mark that edge as fake and
later. */
remove it later. */
#ifdef ENABLE_CHECKING
#ifdef ENABLE_CHECKING
if
(
insn
==
bb
->
end
)
if
(
insn
==
bb
->
end
)
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
...
@@ -307,6 +310,7 @@ flow_call_edges_add (blocks)
...
@@ -307,6 +310,7 @@ flow_call_edges_add (blocks)
make_edge
(
bb
,
EXIT_BLOCK_PTR
,
EDGE_FAKE
);
make_edge
(
bb
,
EXIT_BLOCK_PTR
,
EDGE_FAKE
);
}
}
if
(
insn
==
bb
->
head
)
if
(
insn
==
bb
->
head
)
break
;
break
;
}
}
...
@@ -318,6 +322,7 @@ flow_call_edges_add (blocks)
...
@@ -318,6 +322,7 @@ flow_call_edges_add (blocks)
free
(
bbs
);
free
(
bbs
);
return
blocks_split
;
return
blocks_split
;
}
}
/* Find unreachable blocks. An unreachable block will have 0 in
/* Find unreachable blocks. An unreachable block will have 0 in
the reachable bit in block->flags. A non-zero value indicates the
the reachable bit in block->flags. A non-zero value indicates the
block is reachable. */
block is reachable. */
...
@@ -401,6 +406,7 @@ create_edge_list ()
...
@@ -401,6 +406,7 @@ create_edge_list ()
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
num_edges
++
;
num_edges
++
;
}
}
/* Don't forget successors of the entry block. */
/* Don't forget successors of the entry block. */
for
(
e
=
ENTRY_BLOCK_PTR
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
ENTRY_BLOCK_PTR
->
succ
;
e
;
e
=
e
->
succ_next
)
num_edges
++
;
num_edges
++
;
...
@@ -414,10 +420,7 @@ create_edge_list ()
...
@@ -414,10 +420,7 @@ create_edge_list ()
/* Follow successors of the entry block, and register these edges. */
/* Follow successors of the entry block, and register these edges. */
for
(
e
=
ENTRY_BLOCK_PTR
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
ENTRY_BLOCK_PTR
->
succ
;
e
;
e
=
e
->
succ_next
)
{
elist
->
index_to_edge
[
num_edges
++
]
=
e
;
elist
->
index_to_edge
[
num_edges
]
=
e
;
num_edges
++
;
}
for
(
x
=
0
;
x
<
n_basic_blocks
;
x
++
)
for
(
x
=
0
;
x
<
n_basic_blocks
;
x
++
)
{
{
...
@@ -425,11 +428,9 @@ create_edge_list ()
...
@@ -425,11 +428,9 @@ create_edge_list ()
/* Follow all successors of blocks, and register these edges. */
/* Follow all successors of blocks, and register these edges. */
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
bb
->
succ
;
e
;
e
=
e
->
succ_next
)
{
elist
->
index_to_edge
[
num_edges
++
]
=
e
;
elist
->
index_to_edge
[
num_edges
]
=
e
;
num_edges
++
;
}
}
}
return
elist
;
return
elist
;
}
}
...
@@ -454,6 +455,7 @@ print_edge_list (f, elist)
...
@@ -454,6 +455,7 @@ print_edge_list (f, elist)
struct
edge_list
*
elist
;
struct
edge_list
*
elist
;
{
{
int
x
;
int
x
;
fprintf
(
f
,
"Compressed edge list, %d BBs + entry & exit, and %d edges
\n
"
,
fprintf
(
f
,
"Compressed edge list, %d BBs + entry & exit, and %d edges
\n
"
,
elist
->
num_blocks
-
2
,
elist
->
num_edges
);
elist
->
num_blocks
-
2
,
elist
->
num_edges
);
...
@@ -498,6 +500,7 @@ verify_edge_list (f, elist)
...
@@ -498,6 +500,7 @@ verify_edge_list (f, elist)
fprintf
(
f
,
"*p* No index for edge from %d to %d
\n
"
,
pred
,
succ
);
fprintf
(
f
,
"*p* No index for edge from %d to %d
\n
"
,
pred
,
succ
);
continue
;
continue
;
}
}
if
(
INDEX_EDGE_PRED_BB
(
elist
,
index
)
->
index
!=
pred
)
if
(
INDEX_EDGE_PRED_BB
(
elist
,
index
)
->
index
!=
pred
)
fprintf
(
f
,
"*p* Pred for index %d should be %d not %d
\n
"
,
fprintf
(
f
,
"*p* Pred for index %d should be %d not %d
\n
"
,
index
,
pred
,
INDEX_EDGE_PRED_BB
(
elist
,
index
)
->
index
);
index
,
pred
,
INDEX_EDGE_PRED_BB
(
elist
,
index
)
->
index
);
...
@@ -506,6 +509,7 @@ verify_edge_list (f, elist)
...
@@ -506,6 +509,7 @@ verify_edge_list (f, elist)
index
,
succ
,
INDEX_EDGE_SUCC_BB
(
elist
,
index
)
->
index
);
index
,
succ
,
INDEX_EDGE_SUCC_BB
(
elist
,
index
)
->
index
);
}
}
}
}
for
(
e
=
ENTRY_BLOCK_PTR
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
ENTRY_BLOCK_PTR
->
succ
;
e
;
e
=
e
->
succ_next
)
{
{
pred
=
e
->
src
->
index
;
pred
=
e
->
src
->
index
;
...
@@ -516,6 +520,7 @@ verify_edge_list (f, elist)
...
@@ -516,6 +520,7 @@ verify_edge_list (f, elist)
fprintf
(
f
,
"*p* No index for edge from %d to %d
\n
"
,
pred
,
succ
);
fprintf
(
f
,
"*p* No index for edge from %d to %d
\n
"
,
pred
,
succ
);
continue
;
continue
;
}
}
if
(
INDEX_EDGE_PRED_BB
(
elist
,
index
)
->
index
!=
pred
)
if
(
INDEX_EDGE_PRED_BB
(
elist
,
index
)
->
index
!=
pred
)
fprintf
(
f
,
"*p* Pred for index %d should be %d not %d
\n
"
,
fprintf
(
f
,
"*p* Pred for index %d should be %d not %d
\n
"
,
index
,
pred
,
INDEX_EDGE_PRED_BB
(
elist
,
index
)
->
index
);
index
,
pred
,
INDEX_EDGE_PRED_BB
(
elist
,
index
)
->
index
);
...
@@ -523,6 +528,7 @@ verify_edge_list (f, elist)
...
@@ -523,6 +528,7 @@ verify_edge_list (f, elist)
fprintf
(
f
,
"*p* Succ for index %d should be %d not %d
\n
"
,
fprintf
(
f
,
"*p* Succ for index %d should be %d not %d
\n
"
,
index
,
succ
,
INDEX_EDGE_SUCC_BB
(
elist
,
index
)
->
index
);
index
,
succ
,
INDEX_EDGE_SUCC_BB
(
elist
,
index
)
->
index
);
}
}
/* We've verified that all the edges are in the list, no lets make sure
/* We've verified that all the edges are in the list, no lets make sure
there are no spurious edges in the list. */
there are no spurious edges in the list. */
...
@@ -531,7 +537,6 @@ verify_edge_list (f, elist)
...
@@ -531,7 +537,6 @@ verify_edge_list (f, elist)
{
{
basic_block
p
=
BASIC_BLOCK
(
pred
);
basic_block
p
=
BASIC_BLOCK
(
pred
);
basic_block
s
=
BASIC_BLOCK
(
succ
);
basic_block
s
=
BASIC_BLOCK
(
succ
);
int
found_edge
=
0
;
int
found_edge
=
0
;
for
(
e
=
p
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
p
->
succ
;
e
;
e
=
e
->
succ_next
)
...
@@ -540,12 +545,14 @@ verify_edge_list (f, elist)
...
@@ -540,12 +545,14 @@ verify_edge_list (f, elist)
found_edge
=
1
;
found_edge
=
1
;
break
;
break
;
}
}
for
(
e
=
s
->
pred
;
e
;
e
=
e
->
pred_next
)
for
(
e
=
s
->
pred
;
e
;
e
=
e
->
pred_next
)
if
(
e
->
src
==
p
)
if
(
e
->
src
==
p
)
{
{
found_edge
=
1
;
found_edge
=
1
;
break
;
break
;
}
}
if
(
EDGE_INDEX
(
elist
,
BASIC_BLOCK
(
pred
),
BASIC_BLOCK
(
succ
))
if
(
EDGE_INDEX
(
elist
,
BASIC_BLOCK
(
pred
),
BASIC_BLOCK
(
succ
))
==
EDGE_INDEX_NO_EDGE
&&
found_edge
!=
0
)
==
EDGE_INDEX_NO_EDGE
&&
found_edge
!=
0
)
fprintf
(
f
,
"*** Edge (%d, %d) appears to not have an index
\n
"
,
fprintf
(
f
,
"*** Edge (%d, %d) appears to not have an index
\n
"
,
...
@@ -556,11 +563,11 @@ verify_edge_list (f, elist)
...
@@ -556,11 +563,11 @@ verify_edge_list (f, elist)
pred
,
succ
,
EDGE_INDEX
(
elist
,
BASIC_BLOCK
(
pred
),
pred
,
succ
,
EDGE_INDEX
(
elist
,
BASIC_BLOCK
(
pred
),
BASIC_BLOCK
(
succ
)));
BASIC_BLOCK
(
succ
)));
}
}
for
(
succ
=
0
;
succ
<
n_basic_blocks
;
succ
++
)
for
(
succ
=
0
;
succ
<
n_basic_blocks
;
succ
++
)
{
{
basic_block
p
=
ENTRY_BLOCK_PTR
;
basic_block
p
=
ENTRY_BLOCK_PTR
;
basic_block
s
=
BASIC_BLOCK
(
succ
);
basic_block
s
=
BASIC_BLOCK
(
succ
);
int
found_edge
=
0
;
int
found_edge
=
0
;
for
(
e
=
p
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
p
->
succ
;
e
;
e
=
e
->
succ_next
)
...
@@ -569,12 +576,14 @@ verify_edge_list (f, elist)
...
@@ -569,12 +576,14 @@ verify_edge_list (f, elist)
found_edge
=
1
;
found_edge
=
1
;
break
;
break
;
}
}
for
(
e
=
s
->
pred
;
e
;
e
=
e
->
pred_next
)
for
(
e
=
s
->
pred
;
e
;
e
=
e
->
pred_next
)
if
(
e
->
src
==
p
)
if
(
e
->
src
==
p
)
{
{
found_edge
=
1
;
found_edge
=
1
;
break
;
break
;
}
}
if
(
EDGE_INDEX
(
elist
,
ENTRY_BLOCK_PTR
,
BASIC_BLOCK
(
succ
))
if
(
EDGE_INDEX
(
elist
,
ENTRY_BLOCK_PTR
,
BASIC_BLOCK
(
succ
))
==
EDGE_INDEX_NO_EDGE
&&
found_edge
!=
0
)
==
EDGE_INDEX_NO_EDGE
&&
found_edge
!=
0
)
fprintf
(
f
,
"*** Edge (entry, %d) appears to not have an index
\n
"
,
fprintf
(
f
,
"*** Edge (entry, %d) appears to not have an index
\n
"
,
...
@@ -585,11 +594,11 @@ verify_edge_list (f, elist)
...
@@ -585,11 +594,11 @@ verify_edge_list (f, elist)
succ
,
EDGE_INDEX
(
elist
,
ENTRY_BLOCK_PTR
,
succ
,
EDGE_INDEX
(
elist
,
ENTRY_BLOCK_PTR
,
BASIC_BLOCK
(
succ
)));
BASIC_BLOCK
(
succ
)));
}
}
for
(
pred
=
0
;
pred
<
n_basic_blocks
;
pred
++
)
for
(
pred
=
0
;
pred
<
n_basic_blocks
;
pred
++
)
{
{
basic_block
p
=
BASIC_BLOCK
(
pred
);
basic_block
p
=
BASIC_BLOCK
(
pred
);
basic_block
s
=
EXIT_BLOCK_PTR
;
basic_block
s
=
EXIT_BLOCK_PTR
;
int
found_edge
=
0
;
int
found_edge
=
0
;
for
(
e
=
p
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
p
->
succ
;
e
;
e
=
e
->
succ_next
)
...
@@ -598,12 +607,14 @@ verify_edge_list (f, elist)
...
@@ -598,12 +607,14 @@ verify_edge_list (f, elist)
found_edge
=
1
;
found_edge
=
1
;
break
;
break
;
}
}
for
(
e
=
s
->
pred
;
e
;
e
=
e
->
pred_next
)
for
(
e
=
s
->
pred
;
e
;
e
=
e
->
pred_next
)
if
(
e
->
src
==
p
)
if
(
e
->
src
==
p
)
{
{
found_edge
=
1
;
found_edge
=
1
;
break
;
break
;
}
}
if
(
EDGE_INDEX
(
elist
,
BASIC_BLOCK
(
pred
),
EXIT_BLOCK_PTR
)
if
(
EDGE_INDEX
(
elist
,
BASIC_BLOCK
(
pred
),
EXIT_BLOCK_PTR
)
==
EDGE_INDEX_NO_EDGE
&&
found_edge
!=
0
)
==
EDGE_INDEX_NO_EDGE
&&
found_edge
!=
0
)
fprintf
(
f
,
"*** Edge (%d, exit) appears to not have an index
\n
"
,
fprintf
(
f
,
"*** Edge (%d, exit) appears to not have an index
\n
"
,
...
@@ -625,12 +636,12 @@ find_edge_index (edge_list, pred, succ)
...
@@ -625,12 +636,12 @@ find_edge_index (edge_list, pred, succ)
basic_block
pred
,
succ
;
basic_block
pred
,
succ
;
{
{
int
x
;
int
x
;
for
(
x
=
0
;
x
<
NUM_EDGES
(
edge_list
);
x
++
)
for
(
x
=
0
;
x
<
NUM_EDGES
(
edge_list
);
x
++
)
{
if
(
INDEX_EDGE_PRED_BB
(
edge_list
,
x
)
==
pred
if
(
INDEX_EDGE_PRED_BB
(
edge_list
,
x
)
==
pred
&&
INDEX_EDGE_SUCC_BB
(
edge_list
,
x
)
==
succ
)
&&
INDEX_EDGE_SUCC_BB
(
edge_list
,
x
)
==
succ
)
return
x
;
return
x
;
}
return
(
EDGE_INDEX_NO_EDGE
);
return
(
EDGE_INDEX_NO_EDGE
);
}
}
...
@@ -670,6 +681,7 @@ flow_edge_list_print (str, edge_list, num_edges, file)
...
@@ -670,6 +681,7 @@ flow_edge_list_print (str, edge_list, num_edges, file)
for
(
i
=
0
;
i
<
num_edges
;
i
++
)
for
(
i
=
0
;
i
<
num_edges
;
i
++
)
fprintf
(
file
,
"%d->%d "
,
edge_list
[
i
]
->
src
->
index
,
fprintf
(
file
,
"%d->%d "
,
edge_list
[
i
]
->
src
->
index
,
edge_list
[
i
]
->
dest
->
index
);
edge_list
[
i
]
->
dest
->
index
);
fputs
(
"}
\n
"
,
file
);
fputs
(
"}
\n
"
,
file
);
}
}
...
@@ -683,9 +695,11 @@ remove_fake_successors (bb)
...
@@ -683,9 +695,11 @@ remove_fake_successors (bb)
basic_block
bb
;
basic_block
bb
;
{
{
edge
e
;
edge
e
;
for
(
e
=
bb
->
succ
;
e
;)
for
(
e
=
bb
->
succ
;
e
;)
{
{
edge
tmp
=
e
;
edge
tmp
=
e
;
e
=
e
->
succ_next
;
e
=
e
->
succ_next
;
if
((
tmp
->
flags
&
EDGE_FAKE
)
==
EDGE_FAKE
)
if
((
tmp
->
flags
&
EDGE_FAKE
)
==
EDGE_FAKE
)
remove_edge
(
tmp
);
remove_edge
(
tmp
);
...
@@ -737,11 +751,10 @@ void
...
@@ -737,11 +751,10 @@ void
connect_infinite_loops_to_exit
()
connect_infinite_loops_to_exit
()
{
{
basic_block
unvisited_block
;
basic_block
unvisited_block
;
struct
depth_first_search_dsS
dfs_ds
;
/* Perform depth-first search in the reverse graph to find nodes
/* Perform depth-first search in the reverse graph to find nodes
reachable from the exit block. */
reachable from the exit block. */
struct
depth_first_search_dsS
dfs_ds
;
flow_dfs_compute_reverse_init
(
&
dfs_ds
);
flow_dfs_compute_reverse_init
(
&
dfs_ds
);
flow_dfs_compute_reverse_add_bb
(
&
dfs_ds
,
EXIT_BLOCK_PTR
);
flow_dfs_compute_reverse_add_bb
(
&
dfs_ds
,
EXIT_BLOCK_PTR
);
...
@@ -751,16 +764,17 @@ connect_infinite_loops_to_exit ()
...
@@ -751,16 +764,17 @@ connect_infinite_loops_to_exit ()
unvisited_block
=
flow_dfs_compute_reverse_execute
(
&
dfs_ds
);
unvisited_block
=
flow_dfs_compute_reverse_execute
(
&
dfs_ds
);
if
(
!
unvisited_block
)
if
(
!
unvisited_block
)
break
;
break
;
make_edge
(
unvisited_block
,
EXIT_BLOCK_PTR
,
EDGE_FAKE
);
make_edge
(
unvisited_block
,
EXIT_BLOCK_PTR
,
EDGE_FAKE
);
flow_dfs_compute_reverse_add_bb
(
&
dfs_ds
,
unvisited_block
);
flow_dfs_compute_reverse_add_bb
(
&
dfs_ds
,
unvisited_block
);
}
}
flow_dfs_compute_reverse_finish
(
&
dfs_ds
);
flow_dfs_compute_reverse_finish
(
&
dfs_ds
);
return
;
return
;
}
}
/* Compute reverse top sort order */
/* Compute reverse top sort order */
void
void
flow_reverse_top_sort_order_compute
(
rts_order
)
flow_reverse_top_sort_order_compute
(
rts_order
)
int
*
rts_order
;
int
*
rts_order
;
...
@@ -801,11 +815,9 @@ flow_reverse_top_sort_order_compute (rts_order)
...
@@ -801,11 +815,9 @@ flow_reverse_top_sort_order_compute (rts_order)
SET_BIT
(
visited
,
dest
->
index
);
SET_BIT
(
visited
,
dest
->
index
);
if
(
dest
->
succ
)
if
(
dest
->
succ
)
{
/* Since the DEST node has been visited for the first
/* Since the DEST node has been visited for the first
time, check its successors. */
time, check its successors. */
stack
[
sp
++
]
=
dest
->
succ
;
stack
[
sp
++
]
=
dest
->
succ
;
}
else
else
rts_order
[
postnum
++
]
=
dest
->
index
;
rts_order
[
postnum
++
]
=
dest
->
index
;
}
}
...
@@ -879,28 +891,21 @@ flow_depth_first_order_compute (dfs_order, rc_order)
...
@@ -879,28 +891,21 @@ flow_depth_first_order_compute (dfs_order, rc_order)
dfsnum
++
;
dfsnum
++
;
if
(
dest
->
succ
)
if
(
dest
->
succ
)
{
/* Since the DEST node has been visited for the first
/* Since the DEST node has been visited for the first
time, check its successors. */
time, check its successors. */
stack
[
sp
++
]
=
dest
->
succ
;
stack
[
sp
++
]
=
dest
->
succ
;
else
if
(
rc_order
)
}
/* There are no successors for the DEST node so assign
else
its reverse completion number. */
{
rc_order
[
rcnum
--
]
=
dest
->
index
;
/* There are no successors for the DEST node so assign
its reverse completion number. */
if
(
rc_order
)
rc_order
[
rcnum
--
]
=
dest
->
index
;
}
}
}
else
else
{
{
if
(
!
e
->
succ_next
&&
src
!=
ENTRY_BLOCK_PTR
)
if
(
!
e
->
succ_next
&&
src
!=
ENTRY_BLOCK_PTR
{
&&
rc_order
)
/* There are no more successors for the SRC node
/* There are no more successors for the SRC node
so assign its reverse completion number. */
so assign its reverse completion number. */
if
(
rc_order
)
rc_order
[
rcnum
--
]
=
src
->
index
;
rc_order
[
rcnum
--
]
=
src
->
index
;
}
if
(
e
->
succ_next
)
if
(
e
->
succ_next
)
stack
[
sp
-
1
]
=
e
->
succ_next
;
stack
[
sp
-
1
]
=
e
->
succ_next
;
...
@@ -920,10 +925,12 @@ flow_depth_first_order_compute (dfs_order, rc_order)
...
@@ -920,10 +925,12 @@ flow_depth_first_order_compute (dfs_order, rc_order)
/* There are some nodes left in the CFG that are unreachable. */
/* There are some nodes left in the CFG that are unreachable. */
if
(
dfsnum
<
n_basic_blocks
)
if
(
dfsnum
<
n_basic_blocks
)
abort
();
abort
();
return
dfsnum
;
return
dfsnum
;
}
}
struct
dfst_node
{
struct
dfst_node
{
unsigned
nnodes
;
unsigned
nnodes
;
struct
dfst_node
**
node
;
struct
dfst_node
**
node
;
struct
dfst_node
*
up
;
struct
dfst_node
*
up
;
...
@@ -958,17 +965,20 @@ flow_preorder_transversal_compute (pot_order)
...
@@ -958,17 +965,20 @@ flow_preorder_transversal_compute (pot_order)
sp
=
0
;
sp
=
0
;
/* Allocate the tree. */
/* Allocate the tree. */
dfst
dfst
=
(
struct
dfst_node
*
)
xcalloc
(
n_basic_blocks
,
=
(
struct
dfst_node
*
)
xcalloc
(
n_basic_blocks
,
sizeof
(
struct
dfst_node
));
sizeof
(
struct
dfst_node
));
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
{
{
max_successors
=
0
;
max_successors
=
0
;
for
(
e
=
BASIC_BLOCK
(
i
)
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
BASIC_BLOCK
(
i
)
->
succ
;
e
;
e
=
e
->
succ_next
)
max_successors
++
;
max_successors
++
;
dfst
[
i
].
node
=
max_successors
?
(
struct
dfst_node
**
)
xcalloc
(
max_successors
,
dfst
[
i
].
node
sizeof
(
struct
dfst_node
*
))
=
(
max_successors
:
NULL
;
?
(
struct
dfst_node
**
)
xcalloc
(
max_successors
,
sizeof
(
struct
dfst_node
*
))
:
NULL
);
}
}
/* Allocate bitmap to track nodes that have been visited. */
/* Allocate bitmap to track nodes that have been visited. */
...
@@ -1005,19 +1015,15 @@ flow_preorder_transversal_compute (pot_order)
...
@@ -1005,19 +1015,15 @@ flow_preorder_transversal_compute (pot_order)
}
}
if
(
dest
->
succ
)
if
(
dest
->
succ
)
{
/* Since the DEST node has been visited for the first
/* Since the DEST node has been visited for the first
time, check its successors. */
time, check its successors. */
stack
[
sp
++
]
=
dest
->
succ
;
stack
[
sp
++
]
=
dest
->
succ
;
}
}
}
else
if
(
e
->
succ_next
)
stack
[
sp
-
1
]
=
e
->
succ_next
;
else
else
{
sp
--
;
if
(
e
->
succ_next
)
stack
[
sp
-
1
]
=
e
->
succ_next
;
else
sp
--
;
}
}
}
free
(
stack
);
free
(
stack
);
...
@@ -1046,6 +1052,7 @@ flow_preorder_transversal_compute (pot_order)
...
@@ -1046,6 +1052,7 @@ flow_preorder_transversal_compute (pot_order)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
if
(
dfst
[
i
].
node
)
if
(
dfst
[
i
].
node
)
free
(
dfst
[
i
].
node
);
free
(
dfst
[
i
].
node
);
free
(
dfst
);
free
(
dfst
);
}
}
...
@@ -1084,9 +1091,8 @@ flow_dfs_compute_reverse_init (data)
...
@@ -1084,9 +1091,8 @@ flow_dfs_compute_reverse_init (data)
depth_first_search_ds
data
;
depth_first_search_ds
data
;
{
{
/* Allocate stack for back-tracking up CFG. */
/* Allocate stack for back-tracking up CFG. */
data
->
stack
=
data
->
stack
=
(
basic_block
*
)
xmalloc
((
n_basic_blocks
-
(
INVALID_BLOCK
+
1
))
(
basic_block
*
)
xmalloc
((
n_basic_blocks
-
(
INVALID_BLOCK
+
1
))
*
sizeof
(
basic_block
));
*
sizeof
(
basic_block
));
data
->
sp
=
0
;
data
->
sp
=
0
;
/* Allocate bitmap to track nodes that have been visited. */
/* Allocate bitmap to track nodes that have been visited. */
...
@@ -1109,13 +1115,12 @@ flow_dfs_compute_reverse_add_bb (data, bb)
...
@@ -1109,13 +1115,12 @@ flow_dfs_compute_reverse_add_bb (data, bb)
{
{
data
->
stack
[
data
->
sp
++
]
=
bb
;
data
->
stack
[
data
->
sp
++
]
=
bb
;
SET_BIT
(
data
->
visited_blocks
,
bb
->
index
-
(
INVALID_BLOCK
+
1
));
SET_BIT
(
data
->
visited_blocks
,
bb
->
index
-
(
INVALID_BLOCK
+
1
));
return
;
}
}
/* Continue the depth-first search through the reverse graph starting
/* Continue the depth-first search through the reverse graph starting
with the
with the block at the stack's top and ending when the stack i
s
block at the stack's top and ending when the stack is empty. Visited node
s
empty. Visited nodes are marked. Returns an unvisited basic
are marked. Returns an unvisited basic block, or NULL if there is none
block, or NULL if there is none
available. */
available. */
static
basic_block
static
basic_block
flow_dfs_compute_reverse_execute
(
data
)
flow_dfs_compute_reverse_execute
(
data
)
...
@@ -1128,6 +1133,7 @@ flow_dfs_compute_reverse_execute (data)
...
@@ -1128,6 +1133,7 @@ flow_dfs_compute_reverse_execute (data)
while
(
data
->
sp
>
0
)
while
(
data
->
sp
>
0
)
{
{
bb
=
data
->
stack
[
--
data
->
sp
];
bb
=
data
->
stack
[
--
data
->
sp
];
/* Perform depth-first search on adjacent vertices. */
/* Perform depth-first search on adjacent vertices. */
for
(
e
=
bb
->
pred
;
e
;
e
=
e
->
pred_next
)
for
(
e
=
bb
->
pred
;
e
;
e
=
e
->
pred_next
)
if
(
!
TEST_BIT
(
data
->
visited_blocks
,
if
(
!
TEST_BIT
(
data
->
visited_blocks
,
...
@@ -1136,9 +1142,10 @@ flow_dfs_compute_reverse_execute (data)
...
@@ -1136,9 +1142,10 @@ flow_dfs_compute_reverse_execute (data)
}
}
/* Determine if there are unvisited basic blocks. */
/* Determine if there are unvisited basic blocks. */
for
(
i
=
n_basic_blocks
-
(
INVALID_BLOCK
+
1
);
--
i
>=
0
;)
for
(
i
=
n_basic_blocks
-
(
INVALID_BLOCK
+
1
);
--
i
>=
0
;
)
if
(
!
TEST_BIT
(
data
->
visited_blocks
,
i
))
if
(
!
TEST_BIT
(
data
->
visited_blocks
,
i
))
return
BASIC_BLOCK
(
i
+
(
INVALID_BLOCK
+
1
));
return
BASIC_BLOCK
(
i
+
(
INVALID_BLOCK
+
1
));
return
NULL
;
return
NULL
;
}
}
...
@@ -1151,5 +1158,4 @@ flow_dfs_compute_reverse_finish (data)
...
@@ -1151,5 +1158,4 @@ flow_dfs_compute_reverse_finish (data)
{
{
free
(
data
->
stack
);
free
(
data
->
stack
);
sbitmap_free
(
data
->
visited_blocks
);
sbitmap_free
(
data
->
visited_blocks
);
return
;
}
}
gcc/cfgbuild.c
View file @
4891442b
...
@@ -30,8 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
...
@@ -30,8 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- CFG construction
- CFG construction
find_basic_blocks
find_basic_blocks
- Local CFG construction
- Local CFG construction
find_sub_basic_blocks
find_sub_basic_blocks */
*/
#include "config.h"
#include "config.h"
#include "system.h"
#include "system.h"
...
@@ -46,8 +45,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
...
@@ -46,8 +45,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "except.h"
#include "except.h"
#include "toplev.h"
#include "toplev.h"
#include "timevar.h"
#include "timevar.h"
#include "obstack.h"
#include "obstack.h"
static
int
count_basic_blocks
PARAMS
((
rtx
));
static
int
count_basic_blocks
PARAMS
((
rtx
));
static
void
find_basic_blocks_1
PARAMS
((
rtx
));
static
void
find_basic_blocks_1
PARAMS
((
rtx
));
static
rtx
find_label_refs
PARAMS
((
rtx
,
rtx
));
static
rtx
find_label_refs
PARAMS
((
rtx
,
rtx
));
...
@@ -59,7 +58,7 @@ static void find_bb_boundaries PARAMS ((basic_block));
...
@@ -59,7 +58,7 @@ static void find_bb_boundaries PARAMS ((basic_block));
static
void
compute_outgoing_frequencies
PARAMS
((
basic_block
));
static
void
compute_outgoing_frequencies
PARAMS
((
basic_block
));
static
bool
inside_basic_block_p
PARAMS
((
rtx
));
static
bool
inside_basic_block_p
PARAMS
((
rtx
));
static
bool
control_flow_insn_p
PARAMS
((
rtx
));
static
bool
control_flow_insn_p
PARAMS
((
rtx
));
/* Return true if insn is something that should be contained inside basic
/* Return true if insn is something that should be contained inside basic
block. */
block. */
...
@@ -71,18 +70,14 @@ inside_basic_block_p (insn)
...
@@ -71,18 +70,14 @@ inside_basic_block_p (insn)
{
{
case
CODE_LABEL
:
case
CODE_LABEL
:
/* Avoid creating of basic block for jumptables. */
/* Avoid creating of basic block for jumptables. */
if
(
NEXT_INSN
(
insn
)
return
(
NEXT_INSN
(
insn
)
==
0
&&
GET_CODE
(
NEXT_INSN
(
insn
))
==
JUMP_INSN
||
GET_CODE
(
NEXT_INSN
(
insn
))
!=
JUMP_INSN
&&
(
GET_CODE
(
PATTERN
(
NEXT_INSN
(
insn
)))
==
ADDR_VEC
||
(
GET_CODE
(
PATTERN
(
NEXT_INSN
(
insn
)))
!=
ADDR_VEC
||
GET_CODE
(
PATTERN
(
NEXT_INSN
(
insn
)))
==
ADDR_DIFF_VEC
))
&&
GET_CODE
(
PATTERN
(
NEXT_INSN
(
insn
)))
!=
ADDR_DIFF_VEC
));
return
false
;
return
true
;
case
JUMP_INSN
:
case
JUMP_INSN
:
if
(
GET_CODE
(
PATTERN
(
insn
))
==
ADDR_VEC
return
(
GET_CODE
(
PATTERN
(
insn
))
!=
ADDR_VEC
||
GET_CODE
(
PATTERN
(
insn
))
==
ADDR_DIFF_VEC
)
&&
GET_CODE
(
PATTERN
(
insn
))
!=
ADDR_DIFF_VEC
);
return
false
;
return
true
;
case
CALL_INSN
:
case
CALL_INSN
:
case
INSN
:
case
INSN
:
...
@@ -97,14 +92,15 @@ inside_basic_block_p (insn)
...
@@ -97,14 +92,15 @@ inside_basic_block_p (insn)
}
}
}
}
/* Return true if INSN may cause control flow transfer, so
/* Return true if INSN may cause control flow transfer, so
it should be last in
it should be last in
the basic block. */
the basic block. */
static
bool
static
bool
control_flow_insn_p
(
insn
)
control_flow_insn_p
(
insn
)
rtx
insn
;
rtx
insn
;
{
{
rtx
note
;
rtx
note
;
switch
(
GET_CODE
(
insn
))
switch
(
GET_CODE
(
insn
))
{
{
case
NOTE
:
case
NOTE
:
...
@@ -113,23 +109,20 @@ control_flow_insn_p (insn)
...
@@ -113,23 +109,20 @@ control_flow_insn_p (insn)
case
JUMP_INSN
:
case
JUMP_INSN
:
/* Jump insn always causes control transfer except for tablejumps. */
/* Jump insn always causes control transfer except for tablejumps. */
if
(
GET_CODE
(
PATTERN
(
insn
))
==
ADDR_VEC
return
(
GET_CODE
(
PATTERN
(
insn
))
!=
ADDR_VEC
||
GET_CODE
(
PATTERN
(
insn
))
==
ADDR_DIFF_VEC
)
&&
GET_CODE
(
PATTERN
(
insn
))
!=
ADDR_DIFF_VEC
);
return
false
;
return
true
;
case
CALL_INSN
:
case
CALL_INSN
:
/* Call insn may return to the nonlocal goto handler. */
/* Call insn may return to the nonlocal goto handler. */
if
(
nonlocal_goto_handler_labels
return
(
(
nonlocal_goto_handler_labels
&&
((
note
=
find_reg_note
(
insn
,
REG_EH_REGION
,
NULL_RTX
))
==
0
&&
(
0
==
(
note
=
find_reg_note
(
insn
,
REG_EH_REGION
,
||
INTVAL
(
XEXP
(
note
,
0
))
>=
0
))
NULL_RTX
))
return
true
;
||
INTVAL
(
XEXP
(
note
,
0
))
>=
0
))
/* Or may trap. */
/* Or may trap. */
return
can_throw_internal
(
insn
);
||
can_throw_internal
(
insn
)
);
case
INSN
:
case
INSN
:
return
(
flag_non_call_exceptions
return
(
flag_non_call_exceptions
&&
can_throw_internal
(
insn
));
&&
can_throw_internal
(
insn
));
case
BARRIER
:
case
BARRIER
:
/* It is nonsence to reach barrier when looking for the
/* It is nonsence to reach barrier when looking for the
...
@@ -156,7 +149,6 @@ count_basic_blocks (f)
...
@@ -156,7 +149,6 @@ count_basic_blocks (f)
{
{
/* Code labels and barriers causes curent basic block to be
/* Code labels and barriers causes curent basic block to be
terminated at previous real insn. */
terminated at previous real insn. */
if
((
GET_CODE
(
insn
)
==
CODE_LABEL
||
GET_CODE
(
insn
)
==
BARRIER
)
if
((
GET_CODE
(
insn
)
==
CODE_LABEL
||
GET_CODE
(
insn
)
==
BARRIER
)
&&
saw_insn
)
&&
saw_insn
)
count
++
,
saw_insn
=
false
;
count
++
,
saw_insn
=
false
;
...
@@ -169,6 +161,7 @@ count_basic_blocks (f)
...
@@ -169,6 +161,7 @@ count_basic_blocks (f)
if
(
saw_insn
&&
control_flow_insn_p
(
insn
))
if
(
saw_insn
&&
control_flow_insn_p
(
insn
))
count
++
,
saw_insn
=
false
;
count
++
,
saw_insn
=
false
;
}
}
if
(
saw_insn
)
if
(
saw_insn
)
count
++
;
count
++
;
...
@@ -185,6 +178,7 @@ count_basic_blocks (f)
...
@@ -185,6 +178,7 @@ count_basic_blocks (f)
/* Scan a list of insns for labels referred to other than by jumps.
/* Scan a list of insns for labels referred to other than by jumps.
This is used to scan the alternatives of a call placeholder. */
This is used to scan the alternatives of a call placeholder. */
static
rtx
static
rtx
find_label_refs
(
f
,
lvl
)
find_label_refs
(
f
,
lvl
)
rtx
f
;
rtx
f
;
...
@@ -263,7 +257,7 @@ make_eh_edge (edge_cache, src, insn)
...
@@ -263,7 +257,7 @@ make_eh_edge (edge_cache, src, insn)
basic_block
src
;
basic_block
src
;
rtx
insn
;
rtx
insn
;
{
{
int
is_call
=
(
GET_CODE
(
insn
)
==
CALL_INSN
?
EDGE_ABNORMAL_CALL
:
0
)
;
int
is_call
=
GET_CODE
(
insn
)
==
CALL_INSN
?
EDGE_ABNORMAL_CALL
:
0
;
rtx
handlers
,
i
;
rtx
handlers
,
i
;
handlers
=
reachable_handlers
(
insn
);
handlers
=
reachable_handlers
(
insn
);
...
@@ -274,6 +268,7 @@ make_eh_edge (edge_cache, src, insn)
...
@@ -274,6 +268,7 @@ make_eh_edge (edge_cache, src, insn)
free_INSN_LIST_list
(
&
handlers
);
free_INSN_LIST_list
(
&
handlers
);
}
}
/* Identify the edges between basic blocks MIN to MAX.
/* Identify the edges between basic blocks MIN to MAX.
NONLOCAL_LABEL_LIST is a list of non-local labels in the function. Blocks
NONLOCAL_LABEL_LIST is a list of non-local labels in the function. Blocks
...
@@ -305,6 +300,7 @@ make_edges (label_value_list, min, max, update_p)
...
@@ -305,6 +300,7 @@ make_edges (label_value_list, min, max, update_p)
for
(
i
=
min
;
i
<=
max
;
++
i
)
for
(
i
=
min
;
i
<=
max
;
++
i
)
{
{
edge
e
;
edge
e
;
for
(
e
=
BASIC_BLOCK
(
i
)
->
succ
;
e
;
e
=
e
->
succ_next
)
for
(
e
=
BASIC_BLOCK
(
i
)
->
succ
;
e
;
e
=
e
->
succ_next
)
if
(
e
->
dest
!=
EXIT_BLOCK_PTR
)
if
(
e
->
dest
!=
EXIT_BLOCK_PTR
)
SET_BIT
(
edge_cache
[
i
],
e
->
dest
->
index
);
SET_BIT
(
edge_cache
[
i
],
e
->
dest
->
index
);
...
@@ -313,7 +309,8 @@ make_edges (label_value_list, min, max, update_p)
...
@@ -313,7 +309,8 @@ make_edges (label_value_list, min, max, update_p)
/* By nature of the way these get numbered, block 0 is always the entry. */
/* By nature of the way these get numbered, block 0 is always the entry. */
if
(
min
==
0
)
if
(
min
==
0
)
cached_make_edge
(
edge_cache
,
ENTRY_BLOCK_PTR
,
BASIC_BLOCK
(
0
),
EDGE_FALLTHRU
);
cached_make_edge
(
edge_cache
,
ENTRY_BLOCK_PTR
,
BASIC_BLOCK
(
0
),
EDGE_FALLTHRU
);
for
(
i
=
min
;
i
<=
max
;
++
i
)
for
(
i
=
min
;
i
<=
max
;
++
i
)
{
{
...
@@ -322,8 +319,7 @@ make_edges (label_value_list, min, max, update_p)
...
@@ -322,8 +319,7 @@ make_edges (label_value_list, min, max, update_p)
enum
rtx_code
code
;
enum
rtx_code
code
;
int
force_fallthru
=
0
;
int
force_fallthru
=
0
;
if
(
GET_CODE
(
bb
->
head
)
==
CODE_LABEL
if
(
GET_CODE
(
bb
->
head
)
==
CODE_LABEL
&&
LABEL_ALTERNATE_NAME
(
bb
->
head
))
&&
LABEL_ALTERNATE_NAME
(
bb
->
head
))
cached_make_edge
(
NULL
,
ENTRY_BLOCK_PTR
,
bb
,
0
);
cached_make_edge
(
NULL
,
ENTRY_BLOCK_PTR
,
bb
,
0
);
/* Examine the last instruction of the block, and discover the
/* Examine the last instruction of the block, and discover the
...
@@ -408,11 +404,10 @@ make_edges (label_value_list, min, max, update_p)
...
@@ -408,11 +404,10 @@ make_edges (label_value_list, min, max, update_p)
}
}
}
}
/* If this is a sibling call insn, then this is in effect a
/* If this is a sibling call insn, then this is in effect a combined call
combined call and return, and so we need an edge to the
and return, and so we need an edge to the exit block. No need to
exit block. No need to worry about EH edges, since we
worry about EH edges, since we wouldn't have created the sibling call
wouldn't have created the sibling call in the first place. */
in the first place. */
if
(
code
==
CALL_INSN
&&
SIBLING_CALL_P
(
insn
))
if
(
code
==
CALL_INSN
&&
SIBLING_CALL_P
(
insn
))
cached_make_edge
(
edge_cache
,
bb
,
EXIT_BLOCK_PTR
,
cached_make_edge
(
edge_cache
,
bb
,
EXIT_BLOCK_PTR
,
EDGE_ABNORMAL
|
EDGE_ABNORMAL_CALL
);
EDGE_ABNORMAL
|
EDGE_ABNORMAL_CALL
);
...
@@ -420,9 +415,7 @@ make_edges (label_value_list, min, max, update_p)
...
@@ -420,9 +415,7 @@ make_edges (label_value_list, min, max, update_p)
/* If this is a CALL_INSN, then mark it as reaching the active EH
/* If this is a CALL_INSN, then mark it as reaching the active EH
handler for this CALL_INSN. If we're handling non-call
handler for this CALL_INSN. If we're handling non-call
exceptions then any insn can reach any of the active handlers.
exceptions then any insn can reach any of the active handlers.
Also mark the CALL_INSN as reaching any nonlocal goto handler. */
Also mark the CALL_INSN as reaching any nonlocal goto handler. */
else
if
(
code
==
CALL_INSN
||
flag_non_call_exceptions
)
else
if
(
code
==
CALL_INSN
||
flag_non_call_exceptions
)
{
{
/* Add any appropriate EH edges. */
/* Add any appropriate EH edges. */
...
@@ -432,14 +425,15 @@ make_edges (label_value_list, min, max, update_p)
...
@@ -432,14 +425,15 @@ make_edges (label_value_list, min, max, update_p)
{
{
/* ??? This could be made smarter: in some cases it's possible
/* ??? This could be made smarter: in some cases it's possible
to tell that certain calls will not do a nonlocal goto.
to tell that certain calls will not do a nonlocal goto.
For example, if the nested functions that do the nonlocal
For example, if the nested functions that do the nonlocal
gotos do not have their addresses taken, then only calls to
gotos do not have their addresses taken, then only calls to
those functions or to other nested functions that use them
those functions or to other nested functions that use them
could possibly do nonlocal gotos. */
could possibly do nonlocal gotos. */
/* We do know that a REG_EH_REGION note with a value less
/* We do know that a REG_EH_REGION note with a value less
than 0 is guaranteed not to perform a non-local goto. */
than 0 is guaranteed not to perform a non-local goto. */
rtx
note
=
find_reg_note
(
insn
,
REG_EH_REGION
,
NULL_RTX
);
rtx
note
=
find_reg_note
(
insn
,
REG_EH_REGION
,
NULL_RTX
);
if
(
!
note
||
INTVAL
(
XEXP
(
note
,
0
))
>=
0
)
if
(
!
note
||
INTVAL
(
XEXP
(
note
,
0
))
>=
0
)
for
(
x
=
nonlocal_goto_handler_labels
;
x
;
x
=
XEXP
(
x
,
1
))
for
(
x
=
nonlocal_goto_handler_labels
;
x
;
x
=
XEXP
(
x
,
1
))
make_label_edge
(
edge_cache
,
bb
,
XEXP
(
x
,
0
),
make_label_edge
(
edge_cache
,
bb
,
XEXP
(
x
,
0
),
...
@@ -457,7 +451,8 @@ make_edges (label_value_list, min, max, update_p)
...
@@ -457,7 +451,8 @@ make_edges (label_value_list, min, max, update_p)
if
(
GET_CODE
(
tmp
)
==
NOTE
)
if
(
GET_CODE
(
tmp
)
==
NOTE
)
tmp
=
next_nonnote_insn
(
tmp
);
tmp
=
next_nonnote_insn
(
tmp
);
if
(
force_fallthru
||
insn
==
tmp
)
if
(
force_fallthru
||
insn
==
tmp
)
cached_make_edge
(
edge_cache
,
bb
,
BASIC_BLOCK
(
i
+
1
),
EDGE_FALLTHRU
);
cached_make_edge
(
edge_cache
,
bb
,
BASIC_BLOCK
(
i
+
1
),
EDGE_FALLTHRU
);
}
}
}
}
...
@@ -501,12 +496,14 @@ find_basic_blocks_1 (f)
...
@@ -501,12 +496,14 @@ find_basic_blocks_1 (f)
head
=
end
=
NULL_RTX
;
head
=
end
=
NULL_RTX
;
bb_note
=
NULL_RTX
;
bb_note
=
NULL_RTX
;
}
}
if
(
inside_basic_block_p
(
insn
))
if
(
inside_basic_block_p
(
insn
))
{
{
if
(
head
==
NULL_RTX
)
if
(
head
==
NULL_RTX
)
head
=
insn
;
head
=
insn
;
end
=
insn
;
end
=
insn
;
}
}
if
(
head
&&
control_flow_insn_p
(
insn
))
if
(
head
&&
control_flow_insn_p
(
insn
))
{
{
create_basic_block_structure
(
i
++
,
head
,
end
,
bb_note
);
create_basic_block_structure
(
i
++
,
head
,
end
,
bb_note
);
...
@@ -676,14 +673,10 @@ find_basic_blocks (f, nregs, file)
...
@@ -676,14 +673,10 @@ find_basic_blocks (f, nregs, file)
}
}
/* State of basic block as seen by find_sub_basic_blocks. */
/* State of basic block as seen by find_sub_basic_blocks. */
enum
state
enum
state
{
BLOCK_NEW
=
0
,
BLOCK_ORIGINAL
,
BLOCK_TO_SPLIT
};
{
BLOCK_NEW
=
0
,
#define STATE(BB) (enum state) ((size_t) (BB)->aux)
BLOCK_ORIGINAL
,
#define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
BLOCK_TO_SPLIT
};
#define STATE(bb) (enum state)(size_t)(bb)->aux
#define SET_STATE(bb, state) (bb)->aux = (void *) (size_t) (state)
/* Scan basic block BB for possible BB boundaries inside the block
/* Scan basic block BB for possible BB boundaries inside the block
and create new basic blocks in the progress. */
and create new basic blocks in the progress. */
...
@@ -714,12 +707,14 @@ find_bb_boundaries (bb)
...
@@ -714,12 +707,14 @@ find_bb_boundaries (bb)
fallthru
=
split_block
(
bb
,
PREV_INSN
(
insn
));
fallthru
=
split_block
(
bb
,
PREV_INSN
(
insn
));
if
(
flow_transfer_insn
)
if
(
flow_transfer_insn
)
bb
->
end
=
flow_transfer_insn
;
bb
->
end
=
flow_transfer_insn
;
bb
=
fallthru
->
dest
;
bb
=
fallthru
->
dest
;
remove_edge
(
fallthru
);
remove_edge
(
fallthru
);
flow_transfer_insn
=
NULL_RTX
;
flow_transfer_insn
=
NULL_RTX
;
if
(
LABEL_ALTERNATE_NAME
(
insn
))
if
(
LABEL_ALTERNATE_NAME
(
insn
))
make_edge
(
ENTRY_BLOCK_PTR
,
bb
,
0
);
make_edge
(
ENTRY_BLOCK_PTR
,
bb
,
0
);
}
}
/* In case we've previously seen an insn that effects a control
/* In case we've previously seen an insn that effects a control
flow transfer, split the block. */
flow transfer, split the block. */
if
(
flow_transfer_insn
&&
inside_basic_block_p
(
insn
))
if
(
flow_transfer_insn
&&
inside_basic_block_p
(
insn
))
...
@@ -730,6 +725,7 @@ find_bb_boundaries (bb)
...
@@ -730,6 +725,7 @@ find_bb_boundaries (bb)
remove_edge
(
fallthru
);
remove_edge
(
fallthru
);
flow_transfer_insn
=
NULL_RTX
;
flow_transfer_insn
=
NULL_RTX
;
}
}
if
(
control_flow_insn_p
(
insn
))
if
(
control_flow_insn_p
(
insn
))
flow_transfer_insn
=
insn
;
flow_transfer_insn
=
insn
;
if
(
insn
==
end
)
if
(
insn
==
end
)
...
@@ -757,6 +753,7 @@ compute_outgoing_frequencies (b)
...
@@ -757,6 +753,7 @@ compute_outgoing_frequencies (b)
basic_block
b
;
basic_block
b
;
{
{
edge
e
,
f
;
edge
e
,
f
;
if
(
b
->
succ
&&
b
->
succ
->
succ_next
&&
!
b
->
succ
->
succ_next
->
succ_next
)
if
(
b
->
succ
&&
b
->
succ
->
succ_next
&&
!
b
->
succ
->
succ_next
->
succ_next
)
{
{
rtx
note
=
find_reg_note
(
b
->
end
,
REG_BR_PROB
,
NULL
);
rtx
note
=
find_reg_note
(
b
->
end
,
REG_BR_PROB
,
NULL
);
...
@@ -764,8 +761,10 @@ compute_outgoing_frequencies (b)
...
@@ -764,8 +761,10 @@ compute_outgoing_frequencies (b)
if
(
!
note
)
if
(
!
note
)
return
;
return
;
probability
=
INTVAL
(
XEXP
(
find_reg_note
(
b
->
end
,
probability
=
INTVAL
(
XEXP
(
find_reg_note
(
b
->
end
,
REG_BR_PROB
,
NULL
),
0
));
REG_BR_PROB
,
NULL
),
0
));
e
=
BRANCH_EDGE
(
b
);
e
=
BRANCH_EDGE
(
b
);
e
->
probability
=
probability
;
e
->
probability
=
probability
;
e
->
count
=
((
b
->
count
*
probability
+
REG_BR_PROB_BASE
/
2
)
e
->
count
=
((
b
->
count
*
probability
+
REG_BR_PROB_BASE
/
2
)
...
@@ -774,6 +773,7 @@ compute_outgoing_frequencies (b)
...
@@ -774,6 +773,7 @@ compute_outgoing_frequencies (b)
f
->
probability
=
REG_BR_PROB_BASE
-
probability
;
f
->
probability
=
REG_BR_PROB_BASE
-
probability
;
f
->
count
=
b
->
count
-
e
->
count
;
f
->
count
=
b
->
count
-
e
->
count
;
}
}
if
(
b
->
succ
&&
!
b
->
succ
->
succ_next
)
if
(
b
->
succ
&&
!
b
->
succ
->
succ_next
)
{
{
e
=
b
->
succ
;
e
=
b
->
succ
;
...
@@ -797,15 +797,13 @@ find_many_sub_basic_blocks (blocks)
...
@@ -797,15 +797,13 @@ find_many_sub_basic_blocks (blocks)
TEST_BIT
(
blocks
,
i
)
?
BLOCK_TO_SPLIT
:
BLOCK_ORIGINAL
);
TEST_BIT
(
blocks
,
i
)
?
BLOCK_TO_SPLIT
:
BLOCK_ORIGINAL
);
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
{
if
(
STATE
(
BASIC_BLOCK
(
i
))
==
BLOCK_TO_SPLIT
)
basic_block
bb
=
BASIC_BLOCK
(
i
);
find_bb_boundaries
(
BASIC_BLOCK
(
i
));
if
(
STATE
(
bb
)
==
BLOCK_TO_SPLIT
)
find_bb_boundaries
(
bb
);
}
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
if
(
STATE
(
BASIC_BLOCK
(
i
))
!=
BLOCK_ORIGINAL
)
if
(
STATE
(
BASIC_BLOCK
(
i
))
!=
BLOCK_ORIGINAL
)
break
;
break
;
min
=
max
=
i
;
min
=
max
=
i
;
for
(;
i
<
n_basic_blocks
;
i
++
)
for
(;
i
<
n_basic_blocks
;
i
++
)
if
(
STATE
(
BASIC_BLOCK
(
i
))
!=
BLOCK_ORIGINAL
)
if
(
STATE
(
BASIC_BLOCK
(
i
))
!=
BLOCK_ORIGINAL
)
...
@@ -834,8 +832,10 @@ find_many_sub_basic_blocks (blocks)
...
@@ -834,8 +832,10 @@ find_many_sub_basic_blocks (blocks)
b
->
frequency
+=
EDGE_FREQUENCY
(
e
);
b
->
frequency
+=
EDGE_FREQUENCY
(
e
);
}
}
}
}
compute_outgoing_frequencies
(
b
);
compute_outgoing_frequencies
(
b
);
}
}
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
n_basic_blocks
;
i
++
)
SET_STATE
(
BASIC_BLOCK
(
i
),
0
);
SET_STATE
(
BASIC_BLOCK
(
i
),
0
);
}
}
...
@@ -876,6 +876,7 @@ find_sub_basic_blocks (bb)
...
@@ -876,6 +876,7 @@ find_sub_basic_blocks (bb)
b
->
frequency
+=
EDGE_FREQUENCY
(
e
);
b
->
frequency
+=
EDGE_FREQUENCY
(
e
);
}
}
}
}
compute_outgoing_frequencies
(
b
);
compute_outgoing_frequencies
(
b
);
}
}
}
}
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