#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/LLVMContext.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-static cl::opt<bool>
-ForceAllBaseRegAlloc("arm-force-base-reg-alloc", cl::Hidden, cl::init(false),
- cl::desc("Force use of virtual base registers for stack load/store"));
-static cl::opt<bool>
-EnableLocalStackAlloc("enable-local-stack-alloc", cl::init(true), cl::Hidden,
- cl::desc("Enable pre-regalloc stack frame index allocation"));
-static cl::opt<bool>
-EnableBasePointer("arm-use-base-pointer", cl::Hidden, cl::init(true),
- cl::desc("Enable use of a base pointer for complex stack frames"));
-
ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
const ARMSubtarget &sti)
- : ARMGenRegisterInfo(ARM::LR), TII(tii), STI(sti),
+ : ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC), TII(tii), STI(sti),
FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11),
BasePtr(ARM::R6) {
}
}
}
-/// getRawAllocationOrder - Returns the register allocation order for a
-/// specified register class with a target-dependent hint.
-ArrayRef<uint16_t>
-ARMBaseRegisterInfo::getRawAllocationOrder(const TargetRegisterClass *RC,
- unsigned HintType, unsigned HintReg,
- const MachineFunction &MF) const {
- const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
- // Alternative register allocation orders when favoring even / odd registers
- // of register pairs.
-
- // No FP, R9 is available.
- static const uint16_t GPREven1[] = {
- ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
- ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
- ARM::R9, ARM::R11
- };
- static const uint16_t GPROdd1[] = {
- ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R9, ARM::R11,
- ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
- ARM::R8, ARM::R10
- };
-
- // FP is R7, R9 is available.
- static const uint16_t GPREven2[] = {
- ARM::R0, ARM::R2, ARM::R4, ARM::R8, ARM::R10,
- ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6,
- ARM::R9, ARM::R11
- };
- static const uint16_t GPROdd2[] = {
- ARM::R1, ARM::R3, ARM::R5, ARM::R9, ARM::R11,
- ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
- ARM::R8, ARM::R10
- };
-
- // FP is R11, R9 is available.
- static const uint16_t GPREven3[] = {
- ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8,
- ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7,
- ARM::R9
- };
- static const uint16_t GPROdd3[] = {
- ARM::R1, ARM::R3, ARM::R5, ARM::R6, ARM::R9,
- ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R7,
- ARM::R8
- };
-
- // No FP, R9 is not available.
- static const uint16_t GPREven4[] = {
- ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R10,
- ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8,
- ARM::R11
- };
- static const uint16_t GPROdd4[] = {
- ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R11,
- ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
- ARM::R10
- };
-
- // FP is R7, R9 is not available.
- static const uint16_t GPREven5[] = {
- ARM::R0, ARM::R2, ARM::R4, ARM::R10,
- ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, ARM::R8,
- ARM::R11
- };
- static const uint16_t GPROdd5[] = {
- ARM::R1, ARM::R3, ARM::R5, ARM::R11,
- ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
- ARM::R10
- };
-
- // FP is R11, R9 is not available.
- static const uint16_t GPREven6[] = {
- ARM::R0, ARM::R2, ARM::R4, ARM::R6,
- ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8
- };
- static const uint16_t GPROdd6[] = {
- ARM::R1, ARM::R3, ARM::R5, ARM::R7,
- ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
- };
-
- // We only support even/odd hints for GPR and rGPR.
- if (RC != &ARM::GPRRegClass && RC != &ARM::rGPRRegClass)
- return RC->getRawAllocationOrder(MF);
-
- if (HintType == ARMRI::RegPairEven) {
- if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
- // It's no longer possible to fulfill this hint. Return the default
- // allocation order.
- return RC->getRawAllocationOrder(MF);
-
- if (!TFI->hasFP(MF)) {
- if (!STI.isR9Reserved())
- return makeArrayRef(GPREven1);
- else
- return makeArrayRef(GPREven4);
- } else if (FramePtr == ARM::R7) {
- if (!STI.isR9Reserved())
- return makeArrayRef(GPREven2);
- else
- return makeArrayRef(GPREven5);
- } else { // FramePtr == ARM::R11
- if (!STI.isR9Reserved())
- return makeArrayRef(GPREven3);
- else
- return makeArrayRef(GPREven6);
- }
- } else if (HintType == ARMRI::RegPairOdd) {
- if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0)
- // It's no longer possible to fulfill this hint. Return the default
- // allocation order.
- return RC->getRawAllocationOrder(MF);
-
- if (!TFI->hasFP(MF)) {
- if (!STI.isR9Reserved())
- return makeArrayRef(GPROdd1);
- else
- return makeArrayRef(GPROdd4);
- } else if (FramePtr == ARM::R7) {
- if (!STI.isR9Reserved())
- return makeArrayRef(GPROdd2);
- else
- return makeArrayRef(GPROdd5);
- } else { // FramePtr == ARM::R11
- if (!STI.isR9Reserved())
- return makeArrayRef(GPROdd3);
- else
- return makeArrayRef(GPROdd6);
- }
- }
- return RC->getRawAllocationOrder(MF);
-}
-
-/// ResolveRegAllocHint - Resolves the specified register allocation hint
-/// to a physical register. Returns the physical register if it is successful.
-unsigned
-ARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
- const MachineFunction &MF) const {
- if (Reg == 0 || !isPhysicalRegister(Reg))
- return 0;
- if (Type == 0)
- return Reg;
- else if (Type == (unsigned)ARMRI::RegPairOdd)
- // Odd register.
- return getRegisterPairOdd(Reg, MF);
- else if (Type == (unsigned)ARMRI::RegPairEven)
- // Even register.
- return getRegisterPairEven(Reg, MF);
- return 0;
-}
-
void
ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
MachineFunction &MF) const {
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
- if (!EnableBasePointer)
- return false;
-
// When outgoing call frames are so large that we adjust the stack pointer
// around the call, we can no longer use the stack pointer to reach the
// emergency spill slot.
// pointer adjustments around calls.
if (MF.getTarget().getFrameLowering()->hasReservedCallFrame(MF))
return true;
- if (!EnableBasePointer)
- return false;
// A base pointer is required and allowed. Check that it isn't too late to
// reserve it.
return MRI->canReserveReg(BasePtr);
unsigned StackAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
bool requiresRealignment =
((MFI->getMaxAlignment() > StackAlign) ||
- F->getFnAttributes().hasAttribute(Attributes::StackAlignment));
+ F->getFnAttributes().hasAttribute(Attribute::StackAlignment));
return requiresRealignment && canRealignStack(MF);
}
llvm_unreachable("What is the exception handler register");
}
-unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
- const MachineFunction &MF) const {
- const MachineRegisterInfo &MRI = MF.getRegInfo();
- switch (Reg) {
- default: break;
- // Return 0 if either register of the pair is a special register.
- // So no R12, etc.
- case ARM::R1: return ARM::R0;
- case ARM::R3: return ARM::R2;
- case ARM::R5: return ARM::R4;
- case ARM::R7:
- return (MRI.isReserved(ARM::R7) || MRI.isReserved(ARM::R6))
- ? 0 : ARM::R6;
- case ARM::R9: return MRI.isReserved(ARM::R9) ? 0 :ARM::R8;
- case ARM::R11: return MRI.isReserved(ARM::R11) ? 0 : ARM::R10;
-
- case ARM::S1: return ARM::S0;
- case ARM::S3: return ARM::S2;
- case ARM::S5: return ARM::S4;
- case ARM::S7: return ARM::S6;
- case ARM::S9: return ARM::S8;
- case ARM::S11: return ARM::S10;
- case ARM::S13: return ARM::S12;
- case ARM::S15: return ARM::S14;
- case ARM::S17: return ARM::S16;
- case ARM::S19: return ARM::S18;
- case ARM::S21: return ARM::S20;
- case ARM::S23: return ARM::S22;
- case ARM::S25: return ARM::S24;
- case ARM::S27: return ARM::S26;
- case ARM::S29: return ARM::S28;
- case ARM::S31: return ARM::S30;
-
- case ARM::D1: return ARM::D0;
- case ARM::D3: return ARM::D2;
- case ARM::D5: return ARM::D4;
- case ARM::D7: return ARM::D6;
- case ARM::D9: return ARM::D8;
- case ARM::D11: return ARM::D10;
- case ARM::D13: return ARM::D12;
- case ARM::D15: return ARM::D14;
- case ARM::D17: return ARM::D16;
- case ARM::D19: return ARM::D18;
- case ARM::D21: return ARM::D20;
- case ARM::D23: return ARM::D22;
- case ARM::D25: return ARM::D24;
- case ARM::D27: return ARM::D26;
- case ARM::D29: return ARM::D28;
- case ARM::D31: return ARM::D30;
- }
-
- return 0;
-}
-
-unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
- const MachineFunction &MF) const {
- const MachineRegisterInfo &MRI = MF.getRegInfo();
- switch (Reg) {
- default: break;
- // Return 0 if either register of the pair is a special register.
- // So no R12, etc.
- case ARM::R0: return ARM::R1;
- case ARM::R2: return ARM::R3;
- case ARM::R4: return ARM::R5;
- case ARM::R6:
- return (MRI.isReserved(ARM::R7) || MRI.isReserved(ARM::R6))
- ? 0 : ARM::R7;
- case ARM::R8: return MRI.isReserved(ARM::R9) ? 0 :ARM::R9;
- case ARM::R10: return MRI.isReserved(ARM::R11) ? 0 : ARM::R11;
-
- case ARM::S0: return ARM::S1;
- case ARM::S2: return ARM::S3;
- case ARM::S4: return ARM::S5;
- case ARM::S6: return ARM::S7;
- case ARM::S8: return ARM::S9;
- case ARM::S10: return ARM::S11;
- case ARM::S12: return ARM::S13;
- case ARM::S14: return ARM::S15;
- case ARM::S16: return ARM::S17;
- case ARM::S18: return ARM::S19;
- case ARM::S20: return ARM::S21;
- case ARM::S22: return ARM::S23;
- case ARM::S24: return ARM::S25;
- case ARM::S26: return ARM::S27;
- case ARM::S28: return ARM::S29;
- case ARM::S30: return ARM::S31;
-
- case ARM::D0: return ARM::D1;
- case ARM::D2: return ARM::D3;
- case ARM::D4: return ARM::D5;
- case ARM::D6: return ARM::D7;
- case ARM::D8: return ARM::D9;
- case ARM::D10: return ARM::D11;
- case ARM::D12: return ARM::D13;
- case ARM::D14: return ARM::D15;
- case ARM::D16: return ARM::D17;
- case ARM::D18: return ARM::D19;
- case ARM::D20: return ARM::D21;
- case ARM::D22: return ARM::D23;
- case ARM::D24: return ARM::D25;
- case ARM::D26: return ARM::D27;
- case ARM::D28: return ARM::D29;
- case ARM::D30: return ARM::D31;
- }
-
- return 0;
-}
-
/// emitLoadConstPool - Emits a load from constpool to materialize the
/// specified immediate.
void ARMBaseRegisterInfo::
bool ARMBaseRegisterInfo::
requiresVirtualBaseRegisters(const MachineFunction &MF) const {
- return EnableLocalStackAlloc;
+ return true;
}
static void
case ARM::VLDRS: case ARM::VLDRD:
case ARM::VSTRS: case ARM::VSTRD:
case ARM::tSTRspi: case ARM::tLDRspi:
- if (ForceAllBaseRegAlloc)
- return true;
break;
default:
return false;