diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-08-23 11:18:53 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-08-23 11:18:53 +0000 |
commit | 65ddcfa8c1c05aeecd9d4fb062bb121e376aaceb (patch) | |
tree | 284fe4e394f7d0a3a059c6c7fbddc7cf38ff0643 /lib/Target/SystemZ | |
parent | a8a7099c1849fcbb4a68642a292fd0250aa46505 (diff) | |
download | external_llvm-65ddcfa8c1c05aeecd9d4fb062bb121e376aaceb.zip external_llvm-65ddcfa8c1c05aeecd9d4fb062bb121e376aaceb.tar.gz external_llvm-65ddcfa8c1c05aeecd9d4fb062bb121e376aaceb.tar.bz2 |
[SystemZ] Prefer LHI;ST... over LAY;MV...
If we had a store of an integer to memory, and the integer and store size
were suitable for a form of MV..., we used MV... no matter what. We could
then have sequences like:
lay %r2, 0(%r3,%r4)
mvi 0(%r2), 4
In these cases it seems better to force the constant into a register
and use a normal store:
lhi %r2, 4
stc %r2, 0(%r3, %r4)
since %r2 is more likely to be hoisted and is easier to rematerialize.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189098 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SystemZ')
-rw-r--r-- | lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 25 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrFormats.td | 26 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZOperands.td | 3 |
3 files changed, 44 insertions, 10 deletions
diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index d9794b1..e0d5437 100644 --- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -159,6 +159,12 @@ class SystemZDAGToDAGISel : public SelectionDAGISel { bool selectBDAddr(SystemZAddressingMode::DispRange DR, SDValue Addr, SDValue &Base, SDValue &Disp); + // Try to match Addr as a FormBDX address with displacement type DR. + // Return true on success and if the result had no index. Store the + // base and displacement in Base and Disp respectively. + bool selectMVIAddr(SystemZAddressingMode::DispRange DR, SDValue Addr, + SDValue &Base, SDValue &Disp); + // Try to match Addr as a FormBDX* address of form Form with // displacement type DR. Return true on success, storing the base, // displacement and index in Base, Disp and Index respectively. @@ -189,6 +195,14 @@ class SystemZDAGToDAGISel : public SelectionDAGISel { return selectBDAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp); } + // MVI matching routines used by SystemZOperands.td. + bool selectMVIAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp) { + return selectMVIAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp); + } + bool selectMVIAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp) { + return selectMVIAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp); + } + // BDX matching routines used by SystemZOperands.td. bool selectBDXAddr12Only(SDValue Addr, SDValue &Base, SDValue &Disp, SDValue &Index) { @@ -575,6 +589,17 @@ bool SystemZDAGToDAGISel::selectBDAddr(SystemZAddressingMode::DispRange DR, return true; } +bool SystemZDAGToDAGISel::selectMVIAddr(SystemZAddressingMode::DispRange DR, + SDValue Addr, SDValue &Base, + SDValue &Disp) { + SystemZAddressingMode AM(SystemZAddressingMode::FormBDXNormal, DR); + if (!selectAddress(Addr, AM) || AM.Index.getNode()) + return false; + + getAddressOperands(AM, Addr.getValueType(), Base, Disp); + return true; +} + bool SystemZDAGToDAGISel::selectBDXAddr(SystemZAddressingMode::AddrForm Form, SystemZAddressingMode::DispRange DR, SDValue Addr, SDValue &Base, diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td index 39b7639..f538332 100644 --- a/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/lib/Target/SystemZ/SystemZInstrFormats.td @@ -627,27 +627,33 @@ class StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls> let mayStore = 1; } +// StoreSI* instructions are used to store an integer to memory, but the +// addresses are more restricted than for normal stores. If we are in the +// situation of having to force either the address into a register or the +// constant into a register, it's usually better to do the latter. +// We therefore match the address in the same way as a normal store and +// only use the StoreSI* instruction if the matched address is suitable. class StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator, - Immediate imm, AddressingMode mode = bdaddr12only> - : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2), + Immediate imm> + : InstSI<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2), mnemonic#"\t$BD1, $I2", - [(operator imm:$I2, mode:$BD1)]> { + [(operator imm:$I2, mviaddr12pair:$BD1)]> { let mayStore = 1; } class StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator, - Immediate imm, AddressingMode mode = bdaddr20only> - : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2), + Immediate imm> + : InstSIY<opcode, (outs), (ins mviaddr20pair:$BD1, imm:$I2), mnemonic#"\t$BD1, $I2", - [(operator imm:$I2, mode:$BD1)]> { + [(operator imm:$I2, mviaddr20pair:$BD1)]> { let mayStore = 1; } class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator, Immediate imm> - : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2), + : InstSIL<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2), mnemonic#"\t$BD1, $I2", - [(operator imm:$I2, bdaddr12only:$BD1)]> { + [(operator imm:$I2, mviaddr12pair:$BD1)]> { let mayStore = 1; } @@ -655,9 +661,9 @@ multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode, SDPatternOperator operator, Immediate imm> { let DispKey = mnemonic in { let DispSize = "12" in - def "" : StoreSI<mnemonic, siOpcode, operator, imm, bdaddr12pair>; + def "" : StoreSI<mnemonic, siOpcode, operator, imm>; let DispSize = "20" in - def Y : StoreSIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>; + def Y : StoreSIY<mnemonic#"y", siyOpcode, operator, imm>; } } diff --git a/lib/Target/SystemZ/SystemZOperands.td b/lib/Target/SystemZ/SystemZOperands.td index 9d79439..eb96dba 100644 --- a/lib/Target/SystemZ/SystemZOperands.td +++ b/lib/Target/SystemZ/SystemZOperands.td @@ -435,6 +435,7 @@ def BDLAddr64Disp12Len8 : AddressAsmOperand<"BDLAddr", "64", "12", "Len8">; // <type> is one of: // shift : base + displacement (32-bit) // bdaddr : base + displacement +// mviaddr : like bdaddr, but reject cases with a natural index // bdxaddr : base + displacement + index // laaddr : like bdxaddr, but used for Load Address operations // dynalloc : base + displacement + index + ADJDYNALLOC @@ -460,6 +461,8 @@ def bdaddr12only : BDMode <"BDAddr", "64", "12", "Only">; def bdaddr12pair : BDMode <"BDAddr", "64", "12", "Pair">; def bdaddr20only : BDMode <"BDAddr", "64", "20", "Only">; def bdaddr20pair : BDMode <"BDAddr", "64", "20", "Pair">; +def mviaddr12pair : BDMode <"MVIAddr", "64", "12", "Pair">; +def mviaddr20pair : BDMode <"MVIAddr", "64", "20", "Pair">; def bdxaddr12only : BDXMode<"BDXAddr", "64", "12", "Only">; def bdxaddr12pair : BDXMode<"BDXAddr", "64", "12", "Pair">; def bdxaddr20only : BDXMode<"BDXAddr", "64", "20", "Only">; |