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
fe08a886
Commit
fe08a886
authored
Dec 22, 2000
by
Bernd Schmidt
Committed by
Bernd Schmidt
Dec 22, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Renamer improvements.
From-SVN: r38463
parent
e6fe680d
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
184 additions
and
75 deletions
+184
-75
gcc/ChangeLog
+20
-0
gcc/regrename.c
+164
-75
No files found.
gcc/ChangeLog
View file @
fe08a886
2000-12-22 Bernd Schmidt <bernds@redhat.com>
* regrename.c (struct du_chain): New field "earlyclobber".
(enum scan_actions): Remove unused entry "note_reference".
(enum scan_actions_name): Likewise.
(note_sets, clear_dead_regs, merge_overlapping_regs): New static
functions.
(regrename_optimize): Use them to compute unavailable regs; get
rid of the more simpleminded code we used to have here.
Use a tick array to ensure registers are allocated in a more
round-robin way. Disable code that only optimizes registers
that were seen more than once.
(referenced_regs): Remove variable.
(scan_rtx_reg): New arg "earlyclobber". All callers changed.
Store its value in newly generated du_chain structures.
Add new du_chains at the end, not the start, of the list.
Don't handle the "note_reference" action.
(scan_rtx): New arg "earlyclobber". All callers changed.
(build_def_use): Lose code to keep track of referenced regs.
2000-12-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
2000-12-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Makefile.in (sched-deps.o, sched-rgn.o): Fix dependency typo.
* Makefile.in (sched-deps.o, sched-rgn.o): Fix dependency typo.
...
...
gcc/regrename.c
View file @
fe08a886
...
@@ -57,11 +57,11 @@ struct du_chain
...
@@ -57,11 +57,11 @@ struct du_chain
rtx
*
loc
;
rtx
*
loc
;
enum
reg_class
class
;
enum
reg_class
class
;
unsigned
int
need_caller_save_reg
:
1
;
unsigned
int
need_caller_save_reg
:
1
;
unsigned
int
earlyclobber
:
1
;
};
};
enum
scan_actions
enum
scan_actions
{
{
note_reference
,
terminate_all_read
,
terminate_all_read
,
terminate_overlapping_read
,
terminate_overlapping_read
,
terminate_write
,
terminate_write
,
...
@@ -72,7 +72,6 @@ enum scan_actions
...
@@ -72,7 +72,6 @@ enum scan_actions
static
const
char
*
const
scan_actions_name
[]
=
static
const
char
*
const
scan_actions_name
[]
=
{
{
"note_reference"
,
"terminate_all_read"
,
"terminate_all_read"
,
"terminate_overlapping_read"
,
"terminate_overlapping_read"
,
"terminate_write"
,
"terminate_write"
,
...
@@ -85,20 +84,117 @@ static struct obstack rename_obstack;
...
@@ -85,20 +84,117 @@ static struct obstack rename_obstack;
static
void
do_replace
PARAMS
((
struct
du_chain
*
,
int
));
static
void
do_replace
PARAMS
((
struct
du_chain
*
,
int
));
static
void
scan_rtx_reg
PARAMS
((
rtx
,
rtx
*
,
enum
reg_class
,
static
void
scan_rtx_reg
PARAMS
((
rtx
,
rtx
*
,
enum
reg_class
,
enum
scan_actions
,
enum
op_type
));
enum
scan_actions
,
enum
op_type
,
int
));
static
void
scan_rtx_address
PARAMS
((
rtx
,
rtx
*
,
enum
reg_class
,
static
void
scan_rtx_address
PARAMS
((
rtx
,
rtx
*
,
enum
reg_class
,
enum
scan_actions
,
enum
machine_mode
));
enum
scan_actions
,
enum
machine_mode
));
static
void
scan_rtx
PARAMS
((
rtx
,
rtx
*
,
enum
reg_class
,
static
void
scan_rtx
PARAMS
((
rtx
,
rtx
*
,
enum
reg_class
,
enum
scan_actions
,
enum
op_type
));
enum
scan_actions
,
enum
op_type
,
int
));
static
struct
du_chain
*
build_def_use
PARAMS
((
basic_block
,
HARD_REG_SET
*
));
static
struct
du_chain
*
build_def_use
PARAMS
((
basic_block
));
static
void
dump_def_use_chain
PARAMS
((
struct
du_chain
*
));
static
void
dump_def_use_chain
PARAMS
((
struct
du_chain
*
));
static
void
note_sets
PARAMS
((
rtx
,
rtx
,
void
*
));
static
void
clear_dead_regs
PARAMS
((
HARD_REG_SET
*
,
enum
machine_mode
,
rtx
));
static
void
merge_overlapping_regs
PARAMS
((
basic_block
,
HARD_REG_SET
*
,
struct
du_chain
*
));
/* Called through note_stores from update_life. Find sets of registers, and
record them in *DATA (which is actually a HARD_REG_SET *). */
static
void
note_sets
(
x
,
set
,
data
)
rtx
x
;
rtx
set
ATTRIBUTE_UNUSED
;
void
*
data
;
{
HARD_REG_SET
*
pset
=
(
HARD_REG_SET
*
)
data
;
unsigned
int
regno
;
int
nregs
;
if
(
GET_CODE
(
x
)
!=
REG
)
return
;
regno
=
REGNO
(
x
);
nregs
=
HARD_REGNO_NREGS
(
regno
,
GET_MODE
(
x
));
while
(
nregs
--
>
0
)
SET_HARD_REG_BIT
(
*
pset
,
regno
+
nregs
);
}
/* Clear all registers from *PSET for which a note of kind KIND can be found
in the list NOTES. */
static
void
clear_dead_regs
(
pset
,
kind
,
notes
)
HARD_REG_SET
*
pset
;
enum
machine_mode
kind
;
rtx
notes
;
{
rtx
note
;
for
(
note
=
notes
;
note
;
note
=
XEXP
(
note
,
1
))
if
(
REG_NOTE_KIND
(
note
)
==
kind
&&
REG_P
(
XEXP
(
note
,
0
)))
{
rtx
reg
=
XEXP
(
note
,
0
);
unsigned
int
regno
=
REGNO
(
reg
);
int
nregs
=
HARD_REGNO_NREGS
(
regno
,
GET_MODE
(
reg
));
while
(
nregs
--
>
0
)
CLEAR_HARD_REG_BIT
(
*
pset
,
regno
+
nregs
);
}
}
/* For a def-use chain CHAIN in basic block B, find which registers overlap
its lifetime and set the corresponding bits in *PSET. */
static
void
merge_overlapping_regs
(
b
,
pset
,
chain
)
basic_block
b
;
HARD_REG_SET
*
pset
;
struct
du_chain
*
chain
;
{
struct
du_chain
*
t
=
chain
;
rtx
insn
;
HARD_REG_SET
live
;
REG_SET_TO_HARD_REG_SET
(
live
,
b
->
global_live_at_start
);
insn
=
b
->
head
;
while
(
t
)
{
/* Search forward until the next reference to the register to be
renamed. */
while
(
insn
!=
t
->
insn
)
{
if
(
INSN_P
(
insn
))
{
clear_dead_regs
(
&
live
,
REG_DEAD
,
REG_NOTES
(
insn
));
note_stores
(
PATTERN
(
insn
),
note_sets
,
(
void
*
)
&
live
);
/* Only record currently live regs if we are inside the
reg's live range. */
if
(
t
!=
chain
)
IOR_HARD_REG_SET
(
*
pset
,
live
);
clear_dead_regs
(
&
live
,
REG_UNUSED
,
REG_NOTES
(
insn
));
}
insn
=
NEXT_INSN
(
insn
);
}
IOR_HARD_REG_SET
(
*
pset
,
live
);
/* For the last reference, also merge in all registers set in the
same insn.
@@@ We only have take earlyclobbered sets into account. */
if
(
!
t
->
next_use
)
note_stores
(
PATTERN
(
insn
),
note_sets
,
(
void
*
)
pset
);
t
=
t
->
next_use
;
}
}
/* Perform register renaming on the current function. */
void
void
regrename_optimize
()
regrename_optimize
()
{
{
int
tick
[
FIRST_PSEUDO_REGISTER
];
int
this_tick
=
0
;
int
b
;
int
b
;
char
*
first_obj
;
char
*
first_obj
;
memset
(
tick
,
0
,
sizeof
tick
);
gcc_obstack_init
(
&
rename_obstack
);
gcc_obstack_init
(
&
rename_obstack
);
first_obj
=
(
char
*
)
obstack_alloc
(
&
rename_obstack
,
0
);
first_obj
=
(
char
*
)
obstack_alloc
(
&
rename_obstack
,
0
);
...
@@ -106,28 +202,20 @@ regrename_optimize ()
...
@@ -106,28 +202,20 @@ regrename_optimize ()
{
{
basic_block
bb
=
BASIC_BLOCK
(
b
);
basic_block
bb
=
BASIC_BLOCK
(
b
);
struct
du_chain
*
all_chains
=
0
;
struct
du_chain
*
all_chains
=
0
;
HARD_REG_SET
regs_used
;
HARD_REG_SET
unavailable
;
HARD_REG_SET
unavailable
;
HARD_REG_SET
regs_seen
;
HARD_REG_SET
regs_seen
;
CLEAR_HARD_REG_SET
(
regs_used
);
CLEAR_HARD_REG_SET
(
unavailable
);
CLEAR_HARD_REG_SET
(
unavailable
);
if
(
rtl_dump_file
)
if
(
rtl_dump_file
)
fprintf
(
rtl_dump_file
,
"
\n
Basic block %d:
\n
"
,
b
);
fprintf
(
rtl_dump_file
,
"
\n
Basic block %d:
\n
"
,
b
);
all_chains
=
build_def_use
(
bb
,
&
regs_used
);
all_chains
=
build_def_use
(
bb
);
if
(
rtl_dump_file
)
if
(
rtl_dump_file
)
dump_def_use_chain
(
all_chains
);
dump_def_use_chain
(
all_chains
);
/* Available registers are not: used in the block, live at the start
CLEAR_HARD_REG_SET
(
unavailable
);
live at the end, a register we've renamed to. */
REG_SET_TO_HARD_REG_SET
(
unavailable
,
bb
->
global_live_at_start
);
REG_SET_TO_HARD_REG_SET
(
regs_seen
,
bb
->
global_live_at_end
);
IOR_HARD_REG_SET
(
unavailable
,
regs_seen
);
IOR_HARD_REG_SET
(
unavailable
,
regs_used
);
/* Don't clobber traceback for noreturn functions. */
/* Don't clobber traceback for noreturn functions. */
if
(
frame_pointer_needed
)
if
(
frame_pointer_needed
)
{
{
...
@@ -140,6 +228,7 @@ regrename_optimize ()
...
@@ -140,6 +228,7 @@ regrename_optimize ()
CLEAR_HARD_REG_SET
(
regs_seen
);
CLEAR_HARD_REG_SET
(
regs_seen
);
while
(
all_chains
)
while
(
all_chains
)
{
{
int
new_reg
,
best_new_reg
=
-
1
;
int
n_uses
;
int
n_uses
;
struct
du_chain
*
this
=
all_chains
;
struct
du_chain
*
this
=
all_chains
;
struct
du_chain
*
tmp
,
*
last
;
struct
du_chain
*
tmp
,
*
last
;
...
@@ -149,13 +238,15 @@ regrename_optimize ()
...
@@ -149,13 +238,15 @@ regrename_optimize ()
int
i
;
int
i
;
all_chains
=
this
->
next_chain
;
all_chains
=
this
->
next_chain
;
#if 0 /* This just disables optimization opportunities. */
/* Only rename once we've seen the reg more than once. */
/* Only rename once we've seen the reg more than once. */
if (! TEST_HARD_REG_BIT (regs_seen, reg))
if (! TEST_HARD_REG_BIT (regs_seen, reg))
{
{
SET_HARD_REG_BIT (regs_seen, reg);
SET_HARD_REG_BIT (regs_seen, reg);
continue;
continue;
}
}
#endif
if
(
fixed_regs
[
reg
]
||
global_regs
[
reg
])
if
(
fixed_regs
[
reg
]
||
global_regs
[
reg
])
continue
;
continue
;
...
@@ -178,21 +269,25 @@ regrename_optimize ()
...
@@ -178,21 +269,25 @@ regrename_optimize ()
IOR_COMPL_HARD_REG_SET
(
this_unavailable
,
IOR_COMPL_HARD_REG_SET
(
this_unavailable
,
reg_class_contents
[
last
->
class
]);
reg_class_contents
[
last
->
class
]);
if
(
last
->
need_caller_save_reg
)
if
(
this
->
need_caller_save_reg
)
IOR_HARD_REG_SET
(
this_unavailable
,
call_used_reg_set
);
IOR_HARD_REG_SET
(
this_unavailable
,
call_used_reg_set
);
merge_overlapping_regs
(
bb
,
&
this_unavailable
,
this
);
/* Now potential_regs is a reasonable approximation, let's
/* Now potential_regs is a reasonable approximation, let's
have a closer look at each register still in there. */
have a closer look at each register still in there. */
for
(
treg
=
0
;
treg
<
FIRST_PSEUDO_REGISTER
;
treg
++
)
for
(
treg
=
0
;
treg
<
FIRST_PSEUDO_REGISTER
;
treg
++
)
{
{
new_reg
=
treg
;
for
(
i
=
nregs
-
1
;
i
>=
0
;
--
i
)
for
(
i
=
nregs
-
1
;
i
>=
0
;
--
i
)
if
(
TEST_HARD_REG_BIT
(
this_unavailable
,
treg
+
i
)
if
(
TEST_HARD_REG_BIT
(
this_unavailable
,
new_reg
+
i
)
||
fixed_regs
[
treg
+
i
]
||
fixed_regs
[
new_reg
+
i
]
||
global_regs
[
treg
+
i
]
||
global_regs
[
new_reg
+
i
]
/* Can't use regs which aren't saved by the prologue. */
/* Can't use regs which aren't saved by the prologue. */
||
(
!
regs_ever_live
[
treg
+
i
]
&&
!
call_used_regs
[
treg
+
i
])
||
(
!
regs_ever_live
[
new_reg
+
i
]
&&
!
call_used_regs
[
new_reg
+
i
])
#ifdef HARD_REGNO_RENAME_OK
#ifdef HARD_REGNO_RENAME_OK
||
!
HARD_REGNO_RENAME_OK
(
reg
+
i
,
treg
+
i
)
||
!
HARD_REGNO_RENAME_OK
(
reg
+
i
,
new_reg
+
i
)
#endif
#endif
)
)
break
;
break
;
...
@@ -202,10 +297,14 @@ regrename_optimize ()
...
@@ -202,10 +297,14 @@ regrename_optimize ()
/* See whether it accepts all modes that occur in
/* See whether it accepts all modes that occur in
definition and uses. */
definition and uses. */
for
(
tmp
=
this
;
tmp
;
tmp
=
tmp
->
next_use
)
for
(
tmp
=
this
;
tmp
;
tmp
=
tmp
->
next_use
)
if
(
!
HARD_REGNO_MODE_OK
(
t
reg
,
GET_MODE
(
*
tmp
->
loc
)))
if
(
!
HARD_REGNO_MODE_OK
(
new_
reg
,
GET_MODE
(
*
tmp
->
loc
)))
break
;
break
;
if
(
!
tmp
)
if
(
!
tmp
)
break
;
{
if
(
best_new_reg
==
-
1
||
tick
[
best_new_reg
]
>
tick
[
new_reg
])
best_new_reg
=
new_reg
;
}
}
}
if
(
rtl_dump_file
)
if
(
rtl_dump_file
)
...
@@ -216,20 +315,18 @@ regrename_optimize ()
...
@@ -216,20 +315,18 @@ regrename_optimize ()
fprintf
(
rtl_dump_file
,
" crosses a call"
);
fprintf
(
rtl_dump_file
,
" crosses a call"
);
}
}
if
(
treg
==
FIRST_PSEUDO_REGISTER
)
if
(
best_new_reg
==
-
1
)
{
{
if
(
rtl_dump_file
)
if
(
rtl_dump_file
)
fprintf
(
rtl_dump_file
,
"; no available registers
\n
"
);
fprintf
(
rtl_dump_file
,
"; no available registers
\n
"
);
continue
;
continue
;
}
}
do_replace
(
this
,
best_new_reg
);
for
(
i
=
nregs
-
1
;
i
>=
0
;
--
i
)
tick
[
best_new_reg
]
=
this_tick
++
;
SET_HARD_REG_BIT
(
unavailable
,
treg
+
i
);
do_replace
(
this
,
treg
);
if
(
rtl_dump_file
)
if
(
rtl_dump_file
)
fprintf
(
rtl_dump_file
,
", renamed as %s
\n
"
,
reg_names
[
t
reg
]);
fprintf
(
rtl_dump_file
,
", renamed as %s
\n
"
,
reg_names
[
best_new_
reg
]);
}
}
obstack_free
(
&
rename_obstack
,
first_obj
);
obstack_free
(
&
rename_obstack
,
first_obj
);
...
@@ -258,17 +355,17 @@ do_replace (chain, reg)
...
@@ -258,17 +355,17 @@ do_replace (chain, reg)
}
}
static
HARD_REG_SET
*
referenced_regs
;
static
struct
du_chain
*
open_chains
;
static
struct
du_chain
*
open_chains
;
static
struct
du_chain
*
closed_chains
;
static
struct
du_chain
*
closed_chains
;
static
void
static
void
scan_rtx_reg
(
insn
,
loc
,
class
,
action
,
type
)
scan_rtx_reg
(
insn
,
loc
,
class
,
action
,
type
,
earlyclobber
)
rtx
insn
;
rtx
insn
;
rtx
*
loc
;
rtx
*
loc
;
enum
reg_class
class
;
enum
reg_class
class
;
enum
scan_actions
action
;
enum
scan_actions
action
;
enum
op_type
type
;
enum
op_type
type
;
int
earlyclobber
;
{
{
struct
du_chain
**
p
;
struct
du_chain
**
p
;
rtx
x
=
*
loc
;
rtx
x
=
*
loc
;
...
@@ -276,13 +373,6 @@ scan_rtx_reg (insn, loc, class, action, type)
...
@@ -276,13 +373,6 @@ scan_rtx_reg (insn, loc, class, action, type)
int
this_regno
=
REGNO
(
x
);
int
this_regno
=
REGNO
(
x
);
int
this_nregs
=
HARD_REGNO_NREGS
(
this_regno
,
mode
);
int
this_nregs
=
HARD_REGNO_NREGS
(
this_regno
,
mode
);
if
(
action
==
note_reference
)
{
while
(
this_nregs
--
>
0
)
SET_HARD_REG_BIT
(
*
referenced_regs
,
this_regno
+
this_nregs
);
return
;
}
if
(
action
==
mark_write
)
if
(
action
==
mark_write
)
{
{
if
(
type
==
OP_OUT
)
if
(
type
==
OP_OUT
)
...
@@ -295,6 +385,7 @@ scan_rtx_reg (insn, loc, class, action, type)
...
@@ -295,6 +385,7 @@ scan_rtx_reg (insn, loc, class, action, type)
this
->
insn
=
insn
;
this
->
insn
=
insn
;
this
->
class
=
class
;
this
->
class
=
class
;
this
->
need_caller_save_reg
=
0
;
this
->
need_caller_save_reg
=
0
;
this
->
earlyclobber
=
earlyclobber
;
open_chains
=
this
;
open_chains
=
this
;
}
}
return
;
return
;
...
@@ -343,12 +434,14 @@ scan_rtx_reg (insn, loc, class, action, type)
...
@@ -343,12 +434,14 @@ scan_rtx_reg (insn, loc, class, action, type)
{
{
this
=
(
struct
du_chain
*
)
this
=
(
struct
du_chain
*
)
obstack_alloc
(
&
rename_obstack
,
sizeof
(
struct
du_chain
));
obstack_alloc
(
&
rename_obstack
,
sizeof
(
struct
du_chain
));
this
->
next_use
=
*
p
;
this
->
next_use
=
0
;
this
->
next_chain
=
(
*
p
)
->
next_chain
;
this
->
next_chain
=
(
*
p
)
->
next_chain
;
this
->
loc
=
loc
;
this
->
loc
=
loc
;
this
->
insn
=
insn
;
this
->
insn
=
insn
;
this
->
class
=
class
;
this
->
class
=
class
;
this
->
need_caller_save_reg
=
0
;
this
->
need_caller_save_reg
=
0
;
while
(
*
p
)
p
=
&
(
*
p
)
->
next_use
;
*
p
=
this
;
*
p
=
this
;
return
;
return
;
}
}
...
@@ -510,7 +603,7 @@ scan_rtx_address (insn, loc, class, action, mode)
...
@@ -510,7 +603,7 @@ scan_rtx_address (insn, loc, class, action, mode)
return
;
return
;
case
REG
:
case
REG
:
scan_rtx_reg
(
insn
,
loc
,
class
,
action
,
OP_IN
);
scan_rtx_reg
(
insn
,
loc
,
class
,
action
,
OP_IN
,
0
);
return
;
return
;
default
:
default
:
...
@@ -529,12 +622,13 @@ scan_rtx_address (insn, loc, class, action, mode)
...
@@ -529,12 +622,13 @@ scan_rtx_address (insn, loc, class, action, mode)
}
}
static
void
static
void
scan_rtx
(
insn
,
loc
,
class
,
action
,
type
)
scan_rtx
(
insn
,
loc
,
class
,
action
,
type
,
earlyclobber
)
rtx
insn
;
rtx
insn
;
rtx
*
loc
;
rtx
*
loc
;
enum
reg_class
class
;
enum
reg_class
class
;
enum
scan_actions
action
;
enum
scan_actions
action
;
enum
op_type
type
;
enum
op_type
type
;
int
earlyclobber
;
{
{
const
char
*
fmt
;
const
char
*
fmt
;
rtx
x
=
*
loc
;
rtx
x
=
*
loc
;
...
@@ -554,7 +648,7 @@ scan_rtx (insn, loc, class, action, type)
...
@@ -554,7 +648,7 @@ scan_rtx (insn, loc, class, action, type)
return
;
return
;
case
REG
:
case
REG
:
scan_rtx_reg
(
insn
,
loc
,
class
,
action
,
type
);
scan_rtx_reg
(
insn
,
loc
,
class
,
action
,
type
,
earlyclobber
);
return
;
return
;
case
MEM
:
case
MEM
:
...
@@ -563,20 +657,20 @@ scan_rtx (insn, loc, class, action, type)
...
@@ -563,20 +657,20 @@ scan_rtx (insn, loc, class, action, type)
return
;
return
;
case
SET
:
case
SET
:
scan_rtx
(
insn
,
&
SET_SRC
(
x
),
class
,
action
,
OP_IN
);
scan_rtx
(
insn
,
&
SET_SRC
(
x
),
class
,
action
,
OP_IN
,
0
);
scan_rtx
(
insn
,
&
SET_DEST
(
x
),
class
,
action
,
OP_OUT
);
scan_rtx
(
insn
,
&
SET_DEST
(
x
),
class
,
action
,
OP_OUT
,
0
);
return
;
return
;
case
STRICT_LOW_PART
:
case
STRICT_LOW_PART
:
scan_rtx
(
insn
,
&
XEXP
(
x
,
0
),
class
,
action
,
OP_INOUT
);
scan_rtx
(
insn
,
&
XEXP
(
x
,
0
),
class
,
action
,
OP_INOUT
,
earlyclobber
);
return
;
return
;
case
ZERO_EXTRACT
:
case
ZERO_EXTRACT
:
case
SIGN_EXTRACT
:
case
SIGN_EXTRACT
:
scan_rtx
(
insn
,
&
XEXP
(
x
,
0
),
class
,
action
,
scan_rtx
(
insn
,
&
XEXP
(
x
,
0
),
class
,
action
,
type
==
OP_IN
?
OP_IN
:
OP_INOUT
);
type
==
OP_IN
?
OP_IN
:
OP_INOUT
,
earlyclobber
);
scan_rtx
(
insn
,
&
XEXP
(
x
,
1
),
class
,
action
,
OP_IN
);
scan_rtx
(
insn
,
&
XEXP
(
x
,
1
),
class
,
action
,
OP_IN
,
0
);
scan_rtx
(
insn
,
&
XEXP
(
x
,
2
),
class
,
action
,
OP_IN
);
scan_rtx
(
insn
,
&
XEXP
(
x
,
2
),
class
,
action
,
OP_IN
,
0
);
return
;
return
;
case
POST_INC
:
case
POST_INC
:
...
@@ -589,13 +683,13 @@ scan_rtx (insn, loc, class, action, type)
...
@@ -589,13 +683,13 @@ scan_rtx (insn, loc, class, action, type)
abort
();
abort
();
case
CLOBBER
:
case
CLOBBER
:
scan_rtx
(
insn
,
&
SET_DEST
(
x
),
class
,
action
,
OP_OUT
);
scan_rtx
(
insn
,
&
SET_DEST
(
x
),
class
,
action
,
OP_OUT
,
1
);
return
;
return
;
case
EXPR_LIST
:
case
EXPR_LIST
:
scan_rtx
(
insn
,
&
XEXP
(
x
,
0
),
class
,
action
,
type
);
scan_rtx
(
insn
,
&
XEXP
(
x
,
0
),
class
,
action
,
type
,
0
);
if
(
XEXP
(
x
,
1
))
if
(
XEXP
(
x
,
1
))
scan_rtx
(
insn
,
&
XEXP
(
x
,
1
),
class
,
action
,
type
);
scan_rtx
(
insn
,
&
XEXP
(
x
,
1
),
class
,
action
,
type
,
0
);
return
;
return
;
default
:
default
:
...
@@ -606,24 +700,22 @@ scan_rtx (insn, loc, class, action, type)
...
@@ -606,24 +700,22 @@ scan_rtx (insn, loc, class, action, type)
for
(
i
=
GET_RTX_LENGTH
(
code
)
-
1
;
i
>=
0
;
i
--
)
for
(
i
=
GET_RTX_LENGTH
(
code
)
-
1
;
i
>=
0
;
i
--
)
{
{
if
(
fmt
[
i
]
==
'e'
)
if
(
fmt
[
i
]
==
'e'
)
scan_rtx
(
insn
,
&
XEXP
(
x
,
i
),
class
,
action
,
type
);
scan_rtx
(
insn
,
&
XEXP
(
x
,
i
),
class
,
action
,
type
,
0
);
else
if
(
fmt
[
i
]
==
'E'
)
else
if
(
fmt
[
i
]
==
'E'
)
for
(
j
=
XVECLEN
(
x
,
i
)
-
1
;
j
>=
0
;
j
--
)
for
(
j
=
XVECLEN
(
x
,
i
)
-
1
;
j
>=
0
;
j
--
)
scan_rtx
(
insn
,
&
XVECEXP
(
x
,
i
,
j
),
class
,
action
,
type
);
scan_rtx
(
insn
,
&
XVECEXP
(
x
,
i
,
j
),
class
,
action
,
type
,
0
);
}
}
}
}
/* Build def/use chain */
/* Build def/use chain */
static
struct
du_chain
*
static
struct
du_chain
*
build_def_use
(
bb
,
regs_used
)
build_def_use
(
bb
)
basic_block
bb
;
basic_block
bb
;
HARD_REG_SET
*
regs_used
;
{
{
rtx
insn
;
rtx
insn
;
open_chains
=
closed_chains
=
NULL
;
open_chains
=
closed_chains
=
NULL
;
referenced_regs
=
regs_used
;
for
(
insn
=
bb
->
head
;
;
insn
=
NEXT_INSN
(
insn
))
for
(
insn
=
bb
->
head
;
;
insn
=
NEXT_INSN
(
insn
))
{
{
...
@@ -637,9 +729,6 @@ build_def_use (bb, regs_used)
...
@@ -637,9 +729,6 @@ build_def_use (bb, regs_used)
int
alt
;
int
alt
;
int
predicated
;
int
predicated
;
/* Record all mentioned registers in regs_used. */
scan_rtx
(
insn
,
&
PATTERN
(
insn
),
NO_REGS
,
note_reference
,
OP_IN
);
/* Process the insn, determining its effect on the def-use
/* Process the insn, determining its effect on the def-use
chains. We perform the following steps with the register
chains. We perform the following steps with the register
references in the insn:
references in the insn:
...
@@ -681,7 +770,7 @@ build_def_use (bb, regs_used)
...
@@ -681,7 +770,7 @@ build_def_use (bb, regs_used)
for
(
i
=
0
;
i
<
n_ops
;
i
++
)
for
(
i
=
0
;
i
<
n_ops
;
i
++
)
scan_rtx
(
insn
,
recog_data
.
operand_loc
[
i
],
scan_rtx
(
insn
,
recog_data
.
operand_loc
[
i
],
NO_REGS
,
terminate_overlapping_read
,
NO_REGS
,
terminate_overlapping_read
,
recog_data
.
operand_type
[
i
]);
recog_data
.
operand_type
[
i
]
,
0
);
/* Step 2: Close chains for which we have reads outside operands.
/* Step 2: Close chains for which we have reads outside operands.
We do this by munging all operands into CC0, and closing
We do this by munging all operands into CC0, and closing
...
@@ -703,7 +792,8 @@ build_def_use (bb, regs_used)
...
@@ -703,7 +792,8 @@ build_def_use (bb, regs_used)
*
recog_data
.
dup_loc
[
i
]
=
cc0_rtx
;
*
recog_data
.
dup_loc
[
i
]
=
cc0_rtx
;
}
}
scan_rtx
(
insn
,
&
PATTERN
(
insn
),
NO_REGS
,
terminate_all_read
,
OP_IN
);
scan_rtx
(
insn
,
&
PATTERN
(
insn
),
NO_REGS
,
terminate_all_read
,
OP_IN
,
0
);
for
(
i
=
0
;
i
<
recog_data
.
n_dups
;
i
++
)
for
(
i
=
0
;
i
<
recog_data
.
n_dups
;
i
++
)
*
recog_data
.
dup_loc
[
i
]
=
old_dups
[
i
];
*
recog_data
.
dup_loc
[
i
]
=
old_dups
[
i
];
...
@@ -713,7 +803,7 @@ build_def_use (bb, regs_used)
...
@@ -713,7 +803,7 @@ build_def_use (bb, regs_used)
/* Step 2B: Can't rename function call argument registers. */
/* Step 2B: Can't rename function call argument registers. */
if
(
GET_CODE
(
insn
)
==
CALL_INSN
&&
CALL_INSN_FUNCTION_USAGE
(
insn
))
if
(
GET_CODE
(
insn
)
==
CALL_INSN
&&
CALL_INSN_FUNCTION_USAGE
(
insn
))
scan_rtx
(
insn
,
&
CALL_INSN_FUNCTION_USAGE
(
insn
),
scan_rtx
(
insn
,
&
CALL_INSN_FUNCTION_USAGE
(
insn
),
NO_REGS
,
terminate_all_read
,
OP_IN
);
NO_REGS
,
terminate_all_read
,
OP_IN
,
0
);
/* Step 3: Append to chains for reads inside operands. */
/* Step 3: Append to chains for reads inside operands. */
for
(
i
=
0
;
i
<
n_ops
+
recog_data
.
n_dups
;
i
++
)
for
(
i
=
0
;
i
<
n_ops
+
recog_data
.
n_dups
;
i
++
)
...
@@ -734,7 +824,7 @@ build_def_use (bb, regs_used)
...
@@ -734,7 +824,7 @@ build_def_use (bb, regs_used)
if
(
recog_op_alt
[
opn
][
alt
].
is_address
)
if
(
recog_op_alt
[
opn
][
alt
].
is_address
)
scan_rtx_address
(
insn
,
loc
,
class
,
mark_read
,
VOIDmode
);
scan_rtx_address
(
insn
,
loc
,
class
,
mark_read
,
VOIDmode
);
else
else
scan_rtx
(
insn
,
loc
,
class
,
mark_read
,
type
);
scan_rtx
(
insn
,
loc
,
class
,
mark_read
,
type
,
0
);
}
}
/* Step 4: Close chains for registers that die here.
/* Step 4: Close chains for registers that die here.
...
@@ -742,9 +832,11 @@ build_def_use (bb, regs_used)
...
@@ -742,9 +832,11 @@ build_def_use (bb, regs_used)
for
(
note
=
REG_NOTES
(
insn
);
note
;
note
=
XEXP
(
note
,
1
))
for
(
note
=
REG_NOTES
(
insn
);
note
;
note
=
XEXP
(
note
,
1
))
{
{
if
(
REG_NOTE_KIND
(
note
)
==
REG_DEAD
)
if
(
REG_NOTE_KIND
(
note
)
==
REG_DEAD
)
scan_rtx
(
insn
,
&
XEXP
(
note
,
0
),
NO_REGS
,
terminate_dead
,
OP_IN
);
scan_rtx
(
insn
,
&
XEXP
(
note
,
0
),
NO_REGS
,
terminate_dead
,
OP_IN
,
0
);
else
if
(
REG_NOTE_KIND
(
note
)
==
REG_INC
)
else
if
(
REG_NOTE_KIND
(
note
)
==
REG_INC
)
scan_rtx
(
insn
,
&
XEXP
(
note
,
0
),
ALL_REGS
,
mark_read
,
OP_INOUT
);
scan_rtx
(
insn
,
&
XEXP
(
note
,
0
),
ALL_REGS
,
mark_read
,
OP_INOUT
,
0
);
}
}
/* Step 4B: If this is a call, any chain live at this point
/* Step 4B: If this is a call, any chain live at this point
...
@@ -753,12 +845,7 @@ build_def_use (bb, regs_used)
...
@@ -753,12 +845,7 @@ build_def_use (bb, regs_used)
{
{
struct
du_chain
*
p
;
struct
du_chain
*
p
;
for
(
p
=
open_chains
;
p
;
p
=
p
->
next_chain
)
for
(
p
=
open_chains
;
p
;
p
=
p
->
next_chain
)
{
p
->
need_caller_save_reg
=
1
;
struct
du_chain
*
p2
;
for
(
p2
=
p
;
p2
->
next_use
;
p2
=
p2
->
next_use
)
/* nothing */
;
p2
->
need_caller_save_reg
=
1
;
}
}
}
/* Step 5: Close open chains that overlap writes. Similar to
/* Step 5: Close open chains that overlap writes. Similar to
...
@@ -779,7 +866,7 @@ build_def_use (bb, regs_used)
...
@@ -779,7 +866,7 @@ build_def_use (bb, regs_used)
*
recog_data
.
dup_loc
[
i
]
=
cc0_rtx
;
*
recog_data
.
dup_loc
[
i
]
=
cc0_rtx
;
}
}
scan_rtx
(
insn
,
&
PATTERN
(
insn
),
NO_REGS
,
terminate_write
,
OP_IN
);
scan_rtx
(
insn
,
&
PATTERN
(
insn
),
NO_REGS
,
terminate_write
,
OP_IN
,
0
);
for
(
i
=
0
;
i
<
recog_data
.
n_dups
;
i
++
)
for
(
i
=
0
;
i
<
recog_data
.
n_dups
;
i
++
)
*
recog_data
.
dup_loc
[
i
]
=
old_dups
[
i
];
*
recog_data
.
dup_loc
[
i
]
=
old_dups
[
i
];
...
@@ -800,14 +887,16 @@ build_def_use (bb, regs_used)
...
@@ -800,14 +887,16 @@ build_def_use (bb, regs_used)
enum
reg_class
class
=
recog_op_alt
[
opn
][
alt
].
class
;
enum
reg_class
class
=
recog_op_alt
[
opn
][
alt
].
class
;
if
(
recog_data
.
operand_type
[
opn
]
==
OP_OUT
)
if
(
recog_data
.
operand_type
[
opn
]
==
OP_OUT
)
scan_rtx
(
insn
,
loc
,
class
,
mark_write
,
OP_OUT
);
scan_rtx
(
insn
,
loc
,
class
,
mark_write
,
OP_OUT
,
recog_op_alt
[
opn
][
alt
].
earlyclobber
);
}
}
/* Step 7: Close chains for registers that were never
/* Step 7: Close chains for registers that were never
really used here. */
really used here. */
for
(
note
=
REG_NOTES
(
insn
);
note
;
note
=
XEXP
(
note
,
1
))
for
(
note
=
REG_NOTES
(
insn
);
note
;
note
=
XEXP
(
note
,
1
))
if
(
REG_NOTE_KIND
(
note
)
==
REG_UNUSED
)
if
(
REG_NOTE_KIND
(
note
)
==
REG_UNUSED
)
scan_rtx
(
insn
,
&
XEXP
(
note
,
0
),
NO_REGS
,
terminate_dead
,
OP_IN
);
scan_rtx
(
insn
,
&
XEXP
(
note
,
0
),
NO_REGS
,
terminate_dead
,
OP_IN
,
0
);
}
}
if
(
insn
==
bb
->
end
)
if
(
insn
==
bb
->
end
)
break
;
break
;
...
...
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