Index: include/llvm/CodeGen/TargetSubtargetInfo.h =================================================================== --- include/llvm/CodeGen/TargetSubtargetInfo.h +++ include/llvm/CodeGen/TargetSubtargetInfo.h @@ -248,6 +248,9 @@ /// Returns string representation of scheduler comment std::string getSchedInfoStr(const MachineInstr &MI) const override; std::string getSchedInfoStr(MCInst const &MCI) const override; + + /// This is called after a .mir file was loaded. + virtual void mirFileLoaded(MachineFunction &MF) const; }; } // end namespace llvm Index: lib/CodeGen/MIRParser/MIRParser.cpp =================================================================== --- lib/CodeGen/MIRParser/MIRParser.cpp +++ lib/CodeGen/MIRParser/MIRParser.cpp @@ -417,6 +417,8 @@ computeFunctionProperties(MF); + MF.getSubtarget().mirFileLoaded(MF); + MF.verify(); return false; } Index: lib/CodeGen/TargetSubtargetInfo.cpp =================================================================== --- lib/CodeGen/TargetSubtargetInfo.cpp +++ lib/CodeGen/TargetSubtargetInfo.cpp @@ -111,3 +111,6 @@ TSchedModel.computeInstrRThroughput(MCI.getOpcode()); return createSchedInfoStr(Latency, RThroughput); } + +void TargetSubtargetInfo::mirFileLoaded(MachineFunction &MF) const { +} Index: lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64FrameLowering.cpp +++ lib/Target/AArch64/AArch64FrameLowering.cpp @@ -190,11 +190,24 @@ const MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); // Retain behavior of always omitting the FP for leaf functions when possible. - return (MFI.hasCalls() && - MF.getTarget().Options.DisableFramePointerElim(MF)) || - MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() || - MFI.hasStackMap() || MFI.hasPatchPoint() || - RegInfo->needsStackRealignment(MF); + if (MFI.hasCalls() && MF.getTarget().Options.DisableFramePointerElim(MF)) + return true; + if (MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() || + MFI.hasStackMap() || MFI.hasPatchPoint() || + RegInfo->needsStackRealignment(MF)) + return true; + // With large callframes around we may need to use FP to access the scavenging + // emergency spillslot. + // + // Unfortunately some calls to hasFP() like machine verifier -> + // getReservedReg() -> hasFP in the middle of global isel are too early + // to know the max call frame size. Hopefully conservatively returning "true" + // in those cases is fine. + // The number 255 is taken from estimateRSStackSizeLimit(). + if (!MFI.isMaxCallFrameSizeComputed() || MFI.getMaxCallFrameSize() > 255) + return true; + + return false; } /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is @@ -1253,6 +1266,7 @@ unsigned Size = TRI->getSpillSize(RC); unsigned Align = TRI->getSpillAlignment(RC); int FI = MFI.CreateStackObject(Size, Align, false); + MFI.setScavSlot(FI); RS->addScavengingFrameIndex(FI); DEBUG(dbgs() << "No available CS registers, allocated fi#" << FI << " as the emergency spill slot.\n"); Index: lib/Target/AArch64/AArch64ISelLowering.h =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.h +++ lib/Target/AArch64/AArch64ISelLowering.h @@ -649,6 +649,8 @@ SelectionDAG &DAG) const override; bool shouldNormalizeToSelectSequence(LLVMContext &, EVT) const override; + + void finalizeLowering(MachineFunction &MF) const override; }; namespace AArch64 { Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -10983,3 +10983,8 @@ return 3 * getPointerTy(DL).getSizeInBits() + 2 * 32; } + +void AArch64TargetLowering::finalizeLowering(MachineFunction &MF) const { + MF.getFrameInfo().computeMaxCallFrameSize(MF); + TargetLoweringBase::finalizeLowering(MF); +} Index: lib/Target/AArch64/AArch64RegisterInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64RegisterInfo.cpp +++ lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -225,11 +225,13 @@ bool AArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { - const MachineFrameInfo &MFI = MF.getFrameInfo(); - // AArch64FrameLowering::resolveFrameIndexReference() can always fall back - // to the stack pointer, so only put the emergency spill slot next to the - // FP when there's no better way to access it (SP or base pointer). - return MFI.hasVarSizedObjects() && !hasBasePointer(MF); + // This function indicates whether the emergency spillslot should be placed + // close to the beginning of the stackframe (closer to FP) or the end + // (closer to SP). + // + // The beginning works most reliably if we have a frame pointer. + const AArch64FrameLowering &TFI = *getFrameLowering(MF); + return TFI.hasFP(MF); } bool AArch64RegisterInfo::requiresFrameIndexScavenging( Index: lib/Target/AArch64/AArch64Subtarget.h =================================================================== --- lib/Target/AArch64/AArch64Subtarget.h +++ lib/Target/AArch64/AArch64Subtarget.h @@ -328,6 +328,8 @@ return false; } } + + void mirFileLoaded(MachineFunction &MF) const override; }; } // End llvm namespace Index: lib/Target/AArch64/AArch64Subtarget.cpp =================================================================== --- lib/Target/AArch64/AArch64Subtarget.cpp +++ lib/Target/AArch64/AArch64Subtarget.cpp @@ -267,3 +267,13 @@ AArch64Subtarget::getCustomPBQPConstraints() const { return balanceFPOps() ? llvm::make_unique() : nullptr; } + +void AArch64Subtarget::mirFileLoaded(MachineFunction &MF) const { + // We usually compute max call frame size after ISel. Do the computation now + // if the .mir file didn't specify it. Note that this will probably give you + // bogus values after PEI has eliminated the callframe setup/destroy pseudo + // instructions, specify explicitely if you need it to be correct. + MachineFrameInfo &MFI = MF.getFrameInfo(); + if (!MFI.isMaxCallFrameSizeComputed()) + MFI.computeMaxCallFrameSize(MF); +}