diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp | 194 |
1 files changed, 132 insertions, 62 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp index 7f6a75208d25..38ad582ba923 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp @@ -72,7 +72,6 @@ #include <cstdint> #include <iterator> #include <string> -#include <type_traits> #include <utility> #include <vector> @@ -103,6 +102,7 @@ static const char *getPropertyName(MachineFunctionProperties::Property Prop) { case P::TracksLiveness: return "TracksLiveness"; case P::TiedOpsRewritten: return "TiedOpsRewritten"; case P::FailsVerification: return "FailsVerification"; + case P::FailedRegAlloc: return "FailedRegAlloc"; case P::TracksDebugUserValues: return "TracksDebugUserValues"; } // clang-format on @@ -161,10 +161,10 @@ static inline Align getFnStackAlignment(const TargetSubtargetInfo *STI, return STI->getFrameLowering()->getStackAlign(); } -MachineFunction::MachineFunction(Function &F, const LLVMTargetMachine &Target, - const TargetSubtargetInfo &STI, - unsigned FunctionNum, MachineModuleInfo &mmi) - : F(F), Target(Target), STI(&STI), Ctx(mmi.getContext()), MMI(mmi) { +MachineFunction::MachineFunction(Function &F, const TargetMachine &Target, + const TargetSubtargetInfo &STI, MCContext &Ctx, + unsigned FunctionNum) + : F(F), Target(Target), STI(&STI), Ctx(Ctx) { FunctionNumber = FunctionNum; init(); } @@ -187,12 +187,9 @@ void MachineFunction::handleChangeDesc(MachineInstr &MI, void MachineFunction::init() { // Assume the function starts in SSA form with correct liveness. - Properties.set(MachineFunctionProperties::Property::IsSSA); - Properties.set(MachineFunctionProperties::Property::TracksLiveness); - if (STI->getRegisterInfo()) - RegInfo = new (Allocator) MachineRegisterInfo(this); - else - RegInfo = nullptr; + Properties.setIsSSA(); + Properties.setTracksLiveness(); + RegInfo = new (Allocator) MachineRegisterInfo(this); MFInfo = nullptr; @@ -262,6 +259,15 @@ MachineFunction::~MachineFunction() { void MachineFunction::clear() { Properties.reset(); + + // Clear JumpTableInfo first. Otherwise, every MBB we delete would do a + // linear search over the jump table entries to find and erase itself. + if (JumpTableInfo) { + JumpTableInfo->~MachineJumpTableInfo(); + Allocator.Deallocate(JumpTableInfo); + JumpTableInfo = nullptr; + } + // Don't call destructors on MachineInstr and MachineOperand. All of their // memory comes from the BumpPtrAllocator which is about to be purged. // @@ -290,11 +296,6 @@ void MachineFunction::clear() { ConstantPool->~MachineConstantPool(); Allocator.Deallocate(ConstantPool); - if (JumpTableInfo) { - JumpTableInfo->~MachineJumpTableInfo(); - Allocator.Deallocate(JumpTableInfo); - } - if (WinEHInfo) { WinEHInfo->~WinEHFuncInfo(); Allocator.Deallocate(WinEHInfo); @@ -375,6 +376,38 @@ void MachineFunction::RenumberBlocks(MachineBasicBlock *MBB) { // numbering, shrink MBBNumbering now. assert(BlockNo <= MBBNumbering.size() && "Mismatch!"); MBBNumbering.resize(BlockNo); + MBBNumberingEpoch++; +} + +int64_t MachineFunction::estimateFunctionSizeInBytes() { + const TargetInstrInfo &TII = *getSubtarget().getInstrInfo(); + const Align FunctionAlignment = getAlignment(); + MachineFunction::iterator MBBI = begin(), E = end(); + /// Offset - Distance from the beginning of the function to the end + /// of the basic block. + int64_t Offset = 0; + + for (; MBBI != E; ++MBBI) { + const Align Alignment = MBBI->getAlignment(); + int64_t BlockSize = 0; + + for (auto &MI : *MBBI) { + BlockSize += TII.getInstSizeInBytes(MI); + } + + int64_t OffsetBB; + if (Alignment <= FunctionAlignment) { + OffsetBB = alignTo(Offset, Alignment); + } else { + // The alignment of this MBB is larger than the function's alignment, so + // we can't tell whether or not it will insert nops. Assume that it will. + OffsetBB = alignTo(Offset, Alignment) + Alignment.value() - + FunctionAlignment.value(); + } + Offset = OffsetBB + BlockSize; + } + + return Offset; } /// This method iterates over the basic blocks and assigns their IsBeginSection @@ -427,11 +460,11 @@ MachineInstr &MachineFunction::cloneMachineInstrBundle( break; ++I; } - // Copy over call site info to the cloned instruction if needed. If Orig is in - // a bundle, copyCallSiteInfo takes care of finding the call instruction in - // the bundle. - if (Orig.shouldUpdateCallSiteInfo()) - copyCallSiteInfo(&Orig, FirstClone); + // Copy over call info to the cloned instruction if needed. If Orig is in + // a bundle, copyAdditionalCallInfo takes care of finding the call instruction + // in the bundle. + if (Orig.shouldUpdateAdditionalCallInfo()) + copyAdditionalCallInfo(&Orig, FirstClone); return *FirstClone; } @@ -444,8 +477,13 @@ void MachineFunction::deleteMachineInstr(MachineInstr *MI) { // be triggered during the implementation of support for the // call site info of a new architecture. If the assertion is triggered, // back trace will tell where to insert a call to updateCallSiteInfo(). - assert((!MI->isCandidateForCallSiteEntry() || !CallSitesInfo.contains(MI)) && + assert((!MI->isCandidateForAdditionalCallInfo() || + !CallSitesInfo.contains(MI)) && "Call site info was not updated!"); + // Verify that the "called globals" info is in a valid state. + assert((!MI->isCandidateForAdditionalCallInfo() || + !CalledGlobalsInfo.contains(MI)) && + "Called globals info was not updated!"); // Strip it for parts. The operand array and the MI object itself are // independently recyclable. if (MI->Operands) @@ -464,11 +502,9 @@ MachineFunction::CreateMachineBasicBlock(const BasicBlock *BB, MachineBasicBlock *MBB = new (BasicBlockRecycler.Allocate<MachineBasicBlock>(Allocator)) MachineBasicBlock(*this, BB); - // Set BBID for `-basic-block=sections=labels` and - // `-basic-block-sections=list` to allow robust mapping of profiles to basic - // blocks. - if (Target.getBBSectionsType() == BasicBlockSection::Labels || - Target.Options.BBAddrMap || + // Set BBID for `-basic-block-sections=list` and `-basic-block-address-map` to + // allow robust mapping of profiles to basic blocks. + if (Target.Options.BBAddrMap || Target.getBBSectionsType() == BasicBlockSection::List) MBB->setBBID(BBID.has_value() ? *BBID : UniqueBBID{NextBBID++, 0}); return MBB; @@ -654,9 +690,14 @@ void MachineFunction::print(raw_ostream &OS, const SlotIndexes *Indexes) const { /// True if this function needs frame moves for debug or exceptions. bool MachineFunction::needsFrameMoves() const { - return getMMI().hasDebugInfo() || - getTarget().Options.ForceDwarfFrameSection || - F.needsUnwindTableEntry(); + // TODO: Ideally, what we'd like is to have a switch that allows emitting + // synchronous (precise at call-sites only) CFA into .eh_frame. However, even + // under this switch, we'd like .debug_frame to be precise when using -g. At + // this moment, there's no way to specify that some CFI directives go into + // .eh_frame only, while others go into .debug_frame only. + return getTarget().Options.ForceDwarfFrameSection || + F.needsUnwindTableEntry() || + !F.getParent()->debug_compile_units().empty(); } namespace llvm { @@ -793,7 +834,8 @@ MCSymbol *MachineFunction::addLandingPad(MachineBasicBlock *LandingPad) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); LP.LandingPadLabel = LandingPadLabel; - const Instruction *FirstI = LandingPad->getBasicBlock()->getFirstNonPHI(); + BasicBlock::const_iterator FirstI = + LandingPad->getBasicBlock()->getFirstNonPHIIt(); if (const auto *LPI = dyn_cast<LandingPadInst>(FirstI)) { // If there's no typeid list specified, then "cleanup" is implicit. // Otherwise, id 0 is reserved for the cleanup action. @@ -876,7 +918,7 @@ try_next:; MachineFunction::CallSiteInfoMap::iterator MachineFunction::getCallSiteInfo(const MachineInstr *MI) { - assert(MI->isCandidateForCallSiteEntry() && + assert(MI->isCandidateForAdditionalCallInfo() && "Call site info refers only to call (MI) candidates"); if (!Target.Options.EmitCallSiteInfo) @@ -891,59 +933,72 @@ static const MachineInstr *getCallInstr(const MachineInstr *MI) { for (const auto &BMI : make_range(getBundleStart(MI->getIterator()), getBundleEnd(MI->getIterator()))) - if (BMI.isCandidateForCallSiteEntry()) + if (BMI.isCandidateForAdditionalCallInfo()) return &BMI; llvm_unreachable("Unexpected bundle without a call site candidate"); } -void MachineFunction::eraseCallSiteInfo(const MachineInstr *MI) { - assert(MI->shouldUpdateCallSiteInfo() && - "Call site info refers only to call (MI) candidates or " +void MachineFunction::eraseAdditionalCallInfo(const MachineInstr *MI) { + assert(MI->shouldUpdateAdditionalCallInfo() && + "Call info refers only to call (MI) candidates or " "candidates inside bundles"); const MachineInstr *CallMI = getCallInstr(MI); + CallSiteInfoMap::iterator CSIt = getCallSiteInfo(CallMI); - if (CSIt == CallSitesInfo.end()) - return; - CallSitesInfo.erase(CSIt); + if (CSIt != CallSitesInfo.end()) + CallSitesInfo.erase(CSIt); + + CalledGlobalsInfo.erase(CallMI); } -void MachineFunction::copyCallSiteInfo(const MachineInstr *Old, - const MachineInstr *New) { - assert(Old->shouldUpdateCallSiteInfo() && - "Call site info refers only to call (MI) candidates or " +void MachineFunction::copyAdditionalCallInfo(const MachineInstr *Old, + const MachineInstr *New) { + assert(Old->shouldUpdateAdditionalCallInfo() && + "Call info refers only to call (MI) candidates or " "candidates inside bundles"); - if (!New->isCandidateForCallSiteEntry()) - return eraseCallSiteInfo(Old); + if (!New->isCandidateForAdditionalCallInfo()) + return eraseAdditionalCallInfo(Old); const MachineInstr *OldCallMI = getCallInstr(Old); CallSiteInfoMap::iterator CSIt = getCallSiteInfo(OldCallMI); - if (CSIt == CallSitesInfo.end()) - return; + if (CSIt != CallSitesInfo.end()) { + CallSiteInfo CSInfo = CSIt->second; + CallSitesInfo[New] = std::move(CSInfo); + } - CallSiteInfo CSInfo = CSIt->second; - CallSitesInfo[New] = CSInfo; + CalledGlobalsMap::iterator CGIt = CalledGlobalsInfo.find(OldCallMI); + if (CGIt != CalledGlobalsInfo.end()) { + CalledGlobalInfo CGInfo = CGIt->second; + CalledGlobalsInfo[New] = std::move(CGInfo); + } } -void MachineFunction::moveCallSiteInfo(const MachineInstr *Old, - const MachineInstr *New) { - assert(Old->shouldUpdateCallSiteInfo() && - "Call site info refers only to call (MI) candidates or " +void MachineFunction::moveAdditionalCallInfo(const MachineInstr *Old, + const MachineInstr *New) { + assert(Old->shouldUpdateAdditionalCallInfo() && + "Call info refers only to call (MI) candidates or " "candidates inside bundles"); - if (!New->isCandidateForCallSiteEntry()) - return eraseCallSiteInfo(Old); + if (!New->isCandidateForAdditionalCallInfo()) + return eraseAdditionalCallInfo(Old); const MachineInstr *OldCallMI = getCallInstr(Old); CallSiteInfoMap::iterator CSIt = getCallSiteInfo(OldCallMI); - if (CSIt == CallSitesInfo.end()) - return; + if (CSIt != CallSitesInfo.end()) { + CallSiteInfo CSInfo = std::move(CSIt->second); + CallSitesInfo.erase(CSIt); + CallSitesInfo[New] = std::move(CSInfo); + } - CallSiteInfo CSInfo = std::move(CSIt->second); - CallSitesInfo.erase(CSIt); - CallSitesInfo[New] = CSInfo; + CalledGlobalsMap::iterator CGIt = CalledGlobalsInfo.find(OldCallMI); + if (CGIt != CalledGlobalsInfo.end()) { + CalledGlobalInfo CGInfo = std::move(CGIt->second); + CalledGlobalsInfo.erase(CGIt); + CalledGlobalsInfo[New] = std::move(CGInfo); + } } void MachineFunction::setDebugInstrNumberingCount(unsigned Num) { @@ -998,7 +1053,7 @@ auto MachineFunction::salvageCopySSA( // Check whether this copy-like instruction has already been salvaged into // an operand pair. Register Dest; - if (auto CopyDstSrc = TII.isCopyInstr(MI)) { + if (auto CopyDstSrc = TII.isCopyLikeInstr(MI)) { Dest = CopyDstSrc->Destination->getReg(); } else { assert(MI.isSubregToReg()); @@ -1082,7 +1137,7 @@ auto MachineFunction::salvageCopySSAImpl(MachineInstr &MI) CurInst = Inst.getIterator(); // Any non-copy instruction is the defining instruction we're seeking. - if (!Inst.isCopyLike() && !TII.isCopyInstr(Inst)) + if (!Inst.isCopyLike() && !TII.isCopyLikeInstr(Inst)) break; State = GetRegAndSubreg(Inst); }; @@ -1256,6 +1311,10 @@ const unsigned MachineFunction::DebugOperandMemNumber = 1000000; // MachineJumpTableInfo implementation //===----------------------------------------------------------------------===// +MachineJumpTableEntry::MachineJumpTableEntry( + const std::vector<MachineBasicBlock *> &MBBs) + : MBBs(MBBs), Hotness(MachineFunctionDataHotness::Unknown) {} + /// Return the size of each entry in the jump table. unsigned MachineJumpTableInfo::getEntrySize(const DataLayout &TD) const { // The size of a jump table entry is 4 bytes unless the entry is just the @@ -1305,6 +1364,17 @@ unsigned MachineJumpTableInfo::createJumpTableIndex( return JumpTables.size()-1; } +bool MachineJumpTableInfo::updateJumpTableEntryHotness( + size_t JTI, MachineFunctionDataHotness Hotness) { + assert(JTI < JumpTables.size() && "Invalid JTI!"); + // Record the largest hotness value. + if (Hotness <= JumpTables[JTI].Hotness) + return false; + + JumpTables[JTI].Hotness = Hotness; + return true; +} + /// If Old is the target of any jump tables, update the jump tables to branch /// to New instead. bool MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old, |
