aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp')
-rw-r--r--contrib/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp128
1 files changed, 56 insertions, 72 deletions
diff --git a/contrib/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp b/contrib/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
index d1a17c5500d6..846edd51341a 100644
--- a/contrib/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
+++ b/contrib/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
@@ -16,6 +16,8 @@
#include "SystemZTargetMachine.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
@@ -35,19 +37,16 @@ public:
bool runOnMachineFunction(MachineFunction &F) override;
private:
- bool shortenIIF(MachineInstr &MI, unsigned *GPRMap, unsigned LiveOther,
- unsigned LLIxL, unsigned LLIxH);
+ bool shortenIIF(MachineInstr &MI, unsigned LLIxL, unsigned LLIxH);
bool shortenOn0(MachineInstr &MI, unsigned Opcode);
bool shortenOn01(MachineInstr &MI, unsigned Opcode);
bool shortenOn001(MachineInstr &MI, unsigned Opcode);
+ bool shortenOn001AddCC(MachineInstr &MI, unsigned Opcode);
bool shortenFPConv(MachineInstr &MI, unsigned Opcode);
const SystemZInstrInfo *TII;
-
- // LowGPRs[I] has bit N set if LLVM register I includes the low
- // word of GPR N. HighGPRs is the same for the high word.
- unsigned LowGPRs[SystemZ::NUM_TARGET_REGS];
- unsigned HighGPRs[SystemZ::NUM_TARGET_REGS];
+ const TargetRegisterInfo *TRI;
+ LivePhysRegs LiveRegs;
};
char SystemZShortenInst::ID = 0;
@@ -58,33 +57,31 @@ FunctionPass *llvm::createSystemZShortenInstPass(SystemZTargetMachine &TM) {
}
SystemZShortenInst::SystemZShortenInst(const SystemZTargetMachine &tm)
- : MachineFunctionPass(ID), TII(nullptr), LowGPRs(), HighGPRs() {
- // Set up LowGPRs and HighGPRs.
- for (unsigned I = 0; I < 16; ++I) {
- LowGPRs[SystemZMC::GR32Regs[I]] |= 1 << I;
- LowGPRs[SystemZMC::GR64Regs[I]] |= 1 << I;
- HighGPRs[SystemZMC::GRH32Regs[I]] |= 1 << I;
- HighGPRs[SystemZMC::GR64Regs[I]] |= 1 << I;
- if (unsigned GR128 = SystemZMC::GR128Regs[I]) {
- LowGPRs[GR128] |= 3 << I;
- HighGPRs[GR128] |= 3 << I;
- }
- }
+ : MachineFunctionPass(ID), TII(nullptr) {}
+
+// Tie operands if MI has become a two-address instruction.
+static void tieOpsIfNeeded(MachineInstr &MI) {
+ if (MI.getDesc().getOperandConstraint(0, MCOI::TIED_TO) &&
+ !MI.getOperand(0).isTied())
+ MI.tieOperands(0, 1);
}
// MI loads one word of a GPR using an IIxF instruction and LLIxL and LLIxH
// are the halfword immediate loads for the same word. Try to use one of them
-// instead of IIxF. If MI loads the high word, GPRMap[X] is the set of high
-// words referenced by LLVM register X while LiveOther is the mask of low
-// words that are currently live, and vice versa.
-bool SystemZShortenInst::shortenIIF(MachineInstr &MI, unsigned *GPRMap,
- unsigned LiveOther, unsigned LLIxL,
- unsigned LLIxH) {
+// instead of IIxF.
+bool SystemZShortenInst::shortenIIF(MachineInstr &MI,
+ unsigned LLIxL, unsigned LLIxH) {
unsigned Reg = MI.getOperand(0).getReg();
- assert(Reg < SystemZ::NUM_TARGET_REGS && "Invalid register number");
- unsigned GPRs = GPRMap[Reg];
- assert(GPRs != 0 && "Register must be a GPR");
- if (GPRs & LiveOther)
+ // The new opcode will clear the other half of the GR64 reg, so
+ // cancel if that is live.
+ unsigned thisSubRegIdx = (SystemZ::GRH32BitRegClass.contains(Reg) ?
+ SystemZ::subreg_h32 : SystemZ::subreg_l32);
+ unsigned otherSubRegIdx = (thisSubRegIdx == SystemZ::subreg_l32 ?
+ SystemZ::subreg_h32 : SystemZ::subreg_l32);
+ unsigned GR64BitReg = TRI->getMatchingSuperReg(Reg, thisSubRegIdx,
+ &SystemZ::GR64BitRegClass);
+ unsigned OtherReg = TRI->getSubReg(GR64BitReg, otherSubRegIdx);
+ if (LiveRegs.contains(OtherReg))
return false;
uint64_t Imm = MI.getOperand(1).getImm();
@@ -123,12 +120,26 @@ bool SystemZShortenInst::shortenOn01(MachineInstr &MI, unsigned Opcode) {
}
// Change MI's opcode to Opcode if register operands 0, 1 and 2 have a
-// 4-bit encoding and if operands 0 and 1 are tied.
+// 4-bit encoding and if operands 0 and 1 are tied. Also ties op 0
+// with op 1, if MI becomes 2-address.
bool SystemZShortenInst::shortenOn001(MachineInstr &MI, unsigned Opcode) {
if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
MI.getOperand(1).getReg() == MI.getOperand(0).getReg() &&
SystemZMC::getFirstReg(MI.getOperand(2).getReg()) < 16) {
MI.setDesc(TII->get(Opcode));
+ tieOpsIfNeeded(MI);
+ return true;
+ }
+ return false;
+}
+
+// Calls shortenOn001 if CCLive is false. CC def operand is added in
+// case of success.
+bool SystemZShortenInst::shortenOn001AddCC(MachineInstr &MI,
+ unsigned Opcode) {
+ if (!LiveRegs.contains(SystemZ::CC) && shortenOn001(MI, Opcode)) {
+ MachineInstrBuilder(*MI.getParent()->getParent(), &MI)
+ .addReg(SystemZ::CC, RegState::ImplicitDefine);
return true;
}
return false;
@@ -164,35 +175,24 @@ bool SystemZShortenInst::shortenFPConv(MachineInstr &MI, unsigned Opcode) {
bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
bool Changed = false;
- // Work out which words are live on exit from the block.
- unsigned LiveLow = 0;
- unsigned LiveHigh = 0;
- for (auto SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI) {
- for (auto LI = (*SI)->livein_begin(), LE = (*SI)->livein_end();
- LI != LE; ++LI) {
- unsigned Reg = *LI;
- assert(Reg < SystemZ::NUM_TARGET_REGS && "Invalid register number");
- LiveLow |= LowGPRs[Reg];
- LiveHigh |= HighGPRs[Reg];
- }
- }
+ // Set up the set of live registers at the end of MBB (live out)
+ LiveRegs.clear();
+ LiveRegs.addLiveOuts(&MBB);
// Iterate backwards through the block looking for instructions to change.
for (auto MBBI = MBB.rbegin(), MBBE = MBB.rend(); MBBI != MBBE; ++MBBI) {
MachineInstr &MI = *MBBI;
switch (MI.getOpcode()) {
case SystemZ::IILF:
- Changed |= shortenIIF(MI, LowGPRs, LiveHigh, SystemZ::LLILL,
- SystemZ::LLILH);
+ Changed |= shortenIIF(MI, SystemZ::LLILL, SystemZ::LLILH);
break;
case SystemZ::IIHF:
- Changed |= shortenIIF(MI, HighGPRs, LiveLow, SystemZ::LLIHL,
- SystemZ::LLIHH);
+ Changed |= shortenIIF(MI, SystemZ::LLIHL, SystemZ::LLIHH);
break;
case SystemZ::WFADB:
- Changed |= shortenOn001(MI, SystemZ::ADBR);
+ Changed |= shortenOn001AddCC(MI, SystemZ::ADBR);
break;
case SystemZ::WFDDB:
@@ -216,15 +216,15 @@ bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
break;
case SystemZ::WFLCDB:
- Changed |= shortenOn01(MI, SystemZ::LCDBR);
+ Changed |= shortenOn01(MI, SystemZ::LCDFR);
break;
case SystemZ::WFLNDB:
- Changed |= shortenOn01(MI, SystemZ::LNDBR);
+ Changed |= shortenOn01(MI, SystemZ::LNDFR);
break;
case SystemZ::WFLPDB:
- Changed |= shortenOn01(MI, SystemZ::LPDBR);
+ Changed |= shortenOn01(MI, SystemZ::LPDFR);
break;
case SystemZ::WFSQDB:
@@ -232,7 +232,7 @@ bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
break;
case SystemZ::WFSDB:
- Changed |= shortenOn001(MI, SystemZ::SDBR);
+ Changed |= shortenOn001AddCC(MI, SystemZ::SDBR);
break;
case SystemZ::WFCDB:
@@ -257,33 +257,17 @@ bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
break;
}
- unsigned UsedLow = 0;
- unsigned UsedHigh = 0;
- for (auto MOI = MI.operands_begin(), MOE = MI.operands_end();
- MOI != MOE; ++MOI) {
- MachineOperand &MO = *MOI;
- if (MO.isReg()) {
- if (unsigned Reg = MO.getReg()) {
- assert(Reg < SystemZ::NUM_TARGET_REGS && "Invalid register number");
- if (MO.isDef()) {
- LiveLow &= ~LowGPRs[Reg];
- LiveHigh &= ~HighGPRs[Reg];
- } else if (!MO.isUndef()) {
- UsedLow |= LowGPRs[Reg];
- UsedHigh |= HighGPRs[Reg];
- }
- }
- }
- }
- LiveLow |= UsedLow;
- LiveHigh |= UsedHigh;
+ LiveRegs.stepBackward(MI);
}
return Changed;
}
bool SystemZShortenInst::runOnMachineFunction(MachineFunction &F) {
- TII = static_cast<const SystemZInstrInfo *>(F.getSubtarget().getInstrInfo());
+ const SystemZSubtarget &ST = F.getSubtarget<SystemZSubtarget>();
+ TII = ST.getInstrInfo();
+ TRI = ST.getRegisterInfo();
+ LiveRegs.init(TRI);
bool Changed = false;
for (auto &MBB : F)