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
112333d3
Commit
112333d3
authored
Mar 28, 2001
by
Bernd Schmidt
Committed by
Bernd Schmidt
Mar 28, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix missing barrier problem
From-SVN: r40932
parent
669ff14e
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
128 additions
and
48 deletions
+128
-48
gcc/ChangeLog
+9
-0
gcc/config/ia64/ia64.c
+119
-48
No files found.
gcc/ChangeLog
View file @
112333d3
...
...
@@ -2,6 +2,15 @@
*
cselib
.
c
(
hash_rtx
)
:
Don
'
t
do
tail
recursion
elimination
by
hand
.
*
config
/
ia64
/
ia64
.
c
(
update_set_flags
)
:
New
function
,
broken
out
of
rtx_needs_barrier
.
(
set_src_needs_barrier
)
:
Likewise
.
(
rtx_needs_barrier
)
:
For
SET
case
,
use
these
two
functions
.
Rework
PARALLEL
case
to
handle
all
inputs
before
all
outputs
.
(
emit_insn_group_barriers
):
Call
init_insn_group_barriers
only
if
we
saw
a
label
and
no
stop
bit
since
then
.
(
maybe_rotate
,
process_epilogue
):
Add
prototypes
.
2001
-
03
-
28
Richard
Henderson
<
rth
@redhat
.
com
>
*
config
/
rs6000
/
rs6000
.
h
(
EPILOGUE_USES
)
:
Use
TARGET_AIX
,
...
...
gcc/config/ia64/ia64.c
View file @
112333d3
...
...
@@ -118,6 +118,7 @@ static void ia64_free_machine_status PARAMS ((struct function *));
static
void
emit_insn_group_barriers
PARAMS
((
FILE
*
,
rtx
));
static
void
emit_all_insn_group_barriers
PARAMS
((
FILE
*
,
rtx
));
static
void
emit_predicate_relation_info
PARAMS
((
void
));
static
void
process_epilogue
PARAMS
((
void
));
static
int
process_set
PARAMS
((
FILE
*
,
rtx
));
static
rtx
ia64_expand_fetch_and_op
PARAMS
((
optab
,
enum
machine_mode
,
...
...
@@ -3826,6 +3827,8 @@ static void rws_update PARAMS ((struct reg_write_state *, int,
struct
reg_flags
,
int
));
static
int
rws_access_regno
PARAMS
((
int
,
struct
reg_flags
,
int
));
static
int
rws_access_reg
PARAMS
((
rtx
,
struct
reg_flags
,
int
));
static
void
update_set_flags
PARAMS
((
rtx
,
struct
reg_flags
*
,
int
*
,
rtx
*
));
static
int
set_src_needs_barrier
PARAMS
((
rtx
,
struct
reg_flags
,
int
,
rtx
));
static
int
rtx_needs_barrier
PARAMS
((
rtx
,
struct
reg_flags
,
int
));
static
void
init_insn_group_barriers
PARAMS
((
void
));
static
int
group_barrier_needed_p
PARAMS
((
rtx
));
...
...
@@ -3994,62 +3997,42 @@ rws_access_reg (reg, flags, pred)
}
}
/* Handle an access to rtx X of type FLAGS using predicate register PRED.
Return 1 is this access creates a dependency with an earlier instruction
in the same group. */
/* Examine X, which is a SET rtx, and update the flags, the predicate, and
the condition, stored in *PFLAGS, *PPRED and *PCOND. */
static
int
rtx_needs_barrier
(
x
,
flags
,
pre
d
)
static
void
update_set_flags
(
x
,
pflags
,
ppred
,
pcon
d
)
rtx
x
;
struct
reg_flags
flags
;
int
pred
;
struct
reg_flags
*
pflags
;
int
*
ppred
;
rtx
*
pcond
;
{
int
i
,
j
;
int
is_complemented
=
0
;
int
need_barrier
=
0
;
const
char
*
format_ptr
;
struct
reg_flags
new_flags
;
rtx
src
,
dst
;
rtx
cond
=
0
;
rtx
src
=
SET_SRC
(
x
);
if
(
!
x
)
return
0
;
new_flags
=
flags
;
*
pcond
=
0
;
switch
(
GET_CODE
(
x
))
{
case
SET
:
src
=
SET_SRC
(
x
);
switch
(
GET_CODE
(
src
))
{
case
CALL
:
/* We don't need to worry about the result registers that
get written by subroutine call. */
need_barrier
=
rtx_needs_barrier
(
src
,
flags
,
pred
);
return
need_barrier
;
return
;
case
IF_THEN_ELSE
:
if
(
SET_DEST
(
x
)
==
pc_rtx
)
{
/* X is a conditional branch. */
/* ??? This seems redundant, as the caller sets this bit for
all JUMP_INSNs. */
new_flags
.
is_branch
=
1
;
need_barrier
=
rtx_needs_barrier
(
src
,
new_flags
,
pred
);
return
need_barrier
;
}
return
;
else
{
int
is_complemented
=
0
;
/* X is a conditional move. */
cond
=
XEXP
(
src
,
0
);
rtx
cond
=
XEXP
(
src
,
0
);
if
(
GET_CODE
(
cond
)
==
EQ
)
is_complemented
=
1
;
cond
=
XEXP
(
cond
,
0
);
if
(
GET_CODE
(
cond
)
!=
REG
&&
REGNO_REG_CLASS
(
REGNO
(
cond
))
!=
PR_REGS
)
abort
();
*
pcond
=
cond
;
if
(
XEXP
(
src
,
1
)
==
SET_DEST
(
x
)
||
XEXP
(
src
,
2
)
==
SET_DEST
(
x
))
{
...
...
@@ -4060,9 +4043,9 @@ rtx_needs_barrier (x, flags, pred)
if
(
XEXP
(
src
,
1
)
==
SET_DEST
(
x
))
is_complemented
=
!
is_complemented
;
pred
=
REGNO
(
cond
);
*
p
pred
=
REGNO
(
cond
);
if
(
is_complemented
)
++
pred
;
++*
p
pred
;
}
/* ??? If this is a conditional write to the dest, then this
...
...
@@ -4078,21 +4061,52 @@ rtx_needs_barrier (x, flags, pred)
default
:
if
(
GET_RTX_CLASS
(
GET_CODE
(
src
))
==
'<'
&&
GET_MODE_CLASS
(
GET_MODE
(
XEXP
(
src
,
0
)))
==
MODE_FLOAT
)
/* Set new_flags.
is_fp to 1 so that we know we're dealing
/* Set pflags->
is_fp to 1 so that we know we're dealing
with a floating point comparison when processing the
destination of the SET. */
new_flags
.
is_fp
=
1
;
pflags
->
is_fp
=
1
;
/* Discover if this is a parallel comparison. We only handle
and.orcm and or.andcm at present, since we must retain a
strict inverse on the predicate pair. */
else
if
(
GET_CODE
(
src
)
==
AND
)
new_flags
.
is_and
=
flags
.
is_and
=
1
;
pflags
->
is_and
=
1
;
else
if
(
GET_CODE
(
src
)
==
IOR
)
new_flags
.
is_or
=
flags
.
is_or
=
1
;
pflags
->
is_or
=
1
;
break
;
}
}
/* Subroutine of rtx_needs_barrier; this function determines whether the
source of a given SET rtx found in X needs a barrier. FLAGS and PRED
are as in rtx_needs_barrier. COND is an rtx that holds the condition
for this insn. */
static
int
set_src_needs_barrier
(
x
,
flags
,
pred
,
cond
)
rtx
x
;
struct
reg_flags
flags
;
int
pred
;
rtx
cond
;
{
int
need_barrier
=
0
;
rtx
dst
;
rtx
src
=
SET_SRC
(
x
);
if
(
GET_CODE
(
src
)
==
CALL
)
/* We don't need to worry about the result registers that
get written by subroutine call. */
return
rtx_needs_barrier
(
src
,
flags
,
pred
);
else
if
(
SET_DEST
(
x
)
==
pc_rtx
)
{
/* X is a conditional branch. */
/* ??? This seems redundant, as the caller sets this bit for
all JUMP_INSNs. */
flags
.
is_branch
=
1
;
return
rtx_needs_barrier
(
src
,
flags
,
pred
);
}
need_barrier
=
rtx_needs_barrier
(
src
,
flags
,
pred
);
/* This instruction unconditionally uses a predicate register. */
...
...
@@ -4106,8 +4120,41 @@ rtx_needs_barrier (x, flags, pred)
need_barrier
|=
rtx_needs_barrier
(
XEXP
(
dst
,
2
),
flags
,
pred
);
dst
=
XEXP
(
dst
,
0
);
}
return
need_barrier
;
}
/* Handle an access to rtx X of type FLAGS using predicate register PRED.
Return 1 is this access creates a dependency with an earlier instruction
in the same group. */
static
int
rtx_needs_barrier
(
x
,
flags
,
pred
)
rtx
x
;
struct
reg_flags
flags
;
int
pred
;
{
int
i
,
j
;
int
is_complemented
=
0
;
int
need_barrier
=
0
;
const
char
*
format_ptr
;
struct
reg_flags
new_flags
;
rtx
cond
=
0
;
if
(
!
x
)
return
0
;
new_flags
=
flags
;
switch
(
GET_CODE
(
x
))
{
case
SET
:
update_set_flags
(
x
,
&
new_flags
,
&
pred
,
&
cond
);
need_barrier
=
set_src_needs_barrier
(
x
,
new_flags
,
pred
,
cond
);
if
(
GET_CODE
(
SET_SRC
(
x
))
!=
CALL
)
{
new_flags
.
is_write
=
1
;
need_barrier
|=
rtx_needs_barrier
(
dst
,
new_flags
,
pred
);
need_barrier
|=
rtx_needs_barrier
(
SET_DEST
(
x
),
new_flags
,
pred
);
}
break
;
case
CALL
:
...
...
@@ -4180,8 +4227,33 @@ rtx_needs_barrier (x, flags, pred)
case
PARALLEL
:
for
(
i
=
XVECLEN
(
x
,
0
)
-
1
;
i
>=
0
;
--
i
)
if
(
rtx_needs_barrier
(
XVECEXP
(
x
,
0
,
i
),
flags
,
pred
))
need_barrier
=
1
;
{
rtx
pat
=
XVECEXP
(
x
,
0
,
i
);
if
(
GET_CODE
(
pat
)
==
SET
)
{
update_set_flags
(
pat
,
&
new_flags
,
&
pred
,
&
cond
);
need_barrier
|=
set_src_needs_barrier
(
pat
,
new_flags
,
pred
,
cond
);
}
else
if
(
GET_CODE
(
pat
)
==
USE
||
GET_CODE
(
pat
)
==
CALL
)
need_barrier
|=
rtx_needs_barrier
(
pat
,
flags
,
pred
);
else
if
(
GET_CODE
(
pat
)
!=
CLOBBER
&&
GET_CODE
(
pat
)
!=
RETURN
)
abort
();
}
for
(
i
=
XVECLEN
(
x
,
0
)
-
1
;
i
>=
0
;
--
i
)
{
rtx
pat
=
XVECEXP
(
x
,
0
,
i
);
if
(
GET_CODE
(
pat
)
==
SET
)
{
if
(
GET_CODE
(
SET_SRC
(
pat
))
!=
CALL
)
{
new_flags
.
is_write
=
1
;
need_barrier
|=
rtx_needs_barrier
(
SET_DEST
(
pat
),
new_flags
,
pred
);
}
}
else
if
(
GET_CODE
(
pat
)
==
CLOBBER
)
need_barrier
|=
rtx_needs_barrier
(
pat
,
flags
,
pred
);
}
break
;
case
SUBREG
:
...
...
@@ -4532,12 +4604,13 @@ emit_insn_group_barriers (dump, insns)
INSN_UID
(
last_label
));
emit_insn_before
(
gen_insn_group_barrier
(
GEN_INT
(
3
)),
last_label
);
insn
=
last_label
;
}
init_insn_group_barriers
();
last_label
=
0
;
}
}
}
}
}
/* Like emit_insn_group_barriers, but run if no final scheduling pass was run.
...
...
@@ -4783,9 +4856,7 @@ static int itanium_split_issue PARAMS ((const struct ia64_packet *, int));
static
rtx
ia64_single_set
PARAMS
((
rtx
));
static
int
insn_matches_slot
PARAMS
((
const
struct
ia64_packet
*
,
enum
attr_type
,
int
,
rtx
));
static
void
ia64_emit_insn_before
PARAMS
((
rtx
,
rtx
));
#if 0
static rtx gen_nop_type PARAMS ((enum attr_type));
#endif
static
void
maybe_rotate
PARAMS
((
FILE
*
));
static
void
finish_last_head
PARAMS
((
FILE
*
,
int
));
static
void
rotate_one_bundle
PARAMS
((
FILE
*
));
static
void
rotate_two_bundles
PARAMS
((
FILE
*
));
...
...
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