diff options
author | Lei Huang <lei@ca.ibm.com> | 2019-05-14 14:27:06 +0000 |
---|---|---|
committer | Lei Huang <lei@ca.ibm.com> | 2019-05-14 14:27:06 +0000 |
commit | 22561972af4793ccf156aa2425adfd1daeabf6c6 (patch) | |
tree | 5e4605b522f1657abed679c41d8c57bb3cc36ea9 /llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | |
parent | 9e88a26863745ae7bf7f919cd6b4a731eafce8ea (diff) | |
download | bcm5719-llvm-22561972af4793ccf156aa2425adfd1daeabf6c6.tar.gz bcm5719-llvm-22561972af4793ccf156aa2425adfd1daeabf6c6.zip |
[PowerPC] Custom lower known CR bit spills
For known CRBit spills, CRSET/CRUNSET, it is more efficient to load and spill
the known value instead of extracting the bit.
eg. This sequence is currently used to spill a CRUNSET:
crclr 4*cr5+lt
mfocrf r3,4
rlwinm r3,r3,20,0,0
stw r3,132(r1)
This patch custom lower it to:
li r3,0
stw r3,132(r1)
Differential Revision: https://reviews.llvm.org/D61754
llvm-svn: 360677
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index 64919a26036..1f36d67b09f 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -70,6 +70,12 @@ StackPtrConst("ppc-stack-ptr-caller-preserved", "caller preserved registers can be LICM candidates"), cl::init(true), cl::Hidden); +static cl::opt<unsigned> +MaxCRBitSpillDist("ppc-max-crbit-spill-dist", + cl::desc("Maximum search distance for definition of CR bit " + "spill on ppc"), + cl::Hidden, cl::init(100)); + static unsigned offsetMinAlignForOpcode(unsigned OpC); PPCRegisterInfo::PPCRegisterInfo(const PPCTargetMachine &TM) @@ -710,6 +716,7 @@ void PPCRegisterInfo::lowerCRBitSpilling(MachineBasicBlock::iterator II, MachineFunction &MF = *MBB.getParent(); const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>(); const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + const TargetRegisterInfo* TRI = Subtarget.getRegisterInfo(); DebugLoc dl = MI.getDebugLoc(); bool LP64 = TM.isPPC64(); @@ -719,27 +726,59 @@ void PPCRegisterInfo::lowerCRBitSpilling(MachineBasicBlock::iterator II, unsigned Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC); unsigned SrcReg = MI.getOperand(0).getReg(); - // We need to move the CR field that contains the CR bit we are spilling. - // The super register may not be explicitly defined (i.e. it can be defined - // by a CR-logical that only defines the subreg) so we state that the CR - // field is undef. Also, in order to preserve the kill flag on the CR bit, - // we add it as an implicit use. - BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MFOCRF8 : PPC::MFOCRF), Reg) + // Search up the BB to find the definition of the CR bit. + MachineBasicBlock::reverse_iterator Ins; + unsigned CRBitSpillDistance = 0; + for (Ins = MI; Ins != MBB.rend(); Ins++) { + // Definition found. + if (Ins->modifiesRegister(SrcReg, TRI)) + break; + // Unable to find CR bit definition within maximum search distance. + if (CRBitSpillDistance == MaxCRBitSpillDist) { + Ins = MI; + break; + } + // Skip debug instructions when counting CR bit spill distance. + if (!Ins->isDebugInstr()) + CRBitSpillDistance++; + } + + // Unable to find the definition of the CR bit in the MBB. + if (Ins == MBB.rend()) + Ins = MI; + + // There is no need to extract the CR bit if its value is already known. + switch (Ins->getOpcode()) { + case PPC::CRUNSET: + BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::LI8 : PPC::LI), Reg) + .addImm(0); + break; + case PPC::CRSET: + BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::LIS8 : PPC::LIS), Reg) + .addImm(-32768); + break; + default: + // We need to move the CR field that contains the CR bit we are spilling. + // The super register may not be explicitly defined (i.e. it can be defined + // by a CR-logical that only defines the subreg) so we state that the CR + // field is undef. Also, in order to preserve the kill flag on the CR bit, + // we add it as an implicit use. + BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MFOCRF8 : PPC::MFOCRF), Reg) .addReg(getCRFromCRBit(SrcReg), RegState::Undef) .addReg(SrcReg, RegState::Implicit | getKillRegState(MI.getOperand(0).isKill())); - // If the saved register wasn't CR0LT, shift the bits left so that the bit to - // store is the first one. Mask all but that bit. - unsigned Reg1 = Reg; - Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC); - - // rlwinm rA, rA, ShiftBits, 0, 0. - BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::RLWINM8 : PPC::RLWINM), Reg) - .addReg(Reg1, RegState::Kill) - .addImm(getEncodingValue(SrcReg)) - .addImm(0).addImm(0); + // If the saved register wasn't CR0LT, shift the bits left so that the bit + // to store is the first one. Mask all but that bit. + unsigned Reg1 = Reg; + Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC); + // rlwinm rA, rA, ShiftBits, 0, 0. + BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::RLWINM8 : PPC::RLWINM), Reg) + .addReg(Reg1, RegState::Kill) + .addImm(getEncodingValue(SrcReg)) + .addImm(0).addImm(0); + } addFrameReference(BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::STW8 : PPC::STW)) .addReg(Reg, RegState::Kill), FrameIndex); |