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
d8edf83d
Commit
d8edf83d
authored
Sep 30, 2011
by
Revital Eres
Committed by
Revital Eres
Sep 30, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SMS: Support instructions with REG_INC_NOTE
From-SVN: r179381
parent
442b891d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
174 additions
and
11 deletions
+174
-11
gcc/ChangeLog
+9
-0
gcc/ddg.c
+35
-5
gcc/ddg.h
+2
-0
gcc/modulo-sched.c
+5
-6
gcc/testsuite/ChangeLog
+4
-0
gcc/testsuite/gcc.dg/sms-10.c
+119
-0
No files found.
gcc/ChangeLog
View file @
d8edf83d
2011-09-30 Revital Eres <revital.eres@linaro.org>
* ddg.c (autoinc_var_is_used_p): New function.
(create_ddg_dep_from_intra_loop_link,
add_cross_iteration_register_deps): Call it.
* ddg.h (autoinc_var_is_used_p): Declare.
* modulo-sched.c (generate_reg_moves): Call autoinc_var_is_used_p.
(sms_schedule): Handle instructions with REG_INC.
2011-09-30 Revital Eres <revital.eres@linaro.org>
* modulo-sched.c (generate_reg_moves): Skip instructions that
do not set a register and verify no regmoves are created for
!single_set instructions.
gcc/ddg.c
View file @
d8edf83d
...
...
@@ -145,6 +145,27 @@ mem_access_insn_p (rtx insn)
return
rtx_mem_access_p
(
PATTERN
(
insn
));
}
/* Return true if DEF_INSN contains address being auto-inc or auto-dec
which is used in USE_INSN. Otherwise return false. The result is
being used to decide whether to remove the edge between def_insn and
use_insn when -fmodulo-sched-allow-regmoves is set. This function
doesn't need to consider the specific address register; no reg_moves
will be allowed for any life range defined by def_insn and used
by use_insn, if use_insn uses an address register auto-inc'ed by
def_insn. */
bool
autoinc_var_is_used_p
(
rtx
def_insn
,
rtx
use_insn
)
{
rtx
note
;
for
(
note
=
REG_NOTES
(
def_insn
);
note
;
note
=
XEXP
(
note
,
1
))
if
(
REG_NOTE_KIND
(
note
)
==
REG_INC
&&
reg_referenced_p
(
XEXP
(
note
,
0
),
PATTERN
(
use_insn
)))
return
true
;
return
false
;
}
/* Computes the dependence parameters (latency, distance etc.), creates
a ddg_edge and adds it to the given DDG. */
static
void
...
...
@@ -173,10 +194,15 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
compensate for that by generating reg-moves based on the life-range
analysis. The anti-deps that will be deleted are the ones which
have true-deps edges in the opposite direction (in other words
the kernel has only one def of the relevant register). TODO:
support the removal of all anti-deps edges, i.e. including those
the kernel has only one def of the relevant register).
If the address that is being auto-inc or auto-dec in DEST_NODE
is used in SRC_NODE then do not remove the edge to make sure
reg-moves will not be created for this address.
TODO: support the removal of all anti-deps edges, i.e. including those
whose register has multiple defs in the loop. */
if
(
flag_modulo_sched_allow_regmoves
&&
(
t
==
ANTI_DEP
&&
dt
==
REG_DEP
))
if
(
flag_modulo_sched_allow_regmoves
&&
(
t
==
ANTI_DEP
&&
dt
==
REG_DEP
)
&&
!
autoinc_var_is_used_p
(
dest_node
->
insn
,
src_node
->
insn
))
{
rtx
set
;
...
...
@@ -302,10 +328,14 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
gcc_assert
(
first_def_node
);
/* Always create the edge if the use node is a branch in
order to prevent the creation of reg-moves. */
order to prevent the creation of reg-moves.
If the address that is being auto-inc or auto-dec in LAST_DEF
is used in USE_INSN then do not remove the edge to make sure
reg-moves will not be created for that address. */
if
(
DF_REF_ID
(
last_def
)
!=
DF_REF_ID
(
first_def
)
||
!
flag_modulo_sched_allow_regmoves
||
JUMP_P
(
use_node
->
insn
))
||
JUMP_P
(
use_node
->
insn
)
||
autoinc_var_is_used_p
(
DF_REF_INSN
(
last_def
),
use_insn
))
create_ddg_dep_no_link
(
g
,
use_node
,
first_def_node
,
ANTI_DEP
,
REG_DEP
,
1
);
...
...
gcc/ddg.h
View file @
d8edf83d
...
...
@@ -186,4 +186,6 @@ void free_ddg_all_sccs (ddg_all_sccs_ptr);
int
find_nodes_on_paths
(
sbitmap
result
,
ddg_ptr
,
sbitmap
from
,
sbitmap
to
);
int
longest_simple_path
(
ddg_ptr
,
int
from
,
int
to
,
sbitmap
via
);
bool
autoinc_var_is_used_p
(
rtx
,
rtx
);
#endif
/* GCC_DDG_H */
gcc/modulo-sched.c
View file @
d8edf83d
...
...
@@ -506,6 +506,10 @@ generate_reg_moves (partial_schedule_ptr ps, bool rescan)
we assume no regmoves are generated as the doloop
instructions are tied to the branch with an edge. */
gcc_assert
(
set
);
/* If the instruction contains auto-inc register then
validate that the regmov is being generated for the
target regsiter rather then the inc'ed register. */
gcc_assert
(
!
autoinc_var_is_used_p
(
u
->
insn
,
e
->
dest
->
insn
));
}
nreg_moves
=
MAX
(
nreg_moves
,
nreg_moves4e
);
...
...
@@ -1281,12 +1285,10 @@ sms_schedule (void)
continue
;
}
/* Don't handle BBs with calls or barriers or auto-increment insns
(to avoid creating invalid reg-moves for the auto-increment insns),
/* Don't handle BBs with calls or barriers
or !single_set with the exception of instructions that include
count_reg---these instructions are part of the control part
that do-loop recognizes.
??? Should handle auto-increment insns.
??? Should handle insns defining subregs. */
for
(
insn
=
head
;
insn
!=
NEXT_INSN
(
tail
);
insn
=
NEXT_INSN
(
insn
))
{
...
...
@@ -1297,7 +1299,6 @@ sms_schedule (void)
||
(
NONDEBUG_INSN_P
(
insn
)
&&
!
JUMP_P
(
insn
)
&&
!
single_set
(
insn
)
&&
GET_CODE
(
PATTERN
(
insn
))
!=
USE
&&
!
reg_mentioned_p
(
count_reg
,
insn
))
||
(
FIND_REG_INC_NOTE
(
insn
,
NULL_RTX
)
!=
0
)
||
(
INSN_P
(
insn
)
&&
(
set
=
single_set
(
insn
))
&&
GET_CODE
(
SET_DEST
(
set
))
==
SUBREG
))
break
;
...
...
@@ -1311,8 +1312,6 @@ sms_schedule (void)
fprintf
(
dump_file
,
"SMS loop-with-call
\n
"
);
else
if
(
BARRIER_P
(
insn
))
fprintf
(
dump_file
,
"SMS loop-with-barrier
\n
"
);
else
if
(
FIND_REG_INC_NOTE
(
insn
,
NULL_RTX
)
!=
0
)
fprintf
(
dump_file
,
"SMS reg inc
\n
"
);
else
if
((
NONDEBUG_INSN_P
(
insn
)
&&
!
JUMP_P
(
insn
)
&&
!
single_set
(
insn
)
&&
GET_CODE
(
PATTERN
(
insn
))
!=
USE
))
fprintf
(
dump_file
,
"SMS loop-with-not-single-set
\n
"
);
...
...
gcc/testsuite/ChangeLog
View file @
d8edf83d
2011-09-30 Revital Eres <revital.eres@linaro.org>
* gcc.dg/sms-10.c: New file
2011-09-30 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
* gcc.target/arm/pr50099.c: New test.
...
...
gcc/testsuite/gcc.dg/sms-10.c
0 → 100644
View file @
d8edf83d
/* { dg-do run } */
/* { dg-options "-O2 -fmodulo-sched -fmodulo-sched-allow-regmoves -fdump-rtl-sms" } */
typedef
__SIZE_TYPE__
size_t
;
extern
void
*
malloc
(
size_t
);
extern
void
free
(
void
*
);
extern
void
abort
(
void
);
struct
regstat_n_sets_and_refs_t
{
int
sets
;
int
refs
;
};
struct
regstat_n_sets_and_refs_t
*
regstat_n_sets_and_refs
;
struct
df_reg_info
{
unsigned
int
n_refs
;
};
struct
df_d
{
struct
df_reg_info
**
def_regs
;
struct
df_reg_info
**
use_regs
;
};
struct
df_d
*
df
;
static
inline
int
REG_N_SETS
(
int
regno
)
{
return
regstat_n_sets_and_refs
[
regno
].
sets
;
}
__attribute__
((
noinline
))
int
max_reg_num
(
void
)
{
return
100
;
}
__attribute__
((
noinline
))
void
regstat_init_n_sets_and_refs
(
void
)
{
unsigned
int
i
;
unsigned
int
max_regno
=
max_reg_num
();
for
(
i
=
0
;
i
<
max_regno
;
i
++
)
{
(
regstat_n_sets_and_refs
[
i
].
sets
=
(
df
->
def_regs
[(
i
)]
->
n_refs
));
(
regstat_n_sets_and_refs
[
i
].
refs
=
(
df
->
use_regs
[(
i
)]
->
n_refs
)
+
REG_N_SETS
(
i
));
}
}
int
a_sets
[
100
]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
85
,
86
,
87
,
88
,
89
,
90
,
91
,
92
,
93
,
94
,
95
,
96
,
97
,
98
,
99
};
int
a_refs
[
100
]
=
{
0
,
2
,
4
,
6
,
8
,
10
,
12
,
14
,
16
,
18
,
20
,
22
,
24
,
26
,
28
,
30
,
32
,
34
,
36
,
38
,
40
,
42
,
44
,
46
,
48
,
50
,
52
,
54
,
56
,
58
,
60
,
62
,
64
,
66
,
68
,
70
,
72
,
74
,
76
,
78
,
80
,
82
,
84
,
86
,
88
,
90
,
92
,
94
,
96
,
98
,
100
,
102
,
104
,
106
,
108
,
110
,
112
,
114
,
116
,
118
,
120
,
122
,
124
,
126
,
128
,
130
,
132
,
134
,
136
,
138
,
140
,
142
,
144
,
146
,
148
,
150
,
152
,
154
,
156
,
158
,
160
,
162
,
164
,
166
,
168
,
170
,
172
,
174
,
176
,
178
,
180
,
182
,
184
,
186
,
188
,
190
,
192
,
194
,
196
,
198
};
int
main
()
{
struct
df_reg_info
*
b
[
100
],
*
c
[
100
];
struct
df_d
df1
;
size_t
s
=
sizeof
(
struct
df_reg_info
);
struct
regstat_n_sets_and_refs_t
a
[
100
];
df
=
&
df1
;
regstat_n_sets_and_refs
=
a
;
int
i
;
for
(
i
=
0
;
i
<
100
;
i
++
)
{
b
[
i
]
=
(
struct
df_reg_info
*
)
malloc
(
s
);
b
[
i
]
->
n_refs
=
i
;
c
[
i
]
=
(
struct
df_reg_info
*
)
malloc
(
s
);
c
[
i
]
->
n_refs
=
i
;
}
df1
.
def_regs
=
b
;
df1
.
use_regs
=
c
;
regstat_init_n_sets_and_refs
();
for
(
i
=
0
;
i
<
100
;
i
++
)
if
((
a
[
i
].
sets
!=
a_sets
[
i
])
||
(
a
[
i
].
refs
!=
a_refs
[
i
]))
abort
();
for
(
i
=
0
;
i
<
100
;
i
++
)
{
free
(
b
[
i
]);
free
(
c
[
i
]);
}
return
0
;
}
/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */
/* { dg-final { cleanup-rtl-dump "sms" } } */
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