summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-07-19 16:12:08 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-07-19 16:12:08 +0000
commitff6c5a5609c9eb7f1d4a93b48e651759e073a9cd (patch)
treebef19b8f9ebd30b4b26b0808495e9f6a00ee39db /llvm/lib
parent27d1cfe3d40dbb453e96b65bd17483995500d4a0 (diff)
downloadbcm5719-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.td26
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp47
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.h5
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;
OpenPOWER on IntegriCloud