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
f3a3d0d3
Commit
f3a3d0d3
authored
Oct 02, 1999
by
Richard Henderson
Committed by
Richard Henderson
Oct 02, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* md.texi (define_peephole2): New section.
From-SVN: r29772
parent
ffab8d85
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
319 additions
and
212 deletions
+319
-212
gcc/ChangeLog
+4
-0
gcc/md.texi
+315
-212
No files found.
gcc/ChangeLog
View file @
f3a3d0d3
Sat
Oct
2
11
:
06
:
31
1999
Richard
Henderson
<
rth
@cygnus
.
com
>
*
md
.
texi
(
define_peephole2
)
:
New
section
.
Sat
Oct
2
10
:
57
:
56
1999
Jan
Hubicka
<
hubicka
@freesoft
.
cz
>
Sat
Oct
2
10
:
57
:
56
1999
Jan
Hubicka
<
hubicka
@freesoft
.
cz
>
*
i386
.
md
(
mov
?
i
patterns
):
Fix
handling
of
TARGET_USE_MOV0
*
i386
.
md
(
mov
?
i
patterns
):
Fix
handling
of
TARGET_USE_MOV0
...
...
gcc/md.texi
View file @
f3a3d0d3
...
@@ -32,10 +32,10 @@ See the next chapter for information on the C header file.
...
@@ -32,10 +32,10 @@ See the next chapter for information on the C header file.
*
Dependent
Patterns
::
Having
one
pattern
may
make
you
need
another
.
*
Dependent
Patterns
::
Having
one
pattern
may
make
you
need
another
.
*
Jump
Patterns
::
Special
considerations
for
patterns
for
jump
insns
.
*
Jump
Patterns
::
Special
considerations
for
patterns
for
jump
insns
.
*
Insn
Canonicalizations
::
Canonicalization
of
Instructions
*
Insn
Canonicalizations
::
Canonicalization
of
Instructions
*
Peephole
Definitions
::
Defining
machine
-
specific
peephole
optimizations
.
*
Expander
Definitions
::
Generating
a
sequence
of
several
RTL
insns
*
Expander
Definitions
::
Generating
a
sequence
of
several
RTL
insns
for
a
standard
operation
.
for
a
standard
operation
.
*
Insn
Splitting
::
Splitting
Instructions
into
Multiple
Instructions
*
Insn
Splitting
::
Splitting
Instructions
into
Multiple
Instructions
.
*
Peephole
Definitions
::
Defining
machine
-
specific
peephole
optimizations
.
*
Insn
Attributes
::
Specifying
the
value
of
attributes
for
generated
insns
.
*
Insn
Attributes
::
Specifying
the
value
of
attributes
for
generated
insns
.
@end
menu
@end
menu
...
@@ -2907,210 +2907,6 @@ will be written using @code{zero_extract} rather than the equivalent
...
@@ -2907,210 +2907,6 @@ will be written using @code{zero_extract} rather than the equivalent
@end
itemize
@end
itemize
@node
Peephole
Definitions
@section
Machine
-
Specific
Peephole
Optimizers
@cindex
peephole
optimizer
definitions
@cindex
defining
peephole
optimizers
In
addition
to
instruction
patterns
the
@file
{
md
}
file
may
contain
definitions
of
machine
-
specific
peephole
optimizations
.
The
combiner
does
not
notice
certain
peephole
optimizations
when
the
data
flow
in
the
program
does
not
suggest
that
it
should
try
them
.
For
example
,
sometimes
two
consecutive
insns
related
in
purpose
can
be
combined
even
though
the
second
one
does
not
appear
to
use
a
register
computed
in
the
first
one
.
A
machine
-
specific
peephole
optimizer
can
detect
such
opportunities
.
@need
1000
A
definition
looks
like
this
:
@smallexample
(
define_peephole
[
@var
{
insn
-
pattern
-
1
}
@var
{
insn
-
pattern
-
2
}
@dots
{}]
"@var{condition}"
"@var{template}"
"@var{optional insn-attributes}"
)
@end
smallexample
@noindent
The
last
string
operand
may
be
omitted
if
you
are
not
using
any
machine
-
specific
information
in
this
machine
description
.
If
present
,
it
must
obey
the
same
rules
as
in
a
@code
{
define_insn
}.
In
this
skeleton
,
@var
{
insn
-
pattern
-
1
}
and
so
on
are
patterns
to
match
consecutive
insns
.
The
optimization
applies
to
a
sequence
of
insns
when
@var
{
insn
-
pattern
-
1
}
matches
the
first
one
,
@var
{
insn
-
pattern
-
2
}
matches
the
next
,
and
so
on
.
@refill
Each
of
the
insns
matched
by
a
peephole
must
also
match
a
@code
{
define_insn
}.
Peepholes
are
checked
only
at
the
last
stage
just
before
code
generation
,
and
only
optionally
.
Therefore
,
any
insn
which
would
match
a
peephole
but
no
@code
{
define_insn
}
will
cause
a
crash
in
code
generation
in
an
unoptimized
compilation
,
or
at
various
optimization
stages
.
The
operands
of
the
insns
are
matched
with
@code
{
match_operands
},
@code
{
match_operator
},
and
@code
{
match_dup
},
as
usual
.
What
is
not
usual
is
that
the
operand
numbers
apply
to
all
the
insn
patterns
in
the
definition
.
So
,
you
can
check
for
identical
operands
in
two
insns
by
using
@code
{
match_operand
}
in
one
insn
and
@code
{
match_dup
}
in
the
other
.
The
operand
constraints
used
in
@code
{
match_operand
}
patterns
do
not
have
any
direct
effect
on
the
applicability
of
the
peephole
,
but
they
will
be
validated
afterward
,
so
make
sure
your
constraints
are
general
enough
to
apply
whenever
the
peephole
matches
.
If
the
peephole
matches
but
the
constraints
are
not
satisfied
,
the
compiler
will
crash
.
It
is
safe
to
omit
constraints
in
all
the
operands
of
the
peephole
;
or
you
can
write
constraints
which
serve
as
a
double
-
check
on
the
criteria
previously
tested
.
Once
a
sequence
of
insns
matches
the
patterns
,
the
@var
{
condition
}
is
checked
.
This
is
a
C
expression
which
makes
the
final
decision
whether
to
perform
the
optimization
(
we
do
so
if
the
expression
is
nonzero
).
If
@var
{
condition
}
is
omitted
(
in
other
words
,
the
string
is
empty
)
then
the
optimization
is
applied
to
every
sequence
of
insns
that
matches
the
patterns
.
The
defined
peephole
optimizations
are
applied
after
register
allocation
is
complete
.
Therefore
,
the
peephole
definition
can
check
which
operands
have
ended
up
in
which
kinds
of
registers
,
just
by
looking
at
the
operands
.
@findex
prev_active_insn
The
way
to
refer
to
the
operands
in
@var
{
condition
}
is
to
write
@code
{
operands
[
@var
{
i
}]}
for
operand
number
@var
{
i
}
(
as
matched
by
@code
{(
match_operand
@var
{
i
}
@dots
{})}).
Use
the
variable
@code
{
insn
}
to
refer
to
the
last
of
the
insns
being
matched
;
use
@code
{
prev_active_insn
}
to
find
the
preceding
insns
.
@findex
dead_or_set_p
When
optimizing
computations
with
intermediate
results
,
you
can
use
@var
{
condition
}
to
match
only
when
the
intermediate
results
are
not
used
elsewhere
.
Use
the
C
expression
@code
{
dead_or_set_p
(
@var
{
insn
},
@var
{
op
})},
where
@var
{
insn
}
is
the
insn
in
which
you
expect
the
value
to
be
used
for
the
last
time
(
from
the
value
of
@code
{
insn
},
together
with
use
of
@code
{
prev_nonnote_insn
}),
and
@var
{
op
}
is
the
intermediate
value
(
from
@code
{
operands
[
@var
{
i
}]}).
@refill
Applying
the
optimization
means
replacing
the
sequence
of
insns
with
one
new
insn
.
The
@var
{
template
}
controls
ultimate
output
of
assembler
code
for
this
combined
insn
.
It
works
exactly
like
the
template
of
a
@code
{
define_insn
}.
Operand
numbers
in
this
template
are
the
same
ones
used
in
matching
the
original
sequence
of
insns
.
The
result
of
a
defined
peephole
optimizer
does
not
need
to
match
any
of
the
insn
patterns
in
the
machine
description
;
it
does
not
even
have
an
opportunity
to
match
them
.
The
peephole
optimizer
definition
itself
serves
as
the
insn
pattern
to
control
how
the
insn
is
output
.
Defined
peephole
optimizers
are
run
as
assembler
code
is
being
output
,
so
the
insns
they
produce
are
never
combined
or
rearranged
in
any
way
.
Here
is
an
example
,
taken
from
the
68000
machine
description
:
@smallexample
(
define_peephole
[(
set
(
reg
:
SI
15
)
(
plus
:
SI
(
reg
:
SI
15
)
(
const_int
4
)))
(
set
(
match_operand
:
DF
0
"register_operand"
"=f"
)
(
match_operand
:
DF
1
"register_operand"
"ad"
))]
"FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
"*
@{
rtx xoperands[2];
xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
#ifdef MOTOROLA
output_asm_insn (
\"
move.l %1,(sp)
\"
, xoperands);
output_asm_insn (
\"
move.l %1,-(sp)
\"
, operands);
return
\"
fmove.d (sp)+,%0
\"
;
#else
output_asm_insn (
\"
movel %1,sp@@
\"
, xoperands);
output_asm_insn (
\"
movel %1,sp@@-
\"
, operands);
return
\"
fmoved sp@@+,%0
\"
;
#endif
@}
"
)
@end
smallexample
@need
1000
The
effect
of
this
optimization
is
to
change
@smallexample
@group
jbsr
_foobar
addql
#
4
,
sp
movel
d1
,
sp
@@
-
movel
d0
,
sp
@@
-
fmoved
sp
@@
+
,
fp0
@end
group
@end
smallexample
@noindent
into
@smallexample
@group
jbsr
_foobar
movel
d1
,
sp
@@
movel
d0
,
sp
@@
-
fmoved
sp
@@
+
,
fp0
@end
group
@end
smallexample
@ignore
@findex
CC_REVERSED
If
a
peephole
matches
a
sequence
including
one
or
more
jump
insns
,
you
must
take
account
of
the
flags
such
as
@code
{
CC_REVERSED
}
which
specify
that
the
condition
codes
are
represented
in
an
unusual
manner
.
The
compiler
automatically
alters
any
ordinary
conditional
jumps
which
occur
in
such
situations
,
but
the
compiler
cannot
alter
jumps
which
have
been
replaced
by
peephole
optimizations
.
So
it
is
up
to
you
to
alter
the
assembler
code
that
the
peephole
produces
.
Supply
C
code
to
write
the
assembler
output
,
and
in
this
C
code
check
the
condition
code
status
flags
and
change
the
assembler
code
as
appropriate
.
@end
ignore
@var
{
insn
-
pattern
-
1
}
and
so
on
look
@emph
{
almost
}
like
the
second
operand
of
@code
{
define_insn
}.
There
is
one
important
difference
:
the
second
operand
of
@code
{
define_insn
}
consists
of
one
or
more
RTX
'
s
enclosed
in
square
brackets
.
Usually
,
there
is
only
one
:
then
the
same
action
can
be
written
as
an
element
of
a
@code
{
define_peephole
}.
But
when
there
are
multiple
actions
in
a
@code
{
define_insn
},
they
are
implicitly
enclosed
in
a
@code
{
parallel
}.
Then
you
must
explicitly
write
the
@code
{
parallel
},
and
the
square
brackets
within
it
,
in
the
@code
{
define_peephole
}.
Thus
,
if
an
insn
pattern
looks
like
this
,
@smallexample
(
define_insn
"divmodsi4"
[(
set
(
match_operand
:
SI
0
"general_operand"
"=d"
)
(
div
:
SI
(
match_operand
:
SI
1
"general_operand"
"0"
)
(
match_operand
:
SI
2
"general_operand"
"dmsK"
)))
(
set
(
match_operand
:
SI
3
"general_operand"
"=d"
)
(
mod
:
SI
(
match_dup
1
)
(
match_dup
2
)))]
"TARGET_68020"
"divsl%.l %2,%3:%0"
)
@end
smallexample
@noindent
then
the
way
to
mention
this
insn
in
a
peephole
is
as
follows
:
@smallexample
(
define_peephole
[
@dots
{}
(
parallel
[(
set
(
match_operand
:
SI
0
"general_operand"
"=d"
)
(
div
:
SI
(
match_operand
:
SI
1
"general_operand"
"0"
)
(
match_operand
:
SI
2
"general_operand"
"dmsK"
)))
(
set
(
match_operand
:
SI
3
"general_operand"
"=d"
)
(
mod
:
SI
(
match_dup
1
)
(
match_dup
2
)))])
@dots
{}]
@dots
{})
@end
smallexample
@node
Expander
Definitions
@node
Expander
Definitions
@section
Defining
RTL
Sequences
for
Code
Generation
@section
Defining
RTL
Sequences
for
Code
Generation
@cindex
expander
definitions
@cindex
expander
definitions
...
@@ -3134,11 +2930,10 @@ A @code{define_expand} RTX has four operands:
...
@@ -3134,11 +2930,10 @@ A @code{define_expand} RTX has four operands:
The
name
.
Each
@code
{
define_expand
}
must
have
a
name
,
since
the
only
The
name
.
Each
@code
{
define_expand
}
must
have
a
name
,
since
the
only
use
for
it
is
to
refer
to
it
by
name
.
use
for
it
is
to
refer
to
it
by
name
.
@findex
define_peephole
@item
@item
The
RTL
template
.
This
is
just
like
the
RTL
template
for
a
The
RTL
template
.
This
is
a
vector
of
RTL
expressions
representing
@code
{
define_peephole
}
in
that
it
is
a
vector
of
RTL
expressions
a
sequence
of
separate
instructions
.
Unlike
@code
{
define_insn
},
there
each
being
one
insn
.
is
no
implicit
surrounding
@code
{
PARALLEL
}
.
@item
@item
The
condition
,
a
string
containing
a
C
expression
.
This
expression
is
The
condition
,
a
string
containing
a
C
expression
.
This
expression
is
...
@@ -3333,7 +3128,7 @@ subexpression. However, in some other cases, such as performing an
...
@@ -3333,7 +3128,7 @@ subexpression. However, in some other cases, such as performing an
addition
of
a
large
constant
in
two
insns
on
a
RISC
machine
,
the
way
to
addition
of
a
large
constant
in
two
insns
on
a
RISC
machine
,
the
way
to
split
the
addition
into
two
insns
is
machine
-
dependent
.
split
the
addition
into
two
insns
is
machine
-
dependent
.
@
c
index
define_split
@
f
index
define_split
The
@code
{
define_split
}
definition
tells
the
compiler
how
to
split
a
The
@code
{
define_split
}
definition
tells
the
compiler
how
to
split
a
complex
insn
into
several
simpler
insns
.
It
looks
like
this
:
complex
insn
into
several
simpler
insns
.
It
looks
like
this
:
...
@@ -3466,6 +3261,314 @@ insns that don't. Instead, write two separate @code{define_split}
...
@@ -3466,6 +3261,314 @@ insns that don't. Instead, write two separate @code{define_split}
definitions
,
one
for
the
insns
that
are
valid
and
one
for
the
insns
that
definitions
,
one
for
the
insns
that
are
valid
and
one
for
the
insns
that
are
not
valid
.
are
not
valid
.
@node
Peephole
Definitions
@section
Machine
-
Specific
Peephole
Optimizers
@cindex
peephole
optimizer
definitions
@cindex
defining
peephole
optimizers
In
addition
to
instruction
patterns
the
@file
{
md
}
file
may
contain
definitions
of
machine
-
specific
peephole
optimizations
.
The
combiner
does
not
notice
certain
peephole
optimizations
when
the
data
flow
in
the
program
does
not
suggest
that
it
should
try
them
.
For
example
,
sometimes
two
consecutive
insns
related
in
purpose
can
be
combined
even
though
the
second
one
does
not
appear
to
use
a
register
computed
in
the
first
one
.
A
machine
-
specific
peephole
optimizer
can
detect
such
opportunities
.
There
are
two
forms
of
peephole
definitions
that
may
be
used
.
The
original
@code
{
define_peephole
}
is
run
at
assembly
output
time
to
match
insns
and
substitute
assembly
text
.
Use
of
@code
{
define_peephole
}
is
deprecated
.
A
newer
@code
{
define_peephole2
}
matches
insns
and
substitutes
new
insns
.
The
@code
{
peephole2
}
pass
is
run
after
register
allocation
but
before
scheduling
,
which
may
result
in
much
better
code
for
targets
that
do
scheduling
.
@menu
*
define_peephole
::
RTL
to
Text
Peephole
Optimizers
*
define_peephole2
::
RTL
to
RTL
Peephole
Optimizers
@end
menu
@node
define_peephole
@subsection
RTL
to
Text
Peephole
Optimizers
@findex
define_peephole
@need
1000
A
definition
looks
like
this
:
@smallexample
(
define_peephole
[
@var
{
insn
-
pattern
-
1
}
@var
{
insn
-
pattern
-
2
}
@dots
{}]
"@var{condition}"
"@var{template}"
"@var{optional insn-attributes}"
)
@end
smallexample
@noindent
The
last
string
operand
may
be
omitted
if
you
are
not
using
any
machine
-
specific
information
in
this
machine
description
.
If
present
,
it
must
obey
the
same
rules
as
in
a
@code
{
define_insn
}.
In
this
skeleton
,
@var
{
insn
-
pattern
-
1
}
and
so
on
are
patterns
to
match
consecutive
insns
.
The
optimization
applies
to
a
sequence
of
insns
when
@var
{
insn
-
pattern
-
1
}
matches
the
first
one
,
@var
{
insn
-
pattern
-
2
}
matches
the
next
,
and
so
on
.
@refill
Each
of
the
insns
matched
by
a
peephole
must
also
match
a
@code
{
define_insn
}.
Peepholes
are
checked
only
at
the
last
stage
just
before
code
generation
,
and
only
optionally
.
Therefore
,
any
insn
which
would
match
a
peephole
but
no
@code
{
define_insn
}
will
cause
a
crash
in
code
generation
in
an
unoptimized
compilation
,
or
at
various
optimization
stages
.
The
operands
of
the
insns
are
matched
with
@code
{
match_operands
},
@code
{
match_operator
},
and
@code
{
match_dup
},
as
usual
.
What
is
not
usual
is
that
the
operand
numbers
apply
to
all
the
insn
patterns
in
the
definition
.
So
,
you
can
check
for
identical
operands
in
two
insns
by
using
@code
{
match_operand
}
in
one
insn
and
@code
{
match_dup
}
in
the
other
.
The
operand
constraints
used
in
@code
{
match_operand
}
patterns
do
not
have
any
direct
effect
on
the
applicability
of
the
peephole
,
but
they
will
be
validated
afterward
,
so
make
sure
your
constraints
are
general
enough
to
apply
whenever
the
peephole
matches
.
If
the
peephole
matches
but
the
constraints
are
not
satisfied
,
the
compiler
will
crash
.
It
is
safe
to
omit
constraints
in
all
the
operands
of
the
peephole
;
or
you
can
write
constraints
which
serve
as
a
double
-
check
on
the
criteria
previously
tested
.
Once
a
sequence
of
insns
matches
the
patterns
,
the
@var
{
condition
}
is
checked
.
This
is
a
C
expression
which
makes
the
final
decision
whether
to
perform
the
optimization
(
we
do
so
if
the
expression
is
nonzero
).
If
@var
{
condition
}
is
omitted
(
in
other
words
,
the
string
is
empty
)
then
the
optimization
is
applied
to
every
sequence
of
insns
that
matches
the
patterns
.
The
defined
peephole
optimizations
are
applied
after
register
allocation
is
complete
.
Therefore
,
the
peephole
definition
can
check
which
operands
have
ended
up
in
which
kinds
of
registers
,
just
by
looking
at
the
operands
.
@findex
prev_active_insn
The
way
to
refer
to
the
operands
in
@var
{
condition
}
is
to
write
@code
{
operands
[
@var
{
i
}]}
for
operand
number
@var
{
i
}
(
as
matched
by
@code
{(
match_operand
@var
{
i
}
@dots
{})}).
Use
the
variable
@code
{
insn
}
to
refer
to
the
last
of
the
insns
being
matched
;
use
@code
{
prev_active_insn
}
to
find
the
preceding
insns
.
@findex
dead_or_set_p
When
optimizing
computations
with
intermediate
results
,
you
can
use
@var
{
condition
}
to
match
only
when
the
intermediate
results
are
not
used
elsewhere
.
Use
the
C
expression
@code
{
dead_or_set_p
(
@var
{
insn
},
@var
{
op
})},
where
@var
{
insn
}
is
the
insn
in
which
you
expect
the
value
to
be
used
for
the
last
time
(
from
the
value
of
@code
{
insn
},
together
with
use
of
@code
{
prev_nonnote_insn
}),
and
@var
{
op
}
is
the
intermediate
value
(
from
@code
{
operands
[
@var
{
i
}]}).
@refill
Applying
the
optimization
means
replacing
the
sequence
of
insns
with
one
new
insn
.
The
@var
{
template
}
controls
ultimate
output
of
assembler
code
for
this
combined
insn
.
It
works
exactly
like
the
template
of
a
@code
{
define_insn
}.
Operand
numbers
in
this
template
are
the
same
ones
used
in
matching
the
original
sequence
of
insns
.
The
result
of
a
defined
peephole
optimizer
does
not
need
to
match
any
of
the
insn
patterns
in
the
machine
description
;
it
does
not
even
have
an
opportunity
to
match
them
.
The
peephole
optimizer
definition
itself
serves
as
the
insn
pattern
to
control
how
the
insn
is
output
.
Defined
peephole
optimizers
are
run
as
assembler
code
is
being
output
,
so
the
insns
they
produce
are
never
combined
or
rearranged
in
any
way
.
Here
is
an
example
,
taken
from
the
68000
machine
description
:
@smallexample
(
define_peephole
[(
set
(
reg
:
SI
15
)
(
plus
:
SI
(
reg
:
SI
15
)
(
const_int
4
)))
(
set
(
match_operand
:
DF
0
"register_operand"
"=f"
)
(
match_operand
:
DF
1
"register_operand"
"ad"
))]
"FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
"*
@{
rtx xoperands[2];
xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
#ifdef MOTOROLA
output_asm_insn (
\"
move.l %1,(sp)
\"
, xoperands);
output_asm_insn (
\"
move.l %1,-(sp)
\"
, operands);
return
\"
fmove.d (sp)+,%0
\"
;
#else
output_asm_insn (
\"
movel %1,sp@@
\"
, xoperands);
output_asm_insn (
\"
movel %1,sp@@-
\"
, operands);
return
\"
fmoved sp@@+,%0
\"
;
#endif
@}
"
)
@end
smallexample
@need
1000
The
effect
of
this
optimization
is
to
change
@smallexample
@group
jbsr
_foobar
addql
#
4
,
sp
movel
d1
,
sp
@@
-
movel
d0
,
sp
@@
-
fmoved
sp
@@
+
,
fp0
@end
group
@end
smallexample
@noindent
into
@smallexample
@group
jbsr
_foobar
movel
d1
,
sp
@@
movel
d0
,
sp
@@
-
fmoved
sp
@@
+
,
fp0
@end
group
@end
smallexample
@ignore
@findex
CC_REVERSED
If
a
peephole
matches
a
sequence
including
one
or
more
jump
insns
,
you
must
take
account
of
the
flags
such
as
@code
{
CC_REVERSED
}
which
specify
that
the
condition
codes
are
represented
in
an
unusual
manner
.
The
compiler
automatically
alters
any
ordinary
conditional
jumps
which
occur
in
such
situations
,
but
the
compiler
cannot
alter
jumps
which
have
been
replaced
by
peephole
optimizations
.
So
it
is
up
to
you
to
alter
the
assembler
code
that
the
peephole
produces
.
Supply
C
code
to
write
the
assembler
output
,
and
in
this
C
code
check
the
condition
code
status
flags
and
change
the
assembler
code
as
appropriate
.
@end
ignore
@var
{
insn
-
pattern
-
1
}
and
so
on
look
@emph
{
almost
}
like
the
second
operand
of
@code
{
define_insn
}.
There
is
one
important
difference
:
the
second
operand
of
@code
{
define_insn
}
consists
of
one
or
more
RTX
'
s
enclosed
in
square
brackets
.
Usually
,
there
is
only
one
:
then
the
same
action
can
be
written
as
an
element
of
a
@code
{
define_peephole
}.
But
when
there
are
multiple
actions
in
a
@code
{
define_insn
},
they
are
implicitly
enclosed
in
a
@code
{
parallel
}.
Then
you
must
explicitly
write
the
@code
{
parallel
},
and
the
square
brackets
within
it
,
in
the
@code
{
define_peephole
}.
Thus
,
if
an
insn
pattern
looks
like
this
,
@smallexample
(
define_insn
"divmodsi4"
[(
set
(
match_operand
:
SI
0
"general_operand"
"=d"
)
(
div
:
SI
(
match_operand
:
SI
1
"general_operand"
"0"
)
(
match_operand
:
SI
2
"general_operand"
"dmsK"
)))
(
set
(
match_operand
:
SI
3
"general_operand"
"=d"
)
(
mod
:
SI
(
match_dup
1
)
(
match_dup
2
)))]
"TARGET_68020"
"divsl%.l %2,%3:%0"
)
@end
smallexample
@noindent
then
the
way
to
mention
this
insn
in
a
peephole
is
as
follows
:
@smallexample
(
define_peephole
[
@dots
{}
(
parallel
[(
set
(
match_operand
:
SI
0
"general_operand"
"=d"
)
(
div
:
SI
(
match_operand
:
SI
1
"general_operand"
"0"
)
(
match_operand
:
SI
2
"general_operand"
"dmsK"
)))
(
set
(
match_operand
:
SI
3
"general_operand"
"=d"
)
(
mod
:
SI
(
match_dup
1
)
(
match_dup
2
)))])
@dots
{}]
@dots
{})
@end
smallexample
@node
define_peephole2
@subsection
RTL
to
RTL
Peephole
Optimizers
@findex
define_peephole2
The
@code
{
define_peephole2
}
definition
tells
the
compiler
how
to
substitute
one
sequence
of
instructions
for
another
sequence
,
what
additional
scratch
registers
may
be
needed
and
what
their
lifetimes
must
be
.
@smallexample
(
define_peephole2
[
@var
{
insn
-
pattern
-
1
}
@var
{
insn
-
pattern
-
2
}
@dots
{}]
"@var{condition}"
[
@var
{
new
-
insn
-
pattern
-
1
}
@var
{
new
-
insn
-
pattern
-
2
}
@dots
{}]
"@var{preparation statements}"
)
@end
smallexample
The
definition
is
almost
identical
to
@code
{
define_split
}
(
@pxref
{
Insn
Splitting
})
except
that
the
pattern
to
match
is
not
a
single
instruction
,
but
a
sequence
of
instructions
.
It
is
possible
to
request
additional
scratch
registers
for
use
in
the
output
template
.
If
appropriate
registers
are
not
free
,
the
pattern
will
simply
not
match
.
@findex
match_scratch
@findex
match_dup
Scratch
registers
are
requested
with
a
@code
{
match_scratch
}
pattern
at
the
top
level
of
the
input
pattern
.
The
allocated
register
(
initially
)
will
be
dead
at
the
point
requested
within
the
original
sequence
.
If
the
scratch
is
used
at
more
than
a
single
point
,
a
@code
{
match_dup
}
pattern
at
the
top
level
of
the
input
pattern
marks
the
last
position
in
the
input
sequence
at
which
the
register
must
be
available
.
Here
is
an
example
from
the
IA
-
32
machine
description
:
@smallexample
(
define_peephole2
[(
match_scratch
:
SI
2
"r"
)
(
parallel
[(
set
(
match_operand
:
SI
0
"register_operand"
""
)
(
match_operator
:
SI
3
"arith_or_logical_operator"
[(
match_dup
0
)
(
match_operand
:
SI
1
"memory_operand"
""
)]))
(
clobber
(
reg
:
CC
17
))])]
"! optimize_size && ! TARGET_READ_MODIFY"
[(
set
(
match_dup
2
)
(
match_dup
1
))
(
parallel
[(
set
(
match_dup
0
)
(
match_op_dup
3
[(
match_dup
0
)
(
match_dup
2
)]))
(
clobber
(
reg
:
CC
17
))])]
""
)
@end
smallexample
@noindent
This
pattern
tries
to
split
a
load
from
its
use
in
the
hopes
that
we
'
ll
be
able
to
schedule
around
the
memory
load
latency
.
It
allocates
a
single
@code
{
SImode
}
register
of
class
@code
{
GENERAL_REGS
}
(
@code
{
"r"
})
that
needs
to
be
live
only
at
the
point
just
before
the
arithmetic
.
A
real
example
requring
extended
scratch
lifetimes
is
harder
to
come
by
,
so
here
'
s
a
silly
made
-
up
example
:
@smallexample
(
define_peephole2
[(
match_scratch
:
SI
4
"r"
)
(
set
(
match_operand
:
SI
0
""
""
)
(
match_operand
:
SI
1
""
""
))
(
set
(
match_operand
:
SI
2
""
""
)
(
match_dup
1
))
(
match_dup
4
)
(
set
(
match_operand
:
SI
3
""
""
)
(
match_dup
1
))]
"@var{determine 1 does not overlap 0 and 2}"
[(
set
(
match_dup
4
)
(
match_dup
1
))
(
set
(
match_dup
0
)
(
match_dup
4
))
(
set
(
match_dup
2
)
(
match_dup
4
))]
(
set
(
match_dup
3
)
(
match_dup
4
))]
""
)
@end
smallexample
@noindent
If
we
had
not
added
the
@code
{(
match_dup
3
)}
at
the
end
of
the
sequence
,
it
might
have
been
the
case
that
the
register
we
chose
at
the
beginning
of
the
sequence
is
killed
by
the
first
or
second
@code{
set
}
.
@node
Insn
Attributes
@node
Insn
Attributes
@section
Instruction
Attributes
@section
Instruction
Attributes
@cindex
insn
attributes
@cindex
insn
attributes
...
...
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