forked from OSchip/llvm-project
Implement PPCInstrInfo::FoldImmediate
There are certain PPC instructions into which we can fold a zero immediate operand. We can detect such cases by looking at the register class required by the using operand (so long as it is not otherwise constrained). llvm-svn: 178961
This commit is contained in:
parent
8fc33e5d95
commit
d61d4f80e6
|
@ -806,6 +806,74 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool PPCInstrInfo::FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
|
||||
unsigned Reg, MachineRegisterInfo *MRI) const {
|
||||
// For some instructions, it is legal to fold ZERO into the RA register field.
|
||||
// A zero immediate should always be loaded with a single li.
|
||||
unsigned DefOpc = DefMI->getOpcode();
|
||||
if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
|
||||
return false;
|
||||
if (!DefMI->getOperand(1).isImm())
|
||||
return false;
|
||||
if (DefMI->getOperand(1).getImm() != 0)
|
||||
return false;
|
||||
|
||||
// Note that we cannot here invert the arguments of an isel in order to fold
|
||||
// a ZERO into what is presented as the second argument. All we have here
|
||||
// is the condition bit, and that might come from a CR-logical bit operation.
|
||||
|
||||
const MCInstrDesc &UseMCID = UseMI->getDesc();
|
||||
|
||||
// Only fold into real machine instructions.
|
||||
if (UseMCID.isPseudo())
|
||||
return false;
|
||||
|
||||
unsigned UseIdx;
|
||||
for (UseIdx = 0; UseIdx < UseMI->getNumOperands(); ++UseIdx)
|
||||
if (UseMI->getOperand(UseIdx).isReg() &&
|
||||
UseMI->getOperand(UseIdx).getReg() == Reg)
|
||||
break;
|
||||
|
||||
assert(UseIdx < UseMI->getNumOperands() && "Cannot find Reg in UseMI");
|
||||
assert(UseIdx < UseMCID.getNumOperands() && "No operand description for Reg");
|
||||
|
||||
const MCOperandInfo *UseInfo = &UseMCID.OpInfo[UseIdx];
|
||||
|
||||
// We can fold the zero if this register requires a GPRC_NOR0/G8RC_NOX0
|
||||
// register (which might also be specified as a pointer class kind).
|
||||
if (UseInfo->isLookupPtrRegClass()) {
|
||||
if (UseInfo->RegClass /* Kind */ != 1)
|
||||
return false;
|
||||
} else {
|
||||
if (UseInfo->RegClass != PPC::GPRC_NOR0RegClassID &&
|
||||
UseInfo->RegClass != PPC::G8RC_NOX0RegClassID)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure this is not tied to an output register (or otherwise
|
||||
// constrained). This is true for ST?UX registers, for example, which
|
||||
// are tied to their output registers.
|
||||
if (UseInfo->Constraints != 0)
|
||||
return false;
|
||||
|
||||
unsigned ZeroReg;
|
||||
if (UseInfo->isLookupPtrRegClass()) {
|
||||
bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
|
||||
ZeroReg = isPPC64 ? PPC::ZERO8 : PPC::ZERO;
|
||||
} else {
|
||||
ZeroReg = UseInfo->RegClass == PPC::G8RC_NOX0RegClassID ?
|
||||
PPC::ZERO8 : PPC::ZERO;
|
||||
}
|
||||
|
||||
bool DeleteDef = MRI->hasOneNonDBGUse(Reg);
|
||||
UseMI->getOperand(UseIdx).setReg(ZeroReg);
|
||||
|
||||
if (DeleteDef)
|
||||
DefMI->eraseFromParent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// GetInstSize - Return the number of bytes of code the specified
|
||||
/// instruction may be. This returns the maximum number of bytes.
|
||||
///
|
||||
|
|
|
@ -157,6 +157,9 @@ public:
|
|||
virtual
|
||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
|
||||
|
||||
virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
|
||||
unsigned Reg, MachineRegisterInfo *MRI) const;
|
||||
|
||||
/// GetInstSize - Return the number of bytes of code the specified
|
||||
/// instruction may be. This returns the maximum number of bytes.
|
||||
///
|
||||
|
|
|
@ -76,6 +76,8 @@ PPCRegisterInfo::PPCRegisterInfo(const PPCSubtarget &ST,
|
|||
const TargetRegisterClass *
|
||||
PPCRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
|
||||
const {
|
||||
// Note that PPCInstrInfo::FoldImmediate also directly uses this Kind value
|
||||
// when it checks for ZERO folding.
|
||||
if (Kind == 1) {
|
||||
if (Subtarget.isPPC64())
|
||||
return &PPC::G8RC_NOX0RegClass;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
|
||||
define i32 @test1(i1 %a, i32 %c) nounwind {
|
||||
%x = select i1 %a, i32 %c, i32 0
|
||||
ret i32 %x
|
||||
|
||||
; CHECK: @test1
|
||||
; CHECK-NOT: li {{[0-9]+}}, 0
|
||||
; CHECK: isel 3, 0,
|
||||
; CHECK: blr
|
||||
}
|
||||
|
Loading…
Reference in New Issue