llvm.org GIT mirror llvm / 75e18c4
Clean up ARM PEI code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33389 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
4 changed file(s) with 76 addition(s) and 92 deletion(s). Raw diff Collapse all Expand all
3131 ///
3232 unsigned VarArgsRegSaveSize;
3333
34 /// FramePtrSpilled - True if FP register is spilled. Set by
34 /// HasStackFrame - True if this function has a stack frame. Set by
3535 /// processFunctionBeforeCalleeSavedScan().
36 bool FramePtrSpilled;
36 bool HasStackFrame;
3737
38 /// FramePtrSpillOffset - If FramePtrSpilled, this records the frame pointer
38 /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
3939 /// spill stack offset.
4040 unsigned FramePtrSpillOffset;
4141
7070 public:
7171 ARMFunctionInfo() :
7272 isThumb(false),
73 VarArgsRegSaveSize(0), FramePtrSpilled(false), FramePtrSpillOffset(0),
73 VarArgsRegSaveSize(0), HasStackFrame(false), FramePtrSpillOffset(0),
7474 GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
7575 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
7676
7777 ARMFunctionInfo(MachineFunction &MF) :
7878 isThumb(MF.getTarget().getSubtarget().isThumb()),
79 VarArgsRegSaveSize(0), FramePtrSpilled(false), FramePtrSpillOffset(0),
79 VarArgsRegSaveSize(0), HasStackFrame(false), FramePtrSpillOffset(0),
8080 GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
8181 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
8282
8585 unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
8686 void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }
8787
88 bool isFramePtrSpilled() const { return FramePtrSpilled; }
89 void setFramePtrSpilled(bool s) { FramePtrSpilled = s; }
88 bool hasStackFrame() const { return HasStackFrame; }
89 void setHasStackFrame(bool s) { HasStackFrame = s; }
9090 unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
9191 void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
9292
410410 void ARMRegisterInfo::
411411 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
412412 MachineBasicBlock::iterator I) const {
413 if (MF.getFrameInfo()->hasVarSizedObjects()) {
413 if (hasFP(MF)) {
414414 // If we have alloca, convert as follows:
415415 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
416416 // ADJCALLSTACKUP -> add, sp, sp, amount
479479 Offset -= AFI->getGPRCalleeSavedArea2Offset();
480480 else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex))
481481 Offset -= AFI->getDPRCalleeSavedAreaOffset();
482 else if (MF.getFrameInfo()->hasVarSizedObjects()) {
482 else if (hasFP(MF)) {
483483 // There is alloca()'s in this function, must reference off the frame
484484 // pointer instead.
485485 FrameReg = getFrameRegister(MF);
688688
689689 void ARMRegisterInfo::
690690 processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
691 // This tells PEI to spill the FP as if it is any other callee-save register to
692 // take advantage the eliminateFrameIndex machinery. This also ensures it is
693 // spilled in the order specified by getCalleeSavedRegs() to make it easier
691 // This tells PEI to spill the FP as if it is any other callee-save register
692 // to take advantage the eliminateFrameIndex machinery. This also ensures it
693 // is spilled in the order specified by getCalleeSavedRegs() to make it easier
694694 // to combine multiple loads / stores.
695 bool FramePtrSpilled = MF.getFrameInfo()->hasVarSizedObjects();
695 bool CanEliminateFrame = true;
696696 bool CS1Spilled = false;
697697 bool LRSpilled = false;
698698 unsigned NumGPRSpills = 0;
699699 SmallVector UnspilledCS1GPRs;
700700 SmallVector UnspilledCS2GPRs;
701 if (!FramePtrSpilled && NoFramePointerElim) {
702 // Don't spill FP if the frame can be eliminated. This is determined
703 // by scanning the callee-save registers to see if any is used.
704 const unsigned *CSRegs = getCalleeSavedRegs();
705 const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses();
706 for (unsigned i = 0; CSRegs[i]; ++i) {
707 unsigned Reg = CSRegs[i];
708 bool Spilled = false;
709 if (MF.isPhysRegUsed(Reg)) {
710 Spilled = true;
711 FramePtrSpilled = true;
712 } else {
713 // Check alias registers too.
714 for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
715 if (MF.isPhysRegUsed(*Aliases)) {
716 Spilled = true;
717 FramePtrSpilled = true;
718 }
701
702 // Don't spill FP if the frame can be eliminated. This is determined
703 // by scanning the callee-save registers to see if any is used.
704 const unsigned *CSRegs = getCalleeSavedRegs();
705 const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses();
706 for (unsigned i = 0; CSRegs[i]; ++i) {
707 unsigned Reg = CSRegs[i];
708 bool Spilled = false;
709 if (MF.isPhysRegUsed(Reg)) {
710 Spilled = true;
711 CanEliminateFrame = false;
712 } else {
713 // Check alias registers too.
714 for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
715 if (MF.isPhysRegUsed(*Aliases)) {
716 Spilled = true;
717 CanEliminateFrame = false;
719718 }
720719 }
721
722 if (CSRegClasses[i] == &ARM::GPRRegClass) {
723 if (Spilled) {
724 NumGPRSpills++;
725
726 // Keep track if LR and any of R4, R5, R6, and R7 is spilled.
727 switch (Reg) {
728 case ARM::LR:
729 LRSpilled = true;
730 // Fallthrough
731 case ARM::R4:
732 case ARM::R5:
733 case ARM::R6:
734 case ARM::R7:
735 CS1Spilled = true;
736 break;
737 default:
738 break;
739 }
740 } else {
741 switch (Reg) {
742 case ARM::R4:
743 case ARM::R5:
744 case ARM::R6:
745 case ARM::R7:
746 case ARM::LR:
747 UnspilledCS1GPRs.push_back(Reg);
748 break;
749 default:
750 UnspilledCS2GPRs.push_back(Reg);
751 break;
752 }
720 }
721
722 if (CSRegClasses[i] == &ARM::GPRRegClass) {
723 if (Spilled) {
724 NumGPRSpills++;
725
726 // Keep track if LR and any of R4, R5, R6, and R7 is spilled.
727 switch (Reg) {
728 case ARM::LR:
729 LRSpilled = true;
730 // Fallthrough
731 case ARM::R4:
732 case ARM::R5:
733 case ARM::R6:
734 case ARM::R7:
735 CS1Spilled = true;
736 break;
737 default:
738 break;
739 }
740 } else {
741 switch (Reg) {
742 case ARM::R4:
743 case ARM::R5:
744 case ARM::R6:
745 case ARM::R7:
746 case ARM::LR:
747 UnspilledCS1GPRs.push_back(Reg);
748 break;
749 default:
750 UnspilledCS2GPRs.push_back(Reg);
751 break;
753752 }
754753 }
755754 }
756755 }
757756
758 if (FramePtrSpilled) {
757 if (!CanEliminateFrame) {
759758 ARMFunctionInfo *AFI = MF.getInfo();
760 AFI->setFramePtrSpilled(true);
759 AFI->setHasStackFrame(true);
761760
762761 // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
763762 // Spill LR as well so we can fold BX_RET to the registers restore (LDM).
795794 bool Done = false;
796795 unsigned Category = 0;
797796 switch (MBBI->getOperand(0).getReg()) {
798 case ARM::R4:
799 case ARM::R5:
800 case ARM::R6:
801 case ARM::R7:
797 case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7:
802798 case ARM::LR:
803799 Category = 1;
804800 break;
805 case ARM::R8:
806 case ARM::R9:
807 case ARM::R10:
808 case ARM::R11:
801 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
809802 Category = STI.isTargetDarwin() ? 2 : 1;
810803 break;
811 case ARM::D8:
812 case ARM::D9:
813 case ARM::D10:
814 case ARM::D11:
815 case ARM::D12:
816 case ARM::D13:
817 case ARM::D14:
818 case ARM::D15:
804 case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11:
805 case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
819806 Category = 3;
820807 break;
821808 default:
845832 // belongs to which callee-save spill areas.
846833 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
847834 int FramePtrSpillFI = 0;
848 if (AFI->isFramePtrSpilled()) {
835 if (AFI->hasStackFrame()) {
849836 if (VARegSaveSize)
850837 emitSPUpdate(MBB, MBBI, -VARegSaveSize, isThumb, TII);
851838
908895
909896 // If necessary, add one more SUBri to account for the call frame
910897 // and/or local storage, alloca area.
911 if (MFI->hasCalls())
898 if (MFI->hasCalls() && !hasFP(MF))
912899 // We reserve argument space for call sites in the function immediately on
913900 // entry to the current function. This eliminates the need for add/sub
914901 // brackets around call sites.
915 if (!MF.getFrameInfo()->hasVarSizedObjects())
916 NumBytes += MFI->getMaxCallFrameSize();
902 NumBytes += MFI->getMaxCallFrameSize();
917903
918904 // Round the size to a multiple of the alignment.
919905 NumBytes = (NumBytes+Align-1)/Align*Align;
920906 MFI->setStackSize(NumBytes);
921907
922908 // Determine starting offsets of spill areas.
923 if (AFI->isFramePtrSpilled()) {
909 if (AFI->hasStackFrame()) {
924910 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
925911 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
926912 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
972958 bool isThumb = AFI->isThumbFunction();
973959 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
974960 int NumBytes = (int)MFI->getStackSize();
975 if (AFI->isFramePtrSpilled()) {
961 if (AFI->hasStackFrame()) {
976962 // Unwind MBBI to point to first LDR / FLDD.
977963 const unsigned *CSRegs = getCalleeSavedRegs();
978964 if (MBBI != MBB.begin()) {
165165 I = ARM_GPR_AO_1 + (sizeof(ARM_GPR_AO_1)/sizeof(unsigned));
166166 }
167167
168 return hasFP(MF) ? I-1 : I;
168 // Mac OS X requires FP not to be clobbered for backtracing purpose.
169 return (Subtarget.isTargetDarwin() || hasFP(MF)) ? I-1 : I;
169170 }
170171 }];
171172 }
3333 ///
3434 ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
3535 : Subtarget(M, FS), DataLayout("e-p:32:32-d:32"), InstrInfo(Subtarget),
36 FrameInfo(Subtarget) {
37 if (Subtarget.isTargetDarwin())
38 NoFramePointerElim = true;
39 }
36 FrameInfo(Subtarget) {}
4037
4138 unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
4239 std::string TT = M.getTargetTriple();