diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-07-19 16:12:08 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-07-19 16:12:08 +0000 |
commit | ff6c5a5609c9eb7f1d4a93b48e651759e073a9cd (patch) | |
tree | bef19b8f9ebd30b4b26b0808495e9f6a00ee39db /llvm/lib | |
parent | 27d1cfe3d40dbb453e96b65bd17483995500d4a0 (diff) | |
download | bcm5719-llvm-ff6c5a5609c9eb7f1d4a93b48e651759e073a9cd.tar.gz bcm5719-llvm-ff6c5a5609c9eb7f1d4a93b48e651759e073a9cd.zip |
[SystemZ] Use SLLK, SRLK and SRAK for codegen
This patch uses the instructions added in r186680 for codegen.
llvm-svn: 186681
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrFormats.td | 26 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 47 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.h | 5 |
3 files changed, 73 insertions, 5 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td index 45147c1a919..b0301821a31 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -34,6 +34,12 @@ class InstSystemZ<int size, dag outs, dag ins, string asmstr, string OpKey = ""; string OpType = "none"; + // Many distinct-operands instructions have older 2-operand equivalents. + // NumOpsKey uniquely identifies one of these 2-operand and 3-operand pairs, + // with NumOpsValue being "2" or "3" as appropriate. + string NumOpsKey = ""; + string NumOpsValue = "none"; + // True if this instruction is a simple D(X,B) load of a register // (with no sign or zero extension). bit SimpleBDXLoad = 0; @@ -86,6 +92,7 @@ def getDisp20Opcode : InstrMapping { let ValueCols = [["20"]]; } +// Return the memory form of a register instruction. def getMemOpcode : InstrMapping { let FilterClass = "InstSystemZ"; let RowFields = ["OpKey"]; @@ -94,6 +101,15 @@ def getMemOpcode : InstrMapping { let ValueCols = [["mem"]]; } +// Return the 3-operand form of a 2-operand instruction. +def getThreeOperandOpcode : InstrMapping { + let FilterClass = "InstSystemZ"; + let RowFields = ["NumOpsKey"]; + let ColFields = ["NumOpsValue"]; + let KeyCol = ["2"]; + let ValueCols = [["3"]]; +} + //===----------------------------------------------------------------------===// // Instruction formats //===----------------------------------------------------------------------===// @@ -833,9 +849,13 @@ class ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator, multiclass ShiftRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2, SDPatternOperator operator, RegisterOperand cls> { - def K : ShiftRSY<mnemonic##"k", opcode2, null_frag, cls>, - Requires<[FeatureDistinctOps]>; - def "" : ShiftRS<mnemonic, opcode1, operator, cls>; + let NumOpsKey = mnemonic in { + let NumOpsValue = "3" in + def K : ShiftRSY<mnemonic##"k", opcode2, null_frag, cls>, + Requires<[FeatureDistinctOps]>; + let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in + def "" : ShiftRS<mnemonic, opcode1, operator, cls>; + } } class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator, diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index bbac73fcaff..3a502a0117b 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -12,9 +12,10 @@ //===----------------------------------------------------------------------===// #include "SystemZInstrInfo.h" +#include "SystemZTargetMachine.h" #include "SystemZInstrBuilder.h" +#include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Target/TargetMachine.h" #define GET_INSTRINFO_CTOR #define GET_INSTRMAP_INFO @@ -24,7 +25,7 @@ using namespace llvm; SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP), - RI(tm) { + RI(tm), TM(tm) { } // MI is a 128-bit load or store. Split it into two 64-bit loads or stores, @@ -352,6 +353,48 @@ static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) { } MachineInstr * +SystemZInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, + MachineBasicBlock::iterator &MBBI, + LiveVariables *LV) const { + MachineInstr *MI = MBBI; + MachineBasicBlock *MBB = MI->getParent(); + + unsigned Opcode = MI->getOpcode(); + unsigned NumOps = MI->getNumOperands(); + + // Try to convert something like SLL into SLLK, if supported. + // We prefer to keep the two-operand form where possible both + // because it tends to be shorter and because some instructions + // have memory forms that can be used during spilling. + if (TM.getSubtargetImpl()->hasDistinctOps()) { + int ThreeOperandOpcode = SystemZ::getThreeOperandOpcode(Opcode); + if (ThreeOperandOpcode >= 0) { + unsigned DestReg = MI->getOperand(0).getReg(); + MachineOperand &Src = MI->getOperand(1); + MachineInstrBuilder MIB = BuildMI(*MBB, MBBI, MI->getDebugLoc(), + get(ThreeOperandOpcode), DestReg); + // Keep the kill state, but drop the tied flag. + MIB.addReg(Src.getReg(), getKillRegState(Src.isKill())); + // Keep the remaining operands as-is. + for (unsigned I = 2; I < NumOps; ++I) + MIB.addOperand(MI->getOperand(I)); + MachineInstr *NewMI = MIB; + + // Transfer killing information to the new instruction. + if (LV) { + for (unsigned I = 1; I < NumOps; ++I) { + MachineOperand &Op = MI->getOperand(I); + if (Op.isReg() && Op.isKill()) + LV->replaceKillInstruction(Op.getReg(), MI, NewMI); + } + } + return MIB; + } + } + return 0; +} + +MachineInstr * SystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl<unsigned> &Ops, diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h index 3fe71d88547..2050e8ec7c6 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -79,6 +79,7 @@ namespace SystemZII { class SystemZInstrInfo : public SystemZGenInstrInfo { const SystemZRegisterInfo RI; + SystemZTargetMachine &TM; void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const; void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const; @@ -120,6 +121,10 @@ public: const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const LLVM_OVERRIDE; virtual MachineInstr * + convertToThreeAddress(MachineFunction::iterator &MFI, + MachineBasicBlock::iterator &MBBI, + LiveVariables *LV) const; + virtual MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl<unsigned> &Ops, int FrameIndex) const; |