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
50b2e859
Commit
50b2e859
authored
Jun 22, 2010
by
Jan Hubicka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix version of patch from previous commit ;(
From-SVN: r161199
parent
c42bfef2
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
60 additions
and
34 deletions
+60
-34
gcc/df-core.c
+48
-28
gcc/df-problems.c
+8
-4
gcc/df.h
+4
-2
No files found.
gcc/df-core.c
View file @
50b2e859
...
...
@@ -851,12 +851,25 @@ struct rtl_opt_pass pass_df_finish =
The general data flow analysis engine.
----------------------------------------------------------------------------*/
/* Return time BB when it was visited for last time. */
#define BB_LAST_CHANGE_AGE(bb) ((ptrdiff_t)(bb)->aux)
/* Helper function for df_worklist_dataflow.
Propagate the dataflow forward.
Given a BB_INDEX, do the dataflow propagation
and set bits on for successors in PENDING
if the out set of the dataflow has changed. */
if the out set of the dataflow has changed.
AGE specify time when BB was visited last time.
AGE of 0 means we are visiting for first time and need to
compute transfer function to initialize datastructures.
Otherwise we re-do transfer function only if something change
while computing confluence functions.
We need to compute confluence only of basic block that are younger
then last visit of the BB.
Return true if BB info has changed. This is always the case
in the first visit. */
static
bool
df_worklist_propagate_forward
(
struct
dataflow
*
dataflow
,
...
...
@@ -864,7 +877,7 @@ df_worklist_propagate_forward (struct dataflow *dataflow,
unsigned
*
bbindex_to_postorder
,
bitmap
pending
,
sbitmap
considered
,
size
_t
age
)
ptrdiff
_t
age
)
{
edge
e
;
edge_iterator
ei
;
...
...
@@ -875,15 +888,12 @@ df_worklist_propagate_forward (struct dataflow *dataflow,
if
(
EDGE_COUNT
(
bb
->
preds
)
>
0
)
FOR_EACH_EDGE
(
e
,
ei
,
bb
->
preds
)
{
if
(
(
age
<=
(
size_t
)
e
->
src
->
aux
)
&&
TEST_BIT
(
considered
,
e
->
src
->
index
))
if
(
age
<=
BB_LAST_CHANGE_AGE
(
e
->
src
)
&&
TEST_BIT
(
considered
,
e
->
src
->
index
))
changed
|=
dataflow
->
problem
->
con_fun_n
(
e
);
}
else
if
(
dataflow
->
problem
->
con_fun_0
)
{
dataflow
->
problem
->
con_fun_0
(
bb
);
changed
=
true
;
}
dataflow
->
problem
->
con_fun_0
(
bb
);
if
(
changed
&&
dataflow
->
problem
->
trans_fun
(
bb_index
))
...
...
@@ -912,7 +922,7 @@ df_worklist_propagate_backward (struct dataflow *dataflow,
unsigned
*
bbindex_to_postorder
,
bitmap
pending
,
sbitmap
considered
,
size
_t
age
)
ptrdiff
_t
age
)
{
edge
e
;
edge_iterator
ei
;
...
...
@@ -923,15 +933,12 @@ df_worklist_propagate_backward (struct dataflow *dataflow,
if
(
EDGE_COUNT
(
bb
->
succs
)
>
0
)
FOR_EACH_EDGE
(
e
,
ei
,
bb
->
succs
)
{
if
(
(
age
<=
(
size_t
)
e
->
dest
->
aux
)
&&
TEST_BIT
(
considered
,
e
->
dest
->
index
))
if
(
age
<=
BB_LAST_CHANGE_AGE
(
e
->
dest
)
&&
TEST_BIT
(
considered
,
e
->
dest
->
index
))
changed
|=
dataflow
->
problem
->
con_fun_n
(
e
);
}
else
if
(
dataflow
->
problem
->
con_fun_0
)
{
dataflow
->
problem
->
con_fun_0
(
bb
);
changed
=
true
;
}
dataflow
->
problem
->
con_fun_0
(
bb
);
if
(
changed
&&
dataflow
->
problem
->
trans_fun
(
bb_index
))
...
...
@@ -950,10 +957,24 @@ df_worklist_propagate_backward (struct dataflow *dataflow,
return
false
;
}
DEF_VEC_I
(
size_t
);
DEF_VEC_ALLOC_I
(
size_t
,
heap
);
/* Main dataflow solver loop.
DATAFLOW is problem we are solving, PENDING is worklist of basic blocks we
need to visit.
BLOCK_IN_POSTORDER is array of size N_BLOCKS specifying postorder in BBs and
BBINDEX_TO_POSTORDER is array mapping back BB->index to postorder possition.
PENDING will be freed.
The worklists are bitmaps indexed by postorder positions.
The function implements standard algorithm for dataflow solving with two
worklists (we are processing WORKLIST and storing new BBs to visit in
PENDING).
/* This will free "pending". */
As an optimization we maintain ages when BB was changed (stored in bb->aux)
and when it was last visited (stored in last_visit_age). This avoids need
to re-do confluence function for edges to basic blocks whose source
did not change since destination was visited last time. */
static
void
df_worklist_dataflow_doublequeue
(
struct
dataflow
*
dataflow
,
...
...
@@ -966,14 +987,14 @@ df_worklist_dataflow_doublequeue (struct dataflow *dataflow,
enum
df_flow_dir
dir
=
dataflow
->
problem
->
dir
;
int
dcount
=
0
;
bitmap
worklist
=
BITMAP_ALLOC
(
&
df_bitmap_obstack
);
size_
t
age
=
0
;
in
t
age
=
0
;
bool
changed
;
VEC
(
size_t
,
heap
)
*
las
t_age
=
NULL
;
size_
t
prev_age
;
VEC
(
int
,
heap
)
*
last_visi
t_age
=
NULL
;
in
t
prev_age
;
basic_block
bb
;
int
i
;
VEC_safe_grow_cleared
(
size_t
,
heap
,
las
t_age
,
n_blocks
);
VEC_safe_grow_cleared
(
int
,
heap
,
last_visi
t_age
,
n_blocks
);
/* Double-queueing. Worklist is for the current iteration,
and pending is for the next. */
...
...
@@ -992,9 +1013,10 @@ df_worklist_dataflow_doublequeue (struct dataflow *dataflow,
unsigned
bb_index
;
dcount
++
;
bitmap_clear_bit
(
pending
,
index
);
bb_index
=
blocks_in_postorder
[
index
];
bb
=
BASIC_BLOCK
(
bb_index
);
prev_age
=
VEC_index
(
size_t
,
las
t_age
,
index
);
prev_age
=
VEC_index
(
int
,
last_visi
t_age
,
index
);
if
(
dir
==
DF_FORWARD
)
changed
=
df_worklist_propagate_forward
(
dataflow
,
bb_index
,
bbindex_to_postorder
,
...
...
@@ -1005,11 +1027,9 @@ df_worklist_dataflow_doublequeue (struct dataflow *dataflow,
bbindex_to_postorder
,
pending
,
considered
,
prev_age
);
age
++
;
VEC_replace
(
int
,
last_visit_age
,
index
,
++
age
)
;
if
(
changed
)
bb
->
aux
=
(
void
*
)
age
;
VEC_replace
(
size_t
,
last_age
,
index
,
age
);
age
++
;
bb
->
aux
=
(
void
*
)(
ptrdiff_t
)
age
;
}
bitmap_clear
(
worklist
);
}
...
...
@@ -1018,7 +1038,7 @@ df_worklist_dataflow_doublequeue (struct dataflow *dataflow,
BITMAP_FREE
(
worklist
);
BITMAP_FREE
(
pending
);
VEC_free
(
size_t
,
heap
,
las
t_age
);
VEC_free
(
int
,
heap
,
last_visi
t_age
);
/* Dump statistics. */
if
(
dump_file
)
...
...
gcc/df-problems.c
View file @
50b2e859
...
...
@@ -983,7 +983,8 @@ df_lr_confluence_n (edge e)
else
changed
=
bitmap_ior_into
(
op1
,
op2
);
return
bitmap_ior_into
(
op1
,
&
df
->
hardware_regs_used
)
||
changed
;
changed
|=
bitmap_ior_into
(
op1
,
&
df
->
hardware_regs_used
);
return
changed
;
}
...
...
@@ -2726,11 +2727,13 @@ df_byte_lr_confluence_n (edge e)
/* ??? Abnormal call edges ignored for the moment, as this gets
confused by sibling call edges, which crashes reg-stack. */
if
(
e
->
flags
&
EDGE_EH
)
changed
=
bitmap_ior_and_compl_into
(
op1
,
op2
,
&
problem_data
->
invalidated_by_call
);
changed
=
bitmap_ior_and_compl_into
(
op1
,
op2
,
&
problem_data
->
invalidated_by_call
);
else
changed
=
bitmap_ior_into
(
op1
,
op2
);
return
bitmap_ior_into
(
op1
,
&
problem_data
->
hardware_regs_used
)
||
changed
;
changed
|=
bitmap_ior_into
(
op1
,
&
problem_data
->
hardware_regs_used
);
return
changed
;
}
...
...
@@ -4440,7 +4443,8 @@ df_md_confluence_n (edge e)
return
false
;
if
(
e
->
flags
&
EDGE_EH
)
return
bitmap_ior_and_compl_into
(
op1
,
op2
,
regs_invalidated_by_call_regset
);
return
bitmap_ior_and_compl_into
(
op1
,
op2
,
regs_invalidated_by_call_regset
);
else
return
bitmap_ior_into
(
op1
,
op2
);
}
...
...
gcc/df.h
View file @
50b2e859
...
...
@@ -222,10 +222,12 @@ typedef void (*df_dataflow_function) (struct dataflow *, bitmap, int *, int);
/* Confluence operator for blocks with 0 out (or in) edges. */
typedef
void
(
*
df_confluence_function_0
)
(
basic_block
);
/* Confluence operator for blocks with 1 or more out (or in) edges. */
/* Confluence operator for blocks with 1 or more out (or in) edges.
Return true if BB input data has changed. */
typedef
bool
(
*
df_confluence_function_n
)
(
edge
);
/* Transfer function for blocks. */
/* Transfer function for blocks.
Return true if BB output data has changed. */
typedef
bool
(
*
df_transfer_function
)
(
int
);
/* Function to massage the information after the problem solving. */
...
...
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