From: Michael Meissner <meissner@linux.ibm.com>
To: gcc-patches@gcc.gnu.org,
Segher Boessenkool <segher@kernel.crashing.org>,
David Edelsohn <dje.gcc@gmail.com>,
Michael Meissner <meissner@linux.ibm.com>,
Bill Schmidt <wschmidt@linux.ibm.com>,
Peter Bergner <bergner@linux.ibm.com>
Subject: [PATCH 0/3] Power10 PCREL_OPT support (September 5th 2020)
Date: Sat, 5 Sep 2020 00:27:56 -0400 [thread overview]
Message-ID: <20200905042756.GA15702@ibm-toto.the-meissners.org> (raw)
The ELF-v2 ISA 3.1 support for Power10 has relocations to optimize cases where
the code is references an external variable in only one location. This patch
is similar to the optimizations that the linker already does to optimize TOC
accesses.
This patch is a revision of the patches last submitted on August 18th, 2020.
Compared to those patches, the current patches do:
1) The dataflow (DF) functions are used to find the single defs and single
ref to that def in the same basic block. Less parsing of the RTL is being
done.
2) I switched to use the validate_change and apply_change_group functions
instead of manually replacing the PATTERN if the value did not pan out. I
tested this by temporarily disabling some of the patterns, and validated
the the results were undone (and then I re-instated the changes to allow
these patches to do the work).
3) I tried to clean up the comments, and added some more comments in
places.
4) I verified that the patches could be moved earlier, and these patches
move the code just before the 2nd scheduler pass (previously it was after
the 2nd scheduler pass). I did try out an earlier set of patches, and I
could move the pass to be just after the reload pass. In building Spec
2017, I noticed that moving the changes before the 2nd scheduler pass
caught a for more cases than moving it after the register allocation or
after the 2nd scheduler pass.
5) I removed the '%r' case to print_operand, and instead used a common
function to create the .reloc.
I will be submitting 3 patches as follow-ups to this message:
* The first patch adds support for PCREL_OPT loads;
* The second patch adds support for PCREL_OPT stores; (and)
* The third patch adds the tests.
I have built the compiler with/without the patches, and there were no
regressions in the testsuite. Can I check these patches into the master
branch? I do not antipate needing to backport these changes to GCC 10.3.
If the program is compiled to be the main program, and the variable is defined
in the main program, these relocations will convert loading up the address of
the external variable and then doing a load or store using that address to be
doing the prefixed load or store directly and converting the second instruction
into a NOP.
For example, consider the following program:
extern int ext_variable;
int ret_var (void)
{
return ext_variable;
}
void store_var (int i)
{
ext_variable = i;
}
Currently on power10, the compiler compiles this as:
ret_var:
pld 9,ext_variable@got@pcrel
lwa 3,0(9)
blr
store_var:
pld 9,ext_variable@got@pcrel
stw 3,0(9)
blr
That is, it loads up the address of 'ext_variable' from the GOT table into
register r9, and then uses r9 as a base register to reference the actual
variable.
The linker does optimize the case where you are compiling the main program, and
the variable is also defined in the main program to be:
ret_var:
pla 9,ext_variable
lwa 3,0(9)
blr
store_var:
pla 9,ext_variable
stw 3,0(9)
blr
These patches generate:
ret_var:
pld 9,ext_variable@got@pcrel
.Lpcrel1:
.reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8)
lwa 3,0(9)
blr
store_var:
pld 9,ext_variable@got@pcrel
.Lpcrel2:
.reloc .Lpcrel2-8,R_PPC64_PCREL_OPT,.-(.Lpcrel2-8)
stw 3,0(9)
blr
Note, the label for locating the PLD occurs after the PLD and not before it.
This is so that if the assembler adds a NOP in front of the PLD to align it,
the relocations will still work.
If the linker can, it will convert the code into:
ret_var:
plwa 3,ext_variable@pcrel(0),1
nop
blr
store_var:
pstw 3,ext_variable@pcrel(0),1
nop
blr
These patches allow the load of the address to not be physically adjacent to
the actual load or store, which should allow for better code.
For loads, there must no references to the register that is being loaded
between the PLD and the actual load.
For stores, it becomes a little trickier, in that the register being stored
must be live at the time the PLD instruction is done, and it must continue to
be live and unmodified between the PLD and the store.
For both loads and stores, there must be only one reference to the address
being loaded into a base register, and that base register must die at the point
of the load/store.
For reference, here is what the current compiler generates for a medium code
model system targeting power9 with the TOC support:
.section ".toc","aw"
.LC0:
.quad ext_variable
.section ".text"
ret_var:
.LCF0:
0: addis 2,12,.TOC.-.LCF0@ha
addi 2,2,.TOC.-.LCF0@l
.localentry ret_var,.-ret_var
addis 9,2,.LC0@toc@ha
ld 9,.LC0@toc@l(9)
lwa 3,0(9)
blr
.section ".toc","aw"
.set .LC1,.LC0
.section ".text"
store_var:
.LCF1:
0: addis 2,12,.TOC.-.LCF1@ha
addi 2,2,.TOC.-.LCF1@l
.localentry store_var,.-store_var
addis 9,2,.LC1@toc@ha
ld 9,.LC1@toc@l(9)
stw 3,0(9)
blr
And the linker optimizes this to:
ret_var:
lis 2,.TOC@ha
addi 2,2,.TOC@l
.localentry ret_var,.-ret_var
nop ; addis eliminated due to small TOC
addi 9,2,<offset> ; ld converted into addi
lwa 3,0(9) ; actual load
store_var:
lis 2,.TOC@ha
addi 2,2,.TOC@l
.localentry store_var,.-store_var
nop ; addis eliminated due to small TOC
addi 9,2,<offset> ; ld converted into addi
stw 3,0(9) ; actual store
--
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797
next reply other threads:[~2020-09-05 4:28 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-05 4:27 Michael Meissner [this message]
2020-09-05 4:31 ` [PATCH 1/3] power10: Add PCREL_OPT load support Michael Meissner
2020-09-05 4:35 ` [PATCH 2/3] power10: Add PCREL_OPT store support Michael Meissner
2020-09-05 4:36 ` [PATCH 3/3] power10: Add tests for PCREL_OPT Michael Meissner
2020-09-05 15:20 ` [PATCH 0/3] Power10 PCREL_OPT support (September 5th 2020) Michael Meissner
2020-09-22 3:21 ` Ping: " Michael Meissner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200905042756.GA15702@ibm-toto.the-meissners.org \
--to=meissner@linux.ibm.com \
--cc=bergner@linux.ibm.com \
--cc=dje.gcc@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=segher@kernel.crashing.org \
--cc=wschmidt@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).