Index: llvm/include/llvm/CodeGen/MachineFunction.h =================================================================== --- llvm/include/llvm/CodeGen/MachineFunction.h +++ llvm/include/llvm/CodeGen/MachineFunction.h @@ -103,6 +103,22 @@ static Ty *create(BumpPtrAllocator &Allocator, MachineFunction &MF) { return new (Allocator.Allocate()) Ty(MF); } + + template + static Ty *create(BumpPtrAllocator &Allocator, const Ty &MFI) { + return new (Allocator.Allocate()) Ty(MFI); + } + + /// Make a functionally equivalent copy of this MachineFunctionInfo in \p MF. + /// This requires remapping MachineBasicBlock references from the original + /// parent to values in the new function. Targets may assume that virtual + /// register and frame index values are preserved in the new function. + virtual MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return nullptr; + } }; /// Properties which a MachineFunction may have at a given point in time. @@ -741,6 +757,21 @@ return const_cast(this)->getInfo(); } + template Ty *cloneInfo(const Ty &Old) { + assert(!MFInfo); + MFInfo = Ty::template create(Allocator, Old); + return static_cast(MFInfo); + } + + MachineFunctionInfo *cloneInfoFrom( + const MachineFunction &OrigMF, + const DenseMap &Src2DstMBB) { + assert(!MFInfo && "new function already has MachineFunctionInfo"); + if (!OrigMF.MFInfo) + return nullptr; + return OrigMF.MFInfo->clone(Allocator, *this, Src2DstMBB); + } + /// Returns the denormal handling type for the default rounding mode of the /// function. DenormalMode getDenormalMode(const fltSemantics &FPType) const; Index: llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h =================================================================== --- llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -37,7 +37,7 @@ /// contains private AArch64-specific information for each MachineFunction. class AArch64FunctionInfo final : public MachineFunctionInfo { /// Backreference to the machine function. - MachineFunction &MF; + MachineFunction *MF; /// Number of bytes of arguments this function has on the stack. If the callee /// is expected to restore the argument stack this should be a multiple of 16, @@ -184,6 +184,11 @@ public: explicit AArch64FunctionInfo(MachineFunction &MF); + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + void initializeBaseYamlFields(const yaml::AArch64FunctionInfo &YamlMFI); unsigned getBytesInStackArgArea() const { return BytesInStackArgArea; } Index: llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp +++ llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp @@ -80,13 +80,13 @@ return Key.equals_insensitive("b_key"); } -AArch64FunctionInfo::AArch64FunctionInfo(MachineFunction &MF) : MF(MF) { +AArch64FunctionInfo::AArch64FunctionInfo(MachineFunction &MF_) : MF(&MF_) { // If we already know that the function doesn't have a redzone, set // HasRedZone here. - if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone)) + if (MF->getFunction().hasFnAttribute(Attribute::NoRedZone)) HasRedZone = false; - const Function &F = MF.getFunction(); + const Function &F = MF->getFunction(); std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F); SignWithBKey = ShouldSignWithBKey(F); @@ -104,6 +104,15 @@ BranchTargetEnforcement = BTIEnable.equals_insensitive("true"); } +MachineFunctionInfo *AArch64FunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + AArch64FunctionInfo *InfoClone = DestMF.cloneInfo(*this); + InfoClone->MF = &DestMF; + return InfoClone; +} + bool AArch64FunctionInfo::shouldSignReturnAddress(bool SpillsLR) const { if (!SignReturnAddress) return false; @@ -114,21 +123,21 @@ bool AArch64FunctionInfo::shouldSignReturnAddress() const { return shouldSignReturnAddress(llvm::any_of( - MF.getFrameInfo().getCalleeSavedInfo(), + MF->getFrameInfo().getCalleeSavedInfo(), [](const auto &Info) { return Info.getReg() == AArch64::LR; })); } bool AArch64FunctionInfo::needsDwarfUnwindInfo() const { if (!NeedsDwarfUnwindInfo) - NeedsDwarfUnwindInfo = MF.needsFrameMoves() && - !MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); + NeedsDwarfUnwindInfo = MF->needsFrameMoves() && + !MF->getTarget().getMCAsmInfo()->usesWindowsCFI(); return *NeedsDwarfUnwindInfo; } bool AArch64FunctionInfo::needsAsyncDwarfUnwindInfo() const { if (!NeedsAsyncDwarfUnwindInfo) { - const Function &F = MF.getFunction(); + const Function &F = MF->getFunction(); // The check got "minsize" is because epilogue unwind info is not emitted // (yet) for homogeneous epilogues, outlined functions, and functions // outlined from. Index: llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -540,6 +540,12 @@ public: SIMachineFunctionInfo(const MachineFunction &MF); + SIMachineFunctionInfo(const SIMachineFunctionInfo &MFI) = default; + + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI, const MachineFunction &MF, Index: llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp +++ llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp @@ -197,6 +197,13 @@ } } +MachineFunctionInfo *SIMachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} + void SIMachineFunctionInfo::limitOccupancy(const MachineFunction &MF) { limitOccupancy(getMaxWavesPerEU()); const GCNSubtarget& ST = MF.getSubtarget(); Index: llvm/lib/Target/ARC/ARCMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/ARC/ARCMachineFunctionInfo.h +++ llvm/lib/Target/ARC/ARCMachineFunctionInfo.h @@ -34,9 +34,13 @@ explicit ARCFunctionInfo(MachineFunction &MF) : ReturnStackOffsetSet(false), VarArgsFrameIndex(0), ReturnStackOffset(-1U), MaxCallStackReq(0) {} - ~ARCFunctionInfo() {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + void setVarArgsFrameIndex(int off) { VarArgsFrameIndex = off; } int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } Index: llvm/lib/Target/ARC/ARCMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/ARC/ARCMachineFunctionInfo.cpp +++ llvm/lib/Target/ARC/ARCMachineFunctionInfo.cpp @@ -11,3 +11,10 @@ using namespace llvm; void ARCFunctionInfo::anchor() {} + +MachineFunctionInfo * +ARCFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap + &Src2DstMBB) const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/ARM/ARMMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/ARM/ARMMachineFunctionInfo.h +++ llvm/lib/Target/ARM/ARMMachineFunctionInfo.h @@ -158,6 +158,11 @@ explicit ARMFunctionInfo(MachineFunction &MF); + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + bool isThumbFunction() const { return isThumb; } bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; } bool isThumb2Function() const { return isThumb && hasThumb2; } Index: llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp +++ llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp @@ -73,3 +73,10 @@ std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(MF.getFunction()); } + +MachineFunctionInfo * +ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap + &Src2DstMBB) const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/AVR/AVRMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/AVR/AVRMachineFunctionInfo.h +++ llvm/lib/Target/AVR/AVRMachineFunctionInfo.h @@ -61,6 +61,13 @@ MF.getFunction().hasFnAttribute("signal"); } + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override { + return DestMF.cloneInfo(*this); + } + bool getHasSpills() const { return HasSpills; } void setHasSpills(bool B) { HasSpills = B; } Index: llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h +++ llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h @@ -33,6 +33,13 @@ public: CSKYMachineFunctionInfo(MachineFunction &) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override { + return DestMF.cloneInfo(*this); + } + Register getGlobalBaseReg() const { return GlobalBaseReg; } void setGlobalBaseReg(Register Reg) { GlobalBaseReg = Reg; } Index: llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.h +++ llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.h @@ -42,6 +42,10 @@ HexagonMachineFunctionInfo() = default; HexagonMachineFunctionInfo(MachineFunction &MF) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; unsigned getSRetReturnReg() const { return SRetReturnReg; } void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } Index: llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.cpp +++ llvm/lib/Target/Hexagon/HexagonMachineFunctionInfo.cpp @@ -13,3 +13,9 @@ // pin vtable to this file void HexagonMachineFunctionInfo::anchor() {} +MachineFunctionInfo *HexagonMachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/Lanai/LanaiMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/Lanai/LanaiMachineFunctionInfo.h +++ llvm/lib/Target/Lanai/LanaiMachineFunctionInfo.h @@ -40,6 +40,10 @@ public: explicit LanaiMachineFunctionInfo(MachineFunction &MF) : VarArgsFrameIndex(0) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; Register getSRetReturnReg() const { return SRetReturnReg; } void setSRetReturnReg(Register Reg) { SRetReturnReg = Reg; } Index: llvm/lib/Target/Lanai/LanaiMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/Lanai/LanaiMachineFunctionInfo.cpp +++ llvm/lib/Target/Lanai/LanaiMachineFunctionInfo.cpp @@ -11,3 +11,10 @@ using namespace llvm; void LanaiMachineFunctionInfo::anchor() {} + +MachineFunctionInfo *LanaiMachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h +++ llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h @@ -35,6 +35,13 @@ public: LoongArchMachineFunctionInfo(const MachineFunction &MF) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override { + return DestMF.cloneInfo(*this); + } + int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } Index: llvm/lib/Target/M68k/M68kMachineFunction.h =================================================================== --- llvm/lib/Target/M68k/M68kMachineFunction.h +++ llvm/lib/Target/M68k/M68kMachineFunction.h @@ -21,8 +21,6 @@ namespace llvm { class M68kMachineFunctionInfo : public MachineFunctionInfo { - MachineFunction &MF; - /// Non-zero if the function has base pointer and makes call to /// llvm.eh.sjlj.setjmp. When non-zero, the value is a displacement from the /// frame pointer to a slot where the base pointer is stashed. @@ -68,7 +66,12 @@ unsigned ArgumentStackSize = 0; public: - explicit M68kMachineFunctionInfo(MachineFunction &MF) : MF(MF) {} + explicit M68kMachineFunctionInfo() = default; + + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; bool getRestoreBasePointer() const { return RestoreBasePointerOffset != 0; } void setRestoreBasePointer(const MachineFunction *MF); Index: llvm/lib/Target/M68k/M68kMachineFunction.cpp =================================================================== --- llvm/lib/Target/M68k/M68kMachineFunction.cpp +++ llvm/lib/Target/M68k/M68kMachineFunction.cpp @@ -18,3 +18,10 @@ using namespace llvm; void M68kMachineFunctionInfo::anchor() {} + +MachineFunctionInfo *M68kMachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/MSP430/MSP430MachineFunctionInfo.h =================================================================== --- llvm/lib/Target/MSP430/MSP430MachineFunctionInfo.h +++ llvm/lib/Target/MSP430/MSP430MachineFunctionInfo.h @@ -43,6 +43,11 @@ explicit MSP430MachineFunctionInfo(MachineFunction &MF) : CalleeSavedFrameSize(0), ReturnAddrIndex(0), SRetReturnReg(0) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; } void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; } Index: llvm/lib/Target/MSP430/MSP430MachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/MSP430/MSP430MachineFunctionInfo.cpp +++ llvm/lib/Target/MSP430/MSP430MachineFunctionInfo.cpp @@ -11,3 +11,10 @@ using namespace llvm; void MSP430MachineFunctionInfo::anchor() { } + +MachineFunctionInfo *MSP430MachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/Mips/MipsMachineFunction.h =================================================================== --- llvm/lib/Target/Mips/MipsMachineFunction.h +++ llvm/lib/Target/Mips/MipsMachineFunction.h @@ -26,6 +26,11 @@ public: MipsFunctionInfo(MachineFunction &MF) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + ~MipsFunctionInfo() override; unsigned getSRetReturnReg() const { return SRetReturnReg; } Index: llvm/lib/Target/Mips/MipsMachineFunction.cpp =================================================================== --- llvm/lib/Target/Mips/MipsMachineFunction.cpp +++ llvm/lib/Target/Mips/MipsMachineFunction.cpp @@ -22,6 +22,13 @@ FixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true), cl::desc("Always use $gp as the global base register.")); +MachineFunctionInfo * +MipsFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap + &Src2DstMBB) const { + return DestMF.cloneInfo(*this); +} + MipsFunctionInfo::~MipsFunctionInfo() = default; bool MipsFunctionInfo::globalBaseRegSet() const { Index: llvm/lib/Target/NVPTX/NVPTXMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/NVPTX/NVPTXMachineFunctionInfo.h +++ llvm/lib/Target/NVPTX/NVPTXMachineFunctionInfo.h @@ -26,6 +26,13 @@ public: NVPTXMachineFunctionInfo(MachineFunction &MF) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override { + return DestMF.cloneInfo(*this); + } + /// Returns the index for the symbol \p Symbol. If the symbol was previously, /// added, the same index is returned. Otherwise, the symbol is added and the /// new index is returned. Index: llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h +++ llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h @@ -153,6 +153,11 @@ public: explicit PPCFunctionInfo(const MachineFunction &MF); + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + int getFramePointerSaveIndex() const { return FramePointerSaveIndex; } void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; } Index: llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp +++ llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp @@ -23,6 +23,13 @@ PPCFunctionInfo::PPCFunctionInfo(const MachineFunction &MF) : DisableNonVolatileCR(PPCDisableNonVolatileCR) {} +MachineFunctionInfo * +PPCFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap + &Src2DstMBB) const { + return DestMF.cloneInfo(*this); +} + MCSymbol *PPCFunctionInfo::getPICOffsetSymbol(MachineFunction &MF) const { const DataLayout &DL = MF.getDataLayout(); return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + Index: llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h +++ llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h @@ -65,6 +65,11 @@ public: RISCVMachineFunctionInfo(const MachineFunction &MF) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } Index: llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp +++ llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp @@ -19,6 +19,13 @@ : VarArgsFrameIndex(MFI.getVarArgsFrameIndex()), VarArgsSaveSize(MFI.getVarArgsSaveSize()) {} +MachineFunctionInfo *RISCVMachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} + void yaml::RISCVMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) { MappingTraits::mapping(YamlIO, *this); } Index: llvm/lib/Target/Sparc/SparcMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/Sparc/SparcMachineFunctionInfo.h +++ llvm/lib/Target/Sparc/SparcMachineFunctionInfo.h @@ -38,6 +38,11 @@ : GlobalBaseReg(0), VarArgsFrameOffset(0), SRetReturnReg(0), IsLeafProc(false) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + Register getGlobalBaseReg() const { return GlobalBaseReg; } void setGlobalBaseReg(Register Reg) { GlobalBaseReg = Reg; } Index: llvm/lib/Target/Sparc/SparcMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/Sparc/SparcMachineFunctionInfo.cpp +++ llvm/lib/Target/Sparc/SparcMachineFunctionInfo.cpp @@ -11,3 +11,10 @@ using namespace llvm; void SparcMachineFunctionInfo::anchor() { } + +MachineFunctionInfo *SparcMachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/SystemZ/SystemZMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZMachineFunctionInfo.h +++ llvm/lib/Target/SystemZ/SystemZMachineFunctionInfo.h @@ -41,6 +41,11 @@ : VarArgsFirstGPR(0), VarArgsFirstFPR(0), VarArgsFrameIndex(0), RegSaveFrameIndex(0), FramePointerSaveIndex(0), NumLocalDynamics(0) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + // Get and set the first and last call-saved GPR that should be saved by // this function and the SP offset for the STMG. These are 0 if no GPRs // need to be saved or restored. Index: llvm/lib/Target/SystemZ/SystemZMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZMachineFunctionInfo.cpp +++ llvm/lib/Target/SystemZ/SystemZMachineFunctionInfo.cpp @@ -14,3 +14,9 @@ // pin vtable to this file void SystemZMachineFunctionInfo::anchor() {} +MachineFunctionInfo *SystemZMachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/VE/VEMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/VE/VEMachineFunctionInfo.h +++ llvm/lib/Target/VE/VEMachineFunctionInfo.h @@ -33,6 +33,11 @@ explicit VEMachineFunctionInfo(MachineFunction &MF) : VarArgsFrameOffset(0), IsLeafProc(false) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + Register getGlobalBaseReg() const { return GlobalBaseReg; } void setGlobalBaseReg(Register Reg) { GlobalBaseReg = Reg; } Index: llvm/lib/Target/VE/VEMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/VE/VEMachineFunctionInfo.cpp +++ llvm/lib/Target/VE/VEMachineFunctionInfo.cpp @@ -11,3 +11,10 @@ using namespace llvm; void VEMachineFunctionInfo::anchor() {} + +MachineFunctionInfo *VEMachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} Index: llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -31,7 +31,7 @@ /// This class is derived from MachineFunctionInfo and contains private /// WebAssembly-specific information for each MachineFunction. class WebAssemblyFunctionInfo final : public MachineFunctionInfo { - const MachineFunction &MF; + const MachineFunction *MF; std::vector Params; std::vector Results; @@ -70,11 +70,16 @@ WasmEHFuncInfo *WasmEHInfo = nullptr; public: - explicit WebAssemblyFunctionInfo(MachineFunction &MF) - : MF(MF), WasmEHInfo(MF.getWasmEHFuncInfo()) {} + explicit WebAssemblyFunctionInfo(MachineFunction &MF_) + : MF(&MF_), WasmEHInfo(MF_.getWasmEHFuncInfo()) {} ~WebAssemblyFunctionInfo() override; - const MachineFunction &getMachineFunction() const { return MF; } + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + + const MachineFunction &getMachineFunction() const { return *MF; } void initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo &YamlMFI); Index: llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp +++ llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp @@ -24,6 +24,16 @@ WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor. +MachineFunctionInfo *WebAssemblyFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + WebAssemblyFunctionInfo *Clone = + DestMF.cloneInfo(*this); + Clone->MF = &DestMF; + return Clone; +} + void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo &MRI) { assert(WARegs.empty()); unsigned Reg = UnusedReg; @@ -153,7 +163,7 @@ addResult(WebAssembly::parseMVT(VT.Value)); if (WasmEHInfo) { for (auto KV : YamlMFI.SrcToUnwindDest) - WasmEHInfo->setUnwindDest(MF.getBlockNumbered(KV.first), - MF.getBlockNumbered(KV.second)); + WasmEHInfo->setUnwindDest(MF->getBlockNumbered(KV.first), + MF->getBlockNumbered(KV.second)); } } Index: llvm/lib/Target/X86/X86MachineFunctionInfo.h =================================================================== --- llvm/lib/Target/X86/X86MachineFunctionInfo.h +++ llvm/lib/Target/X86/X86MachineFunctionInfo.h @@ -134,6 +134,12 @@ X86MachineFunctionInfo() = default; explicit X86MachineFunctionInfo(MachineFunction &MF) {} + explicit X86MachineFunctionInfo(const X86MachineFunctionInfo &) = default; + + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; bool getForceFramePointer() const { return ForceFramePointer;} void setForceFramePointer(bool forceFP) { ForceFramePointer = forceFP; } Index: llvm/lib/Target/X86/X86MachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/X86/X86MachineFunctionInfo.cpp +++ llvm/lib/Target/X86/X86MachineFunctionInfo.cpp @@ -13,6 +13,13 @@ using namespace llvm; +MachineFunctionInfo *X86MachineFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} + void X86MachineFunctionInfo::anchor() { } void X86MachineFunctionInfo::setRestoreBasePointer(const MachineFunction *MF) { Index: llvm/lib/Target/XCore/XCoreMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/XCore/XCoreMachineFunctionInfo.h +++ llvm/lib/Target/XCore/XCoreMachineFunctionInfo.h @@ -45,6 +45,11 @@ explicit XCoreFunctionInfo(MachineFunction &MF) {} + MachineFunctionInfo * + clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const override; + ~XCoreFunctionInfo() override = default; void setVarArgsFrameIndex(int off) { VarArgsFrameIndex = off; } Index: llvm/lib/Target/XCore/XCoreMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/XCore/XCoreMachineFunctionInfo.cpp +++ llvm/lib/Target/XCore/XCoreMachineFunctionInfo.cpp @@ -15,6 +15,13 @@ void XCoreFunctionInfo::anchor() { } +MachineFunctionInfo *XCoreFunctionInfo::clone( + BumpPtrAllocator &Allocator, MachineFunction &DestMF, + const DenseMap &Src2DstMBB) + const { + return DestMF.cloneInfo(*this); +} + bool XCoreFunctionInfo::isLargeFrame(const MachineFunction &MF) const { if (CachedEStackSize == -1) { CachedEStackSize = MF.getFrameInfo().estimateStackSize(MF); Index: llvm/test/tools/llvm-reduce/mir/preserve-machine-function-info-amdgpu.mir =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/mir/preserve-machine-function-info-amdgpu.mir @@ -0,0 +1,125 @@ +# REQUIRES: amdgpu-registered-target +# RUN: llvm-reduce -simplify-mir -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t 2> %t.log +# RUN: FileCheck --check-prefix=RESULT %s < %t + +# CHECK-INTERESTINGNESS-COUNT-6: S_NOP + +# RESULT: name: func + +--- | + define void @func() { + ret void + } + +... + +# RESULT: machineFunctionInfo: +# RESULT-NEXT: explicitKernArgSize: 108 +# RESULT-NEXT: maxKernArgAlign: 32 +# RESULT-NEXT: ldsSize: 256 +# RESULT-NEXT: gdsSize: 128 +# RESULT-NEXT: dynLDSAlign: 16 +# RESULT-NEXT: isEntryFunction: true +# RESULT-NEXT: noSignedZerosFPMath: true +# RESULT-NEXT: memoryBound: true +# RESULT-NEXT: waveLimiter: true +# RESULT-NEXT: hasSpilledSGPRs: true +# RESULT-NEXT: hasSpilledVGPRs: true +# RESULT-NEXT: scratchRSrcReg: '$sgpr48_sgpr49_sgpr50_sgpr51' +# RESULT-NEXT: frameOffsetReg: '$sgpr44' +# RESULT-NEXT: stackPtrOffsetReg: '$sgpr45' +# RESULT-NEXT: bytesInStackArgArea: 112 +# RESULT-NEXT: returnsVoid: false +# RESULT-NEXT: argumentInfo: +# RESULT-NEXT: privateSegmentBuffer: { reg: '$sgpr60_sgpr61_sgpr62_sgpr63' } +# RESULT-NEXT: dispatchPtr: { reg: '$sgpr6_sgpr7' } +# RESULT-NEXT: queuePtr: { reg: '$sgpr4_sgpr5' } +# RESULT-NEXT: dispatchID: { reg: '$sgpr12_sgpr13' } +# RESULT-NEXT: workGroupIDX: { reg: '$sgpr20' } +# RESULT-NEXT: workGroupIDY: { reg: '$sgpr19' } +# RESULT-NEXT: workGroupIDZ: { reg: '$sgpr18' } +# RESULT-NEXT: implicitArgPtr: { reg: '$sgpr10_sgpr11' } +# RESULT-NEXT: workItemIDX: { reg: '$vgpr34', mask: 1023 } +# RESULT-NEXT: workItemIDY: { reg: '$vgpr34', mask: 1047552 } +# RESULT-NEXT: workItemIDZ: { reg: '$vgpr34', mask: 1072693248 } +# RESULT-NEXT: mode: +# RESULT-NEXT: ieee: false +# RESULT-NEXT: dx10-clamp: false +# RESULT-NEXT: fp32-input-denormals: false +# RESULT-NEXT: fp32-output-denormals: false +# RESULT-NEXT: fp64-fp16-input-denormals: false +# RESULT-NEXT: fp64-fp16-output-denormals: false +# RESULT-NEXT: highBitsOf32BitAddress: 4276993775 +# RESULT-NEXT: occupancy: 8 +# RESULT-NEXT: wwmReservedRegs: +# RESULT-NEXT: - '$vgpr2' +# RESULT-NEXT: - '$vgpr3' +# RESULT-NEXT: vgprForAGPRCopy: '$vgpr33' + +# RESULT: S_NOP 0, implicit $sgpr48_sgpr49_sgpr50_sgpr51 +# RESULT: S_NOP 0, implicit $vgpr33 +# RESULT: S_NOP 0, implicit $sgpr44 +# RESULT: S_NOP 0, implicit $sgpr45 +# RESULT: S_NOP 0, implicit $vgpr2 +# RESULT: S_NOP 0, implicit $vgpr3 + +--- +name: func +tracksRegLiveness: true +machineFunctionInfo: + explicitKernArgSize: 108 + maxKernArgAlign: 32 + ldsSize: 256 + gdsSize: 128 + dynLDSAlign: 16 + isEntryFunction: true + noSignedZerosFPMath: true + memoryBound: true + waveLimiter: true + hasSpilledSGPRs: true + hasSpilledVGPRs: true + scratchRSrcReg: '$sgpr48_sgpr49_sgpr50_sgpr51' + frameOffsetReg: '$sgpr44' + stackPtrOffsetReg: '$sgpr45' + bytesInStackArgArea: 112 + returnsVoid: false + argumentInfo: + privateSegmentBuffer: { reg: '$sgpr60_sgpr61_sgpr62_sgpr63' } + dispatchPtr: { reg: '$sgpr6_sgpr7' } + queuePtr: { reg: '$sgpr4_sgpr5' } + dispatchID: { reg: '$sgpr12_sgpr13' } + workGroupIDX: { reg: '$sgpr20' } + workGroupIDY: { reg: '$sgpr19' } + workGroupIDZ: { reg: '$sgpr18' } + implicitArgPtr: { reg: '$sgpr10_sgpr11' } + workItemIDX: { reg: '$vgpr34', mask: 1023 } + workItemIDY: { reg: '$vgpr34', mask: 1047552 } + workItemIDZ: { reg: '$vgpr34', mask: 1072693248 } + mode: + ieee: false + dx10-clamp: false + fp32-input-denormals: false + fp32-output-denormals: false + fp64-fp16-input-denormals: false + fp64-fp16-output-denormals: false + highBitsOf32BitAddress: 0xfeedbeef + occupancy: 8 + wwmReservedRegs: + - '$vgpr2' + - '$vgpr3' + vgprForAGPRCopy: '$vgpr33' +body: | + bb.0: + S_WAITCNT 0 + %0:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + + ; Test some register uses that are undef unless the reserved + ; registers are respected. + S_NOP 0, implicit $sgpr48_sgpr49_sgpr50_sgpr51 + S_NOP 0, implicit $vgpr33 + S_NOP 0, implicit $sgpr44 + S_NOP 0, implicit $sgpr45 + S_NOP 0, implicit $vgpr2 + S_NOP 0, implicit $vgpr3 + S_ENDPGM 0, implicit %0 +... Index: llvm/test/tools/llvm-reduce/mir/preserve-machine-function-info-riscv.mir =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/mir/preserve-machine-function-info-riscv.mir @@ -0,0 +1,42 @@ +# REQUIRES: riscv-registered-target +# RUN: llvm-reduce -simplify-mir -mtriple=riscv64-- --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t 2> %t.log +# RUN: FileCheck --check-prefix=RESULT %s < %t + +# CHECK-INTERESTINGNESS: ADDW + +# RESULT: name: func +# RESULT: stack: +# RESULT-NEXT: - { id: 0, offset: 16, size: 16, alignment: 8 } + +# RESULT: machineFunctionInfo: +# RESULT-NEXT: varArgsFrameIndex: 4 +# RESULT-NEXT: varArgsSaveSize: 12 + +# RESULT: $x10 = ADDW %stack.0, renamable $x10 +--- | + define i32 @func(i32 %arg) { + ret i32 undef + } + +... + +# Note the frame index value changes during printing/parsing, not the +# clone. +--- +name: func +tracksRegLiveness: true +machineFunctionInfo: + varArgsFrameIndex: 4 + varArgsSaveSize: 12 +stack: + - { id: 4, offset: 16, size: 16, alignment: 8 } + +body: | + bb.0: + liveins: $x10 + + renamable $x10 = ADDW %stack.4, renamable $x10 + renamable $x10 = ADDIW killed renamable $x10, -4 + PseudoRET implicit $x10 + +... Index: llvm/tools/llvm-reduce/ReducerWorkItem.cpp =================================================================== --- llvm/tools/llvm-reduce/ReducerWorkItem.cpp +++ llvm/tools/llvm-reduce/ReducerWorkItem.cpp @@ -138,8 +138,6 @@ // Remap the debug info frame index references. DstMF->VariableDbgInfos = SrcMF->VariableDbgInfos; - // FIXME: Need to clone MachineFunctionInfo, which may also depend on frame - // index and block mapping. // Clone virtual registers for (unsigned I = 0, E = SrcMRI->getNumVirtRegs(); I != E; ++I) { Register Reg = Register::index2VirtReg(I); @@ -228,6 +226,11 @@ DstMF->setDebugInstrNumberingCount(SrcMF->DebugInstrNumberingCount); + if (!DstMF->cloneInfoFrom(*SrcMF, Src2DstMBB)) + report_fatal_error("target does not implement MachineFunctionInfo cloning"); + + DstMRI->freezeReservedRegs(*DstMF); + DstMF->verify(nullptr, "", /*AbortOnError=*/true); return DstMF; }