mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
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). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178961 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
012ffd5605
commit
839b909653
@ -806,6 +806,74 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
|
|||||||
return false;
|
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
|
/// GetInstSize - Return the number of bytes of code the specified
|
||||||
/// instruction may be. This returns the maximum number of bytes.
|
/// instruction may be. This returns the maximum number of bytes.
|
||||||
///
|
///
|
||||||
|
@ -157,6 +157,9 @@ public:
|
|||||||
virtual
|
virtual
|
||||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
|
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
|
/// GetInstSize - Return the number of bytes of code the specified
|
||||||
/// instruction may be. This returns the maximum number of bytes.
|
/// instruction may be. This returns the maximum number of bytes.
|
||||||
///
|
///
|
||||||
|
@ -76,6 +76,8 @@ PPCRegisterInfo::PPCRegisterInfo(const PPCSubtarget &ST,
|
|||||||
const TargetRegisterClass *
|
const TargetRegisterClass *
|
||||||
PPCRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
|
PPCRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
|
||||||
const {
|
const {
|
||||||
|
// Note that PPCInstrInfo::FoldImmediate also directly uses this Kind value
|
||||||
|
// when it checks for ZERO folding.
|
||||||
if (Kind == 1) {
|
if (Kind == 1) {
|
||||||
if (Subtarget.isPPC64())
|
if (Subtarget.isPPC64())
|
||||||
return &PPC::G8RC_NOX0RegClass;
|
return &PPC::G8RC_NOX0RegClass;
|
||||||
|
14
test/CodeGen/PowerPC/fold-zero.ll
Normal file
14
test/CodeGen/PowerPC/fold-zero.ll
Normal file
@ -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
Block a user