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
Show 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>
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
* modulo-sched.c (generate_reg_moves): Skip instructions that
do not set a register and verify no regmoves are created for
do not set a register and verify no regmoves are created for
!single_set instructions.
!single_set instructions.
gcc/ddg.c
View file @
d8edf83d
...
@@ -145,6 +145,27 @@ mem_access_insn_p (rtx insn)
...
@@ -145,6 +145,27 @@ mem_access_insn_p (rtx insn)
return
rtx_mem_access_p
(
PATTERN
(
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
/* Computes the dependence parameters (latency, distance etc.), creates
a ddg_edge and adds it to the given DDG. */
a ddg_edge and adds it to the given DDG. */
static
void
static
void
...
@@ -173,10 +194,15 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
...
@@ -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
compensate for that by generating reg-moves based on the life-range
analysis. The anti-deps that will be deleted are the ones which
analysis. The anti-deps that will be deleted are the ones which
have true-deps edges in the opposite direction (in other words
have true-deps edges in the opposite direction (in other words
the kernel has only one def of the relevant register). TODO:
the kernel has only one def of the relevant register).
support the removal of all anti-deps edges, i.e. including those
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. */
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
;
rtx
set
;
...
@@ -302,10 +328,14 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
...
@@ -302,10 +328,14 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
gcc_assert
(
first_def_node
);
gcc_assert
(
first_def_node
);
/* Always create the edge if the use node is a branch in
/* 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
)
if
(
DF_REF_ID
(
last_def
)
!=
DF_REF_ID
(
first_def
)
||
!
flag_modulo_sched_allow_regmoves
||
!
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
,
create_ddg_dep_no_link
(
g
,
use_node
,
first_def_node
,
ANTI_DEP
,
REG_DEP
,
1
);
REG_DEP
,
1
);
...
...
gcc/ddg.h
View file @
d8edf83d
...
@@ -186,4 +186,6 @@ void free_ddg_all_sccs (ddg_all_sccs_ptr);
...
@@ -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
find_nodes_on_paths
(
sbitmap
result
,
ddg_ptr
,
sbitmap
from
,
sbitmap
to
);
int
longest_simple_path
(
ddg_ptr
,
int
from
,
int
to
,
sbitmap
via
);
int
longest_simple_path
(
ddg_ptr
,
int
from
,
int
to
,
sbitmap
via
);
bool
autoinc_var_is_used_p
(
rtx
,
rtx
);
#endif
/* GCC_DDG_H */
#endif
/* GCC_DDG_H */
gcc/modulo-sched.c
View file @
d8edf83d
...
@@ -506,6 +506,10 @@ generate_reg_moves (partial_schedule_ptr ps, bool rescan)
...
@@ -506,6 +506,10 @@ generate_reg_moves (partial_schedule_ptr ps, bool rescan)
we assume no regmoves are generated as the doloop
we assume no regmoves are generated as the doloop
instructions are tied to the branch with an edge. */
instructions are tied to the branch with an edge. */
gcc_assert
(
set
);
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
);
nreg_moves
=
MAX
(
nreg_moves
,
nreg_moves4e
);
...
@@ -1281,12 +1285,10 @@ sms_schedule (void)
...
@@ -1281,12 +1285,10 @@ sms_schedule (void)
continue
;
continue
;
}
}
/* Don't handle BBs with calls or barriers or auto-increment insns
/* Don't handle BBs with calls or barriers
(to avoid creating invalid reg-moves for the auto-increment insns),
or !single_set with the exception of instructions that include
or !single_set with the exception of instructions that include
count_reg---these instructions are part of the control part
count_reg---these instructions are part of the control part
that do-loop recognizes.
that do-loop recognizes.
??? Should handle auto-increment insns.
??? Should handle insns defining subregs. */
??? Should handle insns defining subregs. */
for
(
insn
=
head
;
insn
!=
NEXT_INSN
(
tail
);
insn
=
NEXT_INSN
(
insn
))
for
(
insn
=
head
;
insn
!=
NEXT_INSN
(
tail
);
insn
=
NEXT_INSN
(
insn
))
{
{
...
@@ -1297,7 +1299,6 @@ sms_schedule (void)
...
@@ -1297,7 +1299,6 @@ sms_schedule (void)
||
(
NONDEBUG_INSN_P
(
insn
)
&&
!
JUMP_P
(
insn
)
||
(
NONDEBUG_INSN_P
(
insn
)
&&
!
JUMP_P
(
insn
)
&&
!
single_set
(
insn
)
&&
GET_CODE
(
PATTERN
(
insn
))
!=
USE
&&
!
single_set
(
insn
)
&&
GET_CODE
(
PATTERN
(
insn
))
!=
USE
&&
!
reg_mentioned_p
(
count_reg
,
insn
))
&&
!
reg_mentioned_p
(
count_reg
,
insn
))
||
(
FIND_REG_INC_NOTE
(
insn
,
NULL_RTX
)
!=
0
)
||
(
INSN_P
(
insn
)
&&
(
set
=
single_set
(
insn
))
||
(
INSN_P
(
insn
)
&&
(
set
=
single_set
(
insn
))
&&
GET_CODE
(
SET_DEST
(
set
))
==
SUBREG
))
&&
GET_CODE
(
SET_DEST
(
set
))
==
SUBREG
))
break
;
break
;
...
@@ -1311,8 +1312,6 @@ sms_schedule (void)
...
@@ -1311,8 +1312,6 @@ sms_schedule (void)
fprintf
(
dump_file
,
"SMS loop-with-call
\n
"
);
fprintf
(
dump_file
,
"SMS loop-with-call
\n
"
);
else
if
(
BARRIER_P
(
insn
))
else
if
(
BARRIER_P
(
insn
))
fprintf
(
dump_file
,
"SMS loop-with-barrier
\n
"
);
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
)
else
if
((
NONDEBUG_INSN_P
(
insn
)
&&
!
JUMP_P
(
insn
)
&&
!
single_set
(
insn
)
&&
GET_CODE
(
PATTERN
(
insn
))
!=
USE
))
&&
!
single_set
(
insn
)
&&
GET_CODE
(
PATTERN
(
insn
))
!=
USE
))
fprintf
(
dump_file
,
"SMS loop-with-not-single-set
\n
"
);
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>
2011-09-30 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
* gcc.target/arm/pr50099.c: New test.
* 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