aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/MachineFunction.cpp194
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,