diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index a96be563846..41f5e461047 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -28,6 +28,7 @@ #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include @@ -297,6 +298,20 @@ ARMRegisterInfo::getCalleeSavedRegClasses() const { return CalleeSavedRegClasses; } +BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + Reserved.set(ARM::SP); + if (STI.isTargetDarwin() || hasFP(MF)) + Reserved.set(FramePtr); + // Some targets reserve R9. + if (STI.isR9Reserved()) + Reserved.set(ARM::R9); + // At PEI time, if LR is used, it will be spilled upon entry. + if (MF.getUsedPhysregs() && !MF.isPhysRegUsed((unsigned)ARM::LR)) + Reserved.set(ARM::LR); + return Reserved; +} + /// hasFP - Return true if the specified function should have a dedicated frame /// pointer register. This is true if the function has variable sized allocas /// or if frame pointer elimination is disabled. diff --git a/lib/Target/ARM/ARMRegisterInfo.h b/lib/Target/ARM/ARMRegisterInfo.h index e46da07b000..d5c8021e7aa 100644 --- a/lib/Target/ARM/ARMRegisterInfo.h +++ b/lib/Target/ARM/ARMRegisterInfo.h @@ -67,6 +67,8 @@ public: const TargetRegisterClass* const* getCalleeSavedRegClasses() const; + BitVector getReservedRegs(const MachineFunction &MF) const; + bool hasFP(const MachineFunction &MF) const; void eliminateCallFramePseudoInstr(MachineFunction &MF, diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp index bee76a2146b..f08195e8beb 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.cpp +++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp @@ -28,6 +28,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include using namespace llvm; @@ -178,6 +179,14 @@ AlphaRegisterInfo::getCalleeSavedRegClasses() const { return CalleeSavedRegClasses; } +BitVector AlphaRegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + Reserved.set(Alpha::R15); + Reserved.set(Alpha::R30); + Reserved.set(Alpha::R31); + return Reserved; +} + //===----------------------------------------------------------------------===// // Stack Frame Processing methods //===----------------------------------------------------------------------===// diff --git a/lib/Target/Alpha/AlphaRegisterInfo.h b/lib/Target/Alpha/AlphaRegisterInfo.h index 5c3f8ecbf68..4629aaa9aec 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.h +++ b/lib/Target/Alpha/AlphaRegisterInfo.h @@ -49,6 +49,8 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo { const TargetRegisterClass* const* getCalleeSavedRegClasses() const; + BitVector getReservedRegs(const MachineFunction &MF) const; + bool hasFP(const MachineFunction &MF) const; void eliminateCallFramePseudoInstr(MachineFunction &MF, diff --git a/lib/Target/IA64/IA64RegisterInfo.cpp b/lib/Target/IA64/IA64RegisterInfo.cpp index cb9918fcb27..f5f82266863 100644 --- a/lib/Target/IA64/IA64RegisterInfo.cpp +++ b/lib/Target/IA64/IA64RegisterInfo.cpp @@ -28,6 +28,7 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/CommandLine.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" using namespace llvm; @@ -106,6 +107,19 @@ IA64RegisterInfo::getCalleeSavedRegClasses() const { return CalleeSavedRegClasses; } +BitVector IA64RegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + Reserved.set(IA64::r0); + Reserved.set(IA64::r1); + Reserved.set(IA64::r2); + Reserved.set(IA64::r5); + Reserved.set(IA64::r12); + Reserved.set(IA64::r13); + Reserved.set(IA64::r22); + Reserved.set(IA64::rp); + return Reserved; +} + //===----------------------------------------------------------------------===// // Stack Frame Processing methods //===----------------------------------------------------------------------===// diff --git a/lib/Target/IA64/IA64RegisterInfo.h b/lib/Target/IA64/IA64RegisterInfo.h index 42a2567bfaa..9a977122304 100644 --- a/lib/Target/IA64/IA64RegisterInfo.h +++ b/lib/Target/IA64/IA64RegisterInfo.h @@ -48,6 +48,8 @@ struct IA64RegisterInfo : public IA64GenRegisterInfo { const TargetRegisterClass* const* getCalleeSavedRegClasses() const; + BitVector getReservedRegs(const MachineFunction &MF) const; + bool hasFP(const MachineFunction &MF) const; void eliminateCallFramePseudoInstr(MachineFunction &MF, diff --git a/lib/Target/MRegisterInfo.cpp b/lib/Target/MRegisterInfo.cpp index 7caaae9d4fa..08039208fe8 100644 --- a/lib/Target/MRegisterInfo.cpp +++ b/lib/Target/MRegisterInfo.cpp @@ -41,7 +41,7 @@ BitVector MRegisterInfo::getAllocatableSet(MachineFunction &MF) const { const TargetRegisterClass *RC = *I; for (TargetRegisterClass::iterator I = RC->allocation_order_begin(MF), E = RC->allocation_order_end(MF); I != E; ++I) - Allocatable[*I] = true; + Allocatable.set(*I); } return Allocatable; } diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 3370c362f98..7553634066e 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -34,6 +34,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include using namespace llvm; @@ -338,6 +339,35 @@ PPCRegisterInfo::getCalleeSavedRegClasses() const { Darwin32_CalleeSavedRegClasses; } +// needsFP - Return true if the specified function should have a dedicated frame +// pointer register. This is true if the function has variable sized allocas or +// if frame pointer elimination is disabled. +// +static bool needsFP(const MachineFunction &MF) { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + return NoFramePointerElim || MFI->hasVarSizedObjects(); +} + +BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + Reserved.set(PPC::R0); + Reserved.set(PPC::R1); + Reserved.set(PPC::LR); + // In Linux, r2 is reserved for the OS. + if (!Subtarget.isDarwin()) + Reserved.set(PPC::R2); + // On PPC64, r13 is the thread pointer. Never allocate this register. + // Note that this is overconservative, as it also prevents allocation of + // R31 when the FP is not needed. + if (Subtarget.isPPC64()) { + Reserved.set(PPC::R13); + Reserved.set(PPC::R31); + } + if (needsFP(MF)) + Reserved.set(PPC::R31); + return Reserved; +} + /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. MachineInstr *PPCRegisterInfo::foldMemoryOperand(MachineInstr *MI, @@ -398,15 +428,6 @@ MachineInstr *PPCRegisterInfo::foldMemoryOperand(MachineInstr *MI, // Stack Frame Processing methods //===----------------------------------------------------------------------===// -// needsFP - Return true if the specified function should have a dedicated frame -// pointer register. This is true if the function has variable sized allocas or -// if frame pointer elimination is disabled. -// -static bool needsFP(const MachineFunction &MF) { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); -} - // hasFP - Return true if the specified function actually has a dedicated frame // pointer register. This is true if the function needs a frame pointer and has // a non-zero stack size. diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index f8344de6ac1..6c30f6b2a5d 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -58,6 +58,8 @@ public: const TargetRegisterClass* const* getCalleeSavedRegClasses() const; + BitVector getReservedRegs(const MachineFunction &MF) const; + /// targetHandlesStackFrameRounding - Returns true if the target is /// responsible for rounding up the stack frame (probably at emitPrologue /// time). diff --git a/lib/Target/Sparc/SparcRegisterInfo.cpp b/lib/Target/Sparc/SparcRegisterInfo.cpp index 3cb5e502f90..dab0b1037d1 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.cpp +++ b/lib/Target/Sparc/SparcRegisterInfo.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineLocation.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Type.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" using namespace llvm; @@ -116,6 +117,22 @@ const unsigned* SparcRegisterInfo::getCalleeSavedRegs() const { return CalleeSavedRegs; } +BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + Reserved.set(SP::G2); + Reserved.set(SP::G3); + Reserved.set(SP::G4); + Reserved.set(SP::O6); + Reserved.set(SP::I6); + Reserved.set(SP::I7); + Reserved.set(SP::G0); + Reserved.set(SP::G5); + Reserved.set(SP::G6); + Reserved.set(SP::G7); + return Reserved; +} + + const TargetRegisterClass* const* SparcRegisterInfo::getCalleeSavedRegClasses() const { static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 0 }; diff --git a/lib/Target/Sparc/SparcRegisterInfo.h b/lib/Target/Sparc/SparcRegisterInfo.h index 6f80339c018..763156a70c0 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.h +++ b/lib/Target/Sparc/SparcRegisterInfo.h @@ -52,6 +52,8 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo { const TargetRegisterClass* const* getCalleeSavedRegClasses() const; + BitVector getReservedRegs(const MachineFunction &MF) const; + bool hasFP(const MachineFunction &MF) const; void eliminateCallFramePseudoInstr(MachineFunction &MF, diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 50fb0917272..65e847e0dbb 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -31,6 +31,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" using namespace llvm; @@ -883,6 +884,21 @@ X86RegisterInfo::getCalleeSavedRegClasses() const { return Is64Bit ? CalleeSavedRegClasses64Bit : CalleeSavedRegClasses32Bit; } +BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + Reserved.set(X86::RSP); + Reserved.set(X86::ESP); + Reserved.set(X86::SP); + Reserved.set(X86::SPL); + if (hasFP(MF)) { + Reserved.set(X86::RBP); + Reserved.set(X86::EBP); + Reserved.set(X86::BP); + Reserved.set(X86::BPL); + } + return Reserved; +} + //===----------------------------------------------------------------------===// // Stack Frame Processing methods //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index 0066fb6e1ec..d504675b058 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -78,6 +78,12 @@ public: /// length of this list match the getCalleeSavedRegs() list. const TargetRegisterClass* const* getCalleeSavedRegClasses() const; + /// getReservedRegs - Returns a bitset indexed by physical register number + /// indicating if a register is a special register that has particular uses and + /// should be considered unavailable at all times, e.g. SP, RA. This is used by + /// register scavenger to determine what registers are free. + BitVector getReservedRegs(const MachineFunction &MF) const; + bool hasFP(const MachineFunction &MF) const; void eliminateCallFramePseudoInstr(MachineFunction &MF,