Changeset View
Changeset View
Standalone View
Standalone View
llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | EnableGPRToVecSpills("ppc-enable-gpr-to-vsr-spills", cl::Hidden, cl::init(false), | ||||
cl::desc("Enable spills from gpr to vsr rather than stack")); | cl::desc("Enable spills from gpr to vsr rather than stack")); | ||||
static cl::opt<bool> | static cl::opt<bool> | ||||
StackPtrConst("ppc-stack-ptr-caller-preserved", | StackPtrConst("ppc-stack-ptr-caller-preserved", | ||||
cl::desc("Consider R1 caller preserved so stack saves of " | cl::desc("Consider R1 caller preserved so stack saves of " | ||||
"caller preserved registers can be LICM candidates"), | "caller preserved registers can be LICM candidates"), | ||||
cl::init(true), cl::Hidden); | cl::init(true), cl::Hidden); | ||||
static unsigned offsetMinAlignForOpcode(unsigned OpC); | |||||
PPCRegisterInfo::PPCRegisterInfo(const PPCTargetMachine &TM) | PPCRegisterInfo::PPCRegisterInfo(const PPCTargetMachine &TM) | ||||
: PPCGenRegisterInfo(TM.isPPC64() ? PPC::LR8 : PPC::LR, | : PPCGenRegisterInfo(TM.isPPC64() ? PPC::LR8 : PPC::LR, | ||||
TM.isPPC64() ? 0 : 1, | TM.isPPC64() ? 0 : 1, | ||||
TM.isPPC64() ? 0 : 1), | TM.isPPC64() ? 0 : 1), | ||||
TM(TM) { | TM(TM) { | ||||
ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX; | ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX; | ||||
ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX; | ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX; | ||||
ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX; | ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX; | ||||
▲ Show 20 Lines • Show All 229 Lines • ▼ Show 20 Lines | if (!Subtarget.hasAltivec()) | ||||
for (TargetRegisterClass::iterator I = PPC::VRRCRegClass.begin(), | for (TargetRegisterClass::iterator I = PPC::VRRCRegClass.begin(), | ||||
IE = PPC::VRRCRegClass.end(); I != IE; ++I) | IE = PPC::VRRCRegClass.end(); I != IE; ++I) | ||||
markSuperRegs(Reserved, *I); | markSuperRegs(Reserved, *I); | ||||
assert(checkAllSuperRegsMarked(Reserved)); | assert(checkAllSuperRegsMarked(Reserved)); | ||||
return Reserved; | return Reserved; | ||||
} | } | ||||
bool PPCRegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) const { | |||||
const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>(); | |||||
const PPCInstrInfo *InstrInfo = Subtarget.getInstrInfo(); | |||||
const MachineFrameInfo &MFI = MF.getFrameInfo(); | |||||
const std::vector<CalleeSavedInfo> &Info = MFI.getCalleeSavedInfo(); | |||||
// If the callee saved info is invalid we have to default to true for safety. | |||||
if (!MFI.isCalleeSavedInfoValid()) | |||||
return true; | |||||
// We will require the use of X-Forms because the frame is larger than what | |||||
// can be represented in signed 16 bits that fit in the immediate of a D-Form. | |||||
// If we need an X-Form then we need a register to store the address offset. | |||||
unsigned FrameSize = MFI.getStackSize(); | |||||
// Signed 16 bits means that the FrameSize cannot be more than 15 bits. | |||||
if (FrameSize & ~0x7FFF) | |||||
return true; | |||||
// The callee saved info is valid so it can be traversed. | |||||
// Checking for registers that need saving that do not have load or store | |||||
// forms where the address offset is an immediate. | |||||
for (unsigned i = 0; i < Info.size(); i++) { | |||||
int FrIdx = Info[i].getFrameIdx(); | |||||
unsigned Reg = Info[i].getReg(); | |||||
unsigned Opcode = InstrInfo->getStoreOpcodeForSpill(Reg); | |||||
if (!MFI.isFixedObjectIndex(FrIdx)) { | |||||
// This is not a fixed object. If it requires alignment then we may still | |||||
// need to use the XForm. | |||||
if (offsetMinAlignForOpcode(Opcode) > 1) | |||||
return true; | |||||
} | |||||
// This is eiher: | |||||
// 1) A fixed frame index object which we know are aligned so | |||||
// as long as we have a valid DForm/DSForm/DQForm (non XForm) we don't | |||||
// need to consider the alignement here. | |||||
// 2) A not fixed object but in that case we now know that the min required | |||||
// alignment is no more than 1 based on the previous check. | |||||
if (InstrInfo->isXFormMemOp(Opcode)) | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
bool PPCRegisterInfo::isCallerPreservedPhysReg(unsigned PhysReg, | bool PPCRegisterInfo::isCallerPreservedPhysReg(unsigned PhysReg, | ||||
const MachineFunction &MF) const { | const MachineFunction &MF) const { | ||||
assert(TargetRegisterInfo::isPhysicalRegister(PhysReg)); | assert(TargetRegisterInfo::isPhysicalRegister(PhysReg)); | ||||
const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>(); | const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>(); | ||||
const MachineFrameInfo &MFI = MF.getFrameInfo(); | const MachineFrameInfo &MFI = MF.getFrameInfo(); | ||||
if (!TM.isPPC64()) | if (!TM.isPPC64()) | ||||
return false; | return false; | ||||
▲ Show 20 Lines • Show All 494 Lines • ▼ Show 20 Lines | else { | ||||
FrameIdx = FI->getCRSpillFrameIndex(); | FrameIdx = FI->getCRSpillFrameIndex(); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
// If the offset must be a multiple of some value, return what that value is. | // If the offset must be a multiple of some value, return what that value is. | ||||
static unsigned offsetMinAlign(const MachineInstr &MI) { | static unsigned offsetMinAlignForOpcode(unsigned OpC) { | ||||
unsigned OpC = MI.getOpcode(); | |||||
switch (OpC) { | switch (OpC) { | ||||
default: | default: | ||||
return 1; | return 1; | ||||
case PPC::LWA: | case PPC::LWA: | ||||
case PPC::LWA_32: | case PPC::LWA_32: | ||||
case PPC::LD: | case PPC::LD: | ||||
case PPC::LDU: | case PPC::LDU: | ||||
case PPC::STD: | case PPC::STD: | ||||
case PPC::STDU: | case PPC::STDU: | ||||
case PPC::DFLOADf32: | case PPC::DFLOADf32: | ||||
case PPC::DFLOADf64: | case PPC::DFLOADf64: | ||||
case PPC::DFSTOREf32: | case PPC::DFSTOREf32: | ||||
case PPC::DFSTOREf64: | case PPC::DFSTOREf64: | ||||
case PPC::LXSD: | case PPC::LXSD: | ||||
case PPC::LXSSP: | case PPC::LXSSP: | ||||
case PPC::STXSD: | case PPC::STXSD: | ||||
case PPC::STXSSP: | case PPC::STXSSP: | ||||
return 4; | return 4; | ||||
case PPC::LXV: | case PPC::LXV: | ||||
case PPC::STXV: | case PPC::STXV: | ||||
return 16; | return 16; | ||||
} | } | ||||
} | } | ||||
// If the offset must be a multiple of some value, return what that value is. | |||||
static unsigned offsetMinAlign(const MachineInstr &MI) { | |||||
unsigned OpC = MI.getOpcode(); | |||||
return offsetMinAlignForOpcode(OpC); | |||||
} | |||||
// Return the OffsetOperandNo given the FIOperandNum (and the instruction). | // Return the OffsetOperandNo given the FIOperandNum (and the instruction). | ||||
static unsigned getOffsetONFromFION(const MachineInstr &MI, | static unsigned getOffsetONFromFION(const MachineInstr &MI, | ||||
unsigned FIOperandNum) { | unsigned FIOperandNum) { | ||||
// Take into account whether it's an add or mem instruction | // Take into account whether it's an add or mem instruction | ||||
unsigned OffsetOperandNo = (FIOperandNum == 2) ? 1 : 2; | unsigned OffsetOperandNo = (FIOperandNum == 2) ? 1 : 2; | ||||
if (MI.isInlineAsm()) | if (MI.isInlineAsm()) | ||||
OffsetOperandNo = FIOperandNum - 1; | OffsetOperandNo = FIOperandNum - 1; | ||||
else if (MI.getOpcode() == TargetOpcode::STACKMAP || | else if (MI.getOpcode() == TargetOpcode::STACKMAP || | ||||
▲ Show 20 Lines • Show All 212 Lines • ▼ Show 20 Lines | needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { | ||||
// Don't generate a new virtual base register just to add zero to it. | // Don't generate a new virtual base register just to add zero to it. | ||||
if ((OpC == PPC::ADDI || OpC == PPC::ADDI8) && | if ((OpC == PPC::ADDI || OpC == PPC::ADDI8) && | ||||
MI->getOperand(2).getImm() == 0) | MI->getOperand(2).getImm() == 0) | ||||
return false; | return false; | ||||
MachineBasicBlock &MBB = *MI->getParent(); | MachineBasicBlock &MBB = *MI->getParent(); | ||||
MachineFunction &MF = *MBB.getParent(); | MachineFunction &MF = *MBB.getParent(); | ||||
const PPCFrameLowering *TFI = getFrameLowering(MF); | const PPCFrameLowering *TFI = getFrameLowering(MF); | ||||
unsigned StackEst = TFI->determineFrameLayout(MF, false, true); | unsigned StackEst = TFI->determineFrameLayout(MF, true); | ||||
// If we likely don't need a stack frame, then we probably don't need a | // If we likely don't need a stack frame, then we probably don't need a | ||||
// virtual base register either. | // virtual base register either. | ||||
if (!StackEst) | if (!StackEst) | ||||
return false; | return false; | ||||
// Estimate an offset from the stack pointer. | // Estimate an offset from the stack pointer. | ||||
// The incoming offset is relating to the SP at the start of the function, | // The incoming offset is relating to the SP at the start of the function, | ||||
▲ Show 20 Lines • Show All 75 Lines • Show Last 20 Lines |