diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-04 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:02:26 +0000 |
commit | 81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch) | |
tree | 311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues | |
parent | 5fff09660e06a66bed6482da9c70df328e16bbb6 (diff) | |
parent | 145449b1e420787bb99721a429341fa6be3adfb6 (diff) | |
download | src-81ad626541db97eb356e2c1d4a20eb2a26a766ab.tar.gz src-81ad626541db97eb356e2c1d4a20eb2a26a766ab.zip |
Merge llvm-project main llvmorg-15-init-15358-g53dc0f10787
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-15-init-15358-g53dc0f10787.
PR: 265425
MFC after: 2 weeks
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues')
5 files changed, 254 insertions, 195 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp index 6af5f07d801a..30ca8bd871e8 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -84,21 +84,18 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Analysis/IteratedDominanceFrontier.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/LexicalScopes.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/PseudoSourceValue.h" -#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetLowering.h" @@ -106,27 +103,23 @@ #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Config/llvm-config.h" -#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Function.h" -#include "llvm/IR/Module.h" -#include "llvm/InitializePasses.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/GenericIteratedDominanceFrontier.h" #include "llvm/Support/TypeSize.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/SSAUpdaterImpl.h" #include <algorithm> #include <cassert> +#include <climits> #include <cstdint> #include <functional> -#include <limits.h> -#include <limits> #include <queue> #include <tuple> #include <utility> @@ -266,7 +259,7 @@ public: /// object fields to track variable locations as we step through the block. /// FIXME: could just examine mloctracker instead of passing in \p mlocs? void - loadInlocs(MachineBasicBlock &MBB, ValueIDNum *MLocs, + loadInlocs(MachineBasicBlock &MBB, ValueTable &MLocs, const SmallVectorImpl<std::pair<DebugVariable, DbgValue>> &VLocs, unsigned NumLocs) { ActiveMLocs.clear(); @@ -729,6 +722,20 @@ MLocTracker::MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII, StackSlotIdxes.insert({{Size, Offs}, Idx}); } + // There may also be strange register class sizes (think x86 fp80s). + for (const TargetRegisterClass *RC : TRI.regclasses()) { + unsigned Size = TRI.getRegSizeInBits(*RC); + + // We might see special reserved values as sizes, and classes for other + // stuff the machine tries to model. If it's more than 512 bits, then it + // is very unlikely to be a register than can be spilt. + if (Size > 512) + continue; + + unsigned Idx = StackSlotIdxes.size(); + StackSlotIdxes.insert({{Size, 0}, Idx}); + } + for (auto &Idx : StackSlotIdxes) StackIdxesToPos[Idx.second] = Idx.first; @@ -863,19 +870,72 @@ MachineInstrBuilder MLocTracker::emitLoc(Optional<LocIdx> MLoc, // the variable is. if (Offset == 0) { const SpillLoc &Spill = SpillLocs[SpillID.id()]; - Expr = TRI.prependOffsetExpression(Expr, DIExpression::ApplyOffset, - Spill.SpillOffset); unsigned Base = Spill.SpillBase; MIB.addReg(Base); - MIB.addImm(0); - // Being on the stack makes this location indirect; if it was _already_ - // indirect though, we need to add extra indirection. See this test for - // a scenario where this happens: - // llvm/test/DebugInfo/X86/spill-nontrivial-param.ll + // There are several ways we can dereference things, and several inputs + // to consider: + // * NRVO variables will appear with IsIndirect set, but should have + // nothing else in their DIExpressions, + // * Variables with DW_OP_stack_value in their expr already need an + // explicit dereference of the stack location, + // * Values that don't match the variable size need DW_OP_deref_size, + // * Everything else can just become a simple location expression. + + // We need to use deref_size whenever there's a mismatch between the + // size of value and the size of variable portion being read. + // Additionally, we should use it whenever dealing with stack_value + // fragments, to avoid the consumer having to determine the deref size + // from DW_OP_piece. + bool UseDerefSize = false; + unsigned ValueSizeInBits = getLocSizeInBits(*MLoc); + unsigned DerefSizeInBytes = ValueSizeInBits / 8; + if (auto Fragment = Var.getFragment()) { + unsigned VariableSizeInBits = Fragment->SizeInBits; + if (VariableSizeInBits != ValueSizeInBits || Expr->isComplex()) + UseDerefSize = true; + } else if (auto Size = Var.getVariable()->getSizeInBits()) { + if (*Size != ValueSizeInBits) { + UseDerefSize = true; + } + } + if (Properties.Indirect) { - std::vector<uint64_t> Elts = {dwarf::DW_OP_deref}; - Expr = DIExpression::append(Expr, Elts); + // This is something like an NRVO variable, where the pointer has been + // spilt to the stack, or a dbg.addr pointing at a coroutine frame + // field. It should end up being a memory location, with the pointer + // to the variable loaded off the stack with a deref. It can't be a + // DW_OP_stack_value expression. + assert(!Expr->isImplicit()); + Expr = TRI.prependOffsetExpression( + Expr, DIExpression::ApplyOffset | DIExpression::DerefAfter, + Spill.SpillOffset); + MIB.addImm(0); + } else if (UseDerefSize) { + // We're loading a value off the stack that's not the same size as the + // variable. Add / subtract stack offset, explicitly deref with a size, + // and add DW_OP_stack_value if not already present. + SmallVector<uint64_t, 2> Ops = {dwarf::DW_OP_deref_size, + DerefSizeInBytes}; + Expr = DIExpression::prependOpcodes(Expr, Ops, true); + unsigned Flags = DIExpression::StackValue | DIExpression::ApplyOffset; + Expr = TRI.prependOffsetExpression(Expr, Flags, Spill.SpillOffset); + MIB.addReg(0); + } else if (Expr->isComplex()) { + // A variable with no size ambiguity, but with extra elements in it's + // expression. Manually dereference the stack location. + assert(Expr->isComplex()); + Expr = TRI.prependOffsetExpression( + Expr, DIExpression::ApplyOffset | DIExpression::DerefAfter, + Spill.SpillOffset); + MIB.addReg(0); + } else { + // A plain value that has been spilt to the stack, with no further + // context. Request a location expression, marking the DBG_VALUE as + // IsIndirect. + Expr = TRI.prependOffsetExpression(Expr, DIExpression::ApplyOffset, + Spill.SpillOffset); + MIB.addImm(0); } } else { // This is a stack location with a weird subregister offset: emit an undef @@ -899,7 +959,7 @@ MachineInstrBuilder MLocTracker::emitLoc(Optional<LocIdx> MLoc, } /// Default construct and initialize the pass. -InstrRefBasedLDV::InstrRefBasedLDV() {} +InstrRefBasedLDV::InstrRefBasedLDV() = default; bool InstrRefBasedLDV::isCalleeSaved(LocIdx L) const { unsigned Reg = MTracker->LocIdxToLocID[L]; @@ -1022,8 +1082,8 @@ bool InstrRefBasedLDV::transferDebugValue(const MachineInstr &MI) { } bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI, - ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns) { + const ValueTable *MLiveOuts, + const ValueTable *MLiveIns) { if (!MI.isDebugRef()) return false; @@ -1091,15 +1151,25 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI, if (L) NewID = ValueIDNum(BlockNo, InstrIt->second.second, *L); } else if (OpNo != MachineFunction::DebugOperandMemNumber) { - assert(OpNo < TargetInstr.getNumOperands()); - const MachineOperand &MO = TargetInstr.getOperand(OpNo); - - // Today, this can only be a register. - assert(MO.isReg() && MO.isDef()); + // Permit the debug-info to be completely wrong: identifying a nonexistant + // operand, or one that is not a register definition, means something + // unexpected happened during optimisation. Broken debug-info, however, + // shouldn't crash the compiler -- instead leave the variable value as + // None, which will make it appear "optimised out". + if (OpNo < TargetInstr.getNumOperands()) { + const MachineOperand &MO = TargetInstr.getOperand(OpNo); + + if (MO.isReg() && MO.isDef() && MO.getReg()) { + unsigned LocID = MTracker->getLocID(MO.getReg()); + LocIdx L = MTracker->LocIDToLocIdx[LocID]; + NewID = ValueIDNum(BlockNo, InstrIt->second.second, L); + } + } - unsigned LocID = MTracker->getLocID(MO.getReg()); - LocIdx L = MTracker->LocIDToLocIdx[LocID]; - NewID = ValueIDNum(BlockNo, InstrIt->second.second, L); + if (!NewID) { + LLVM_DEBUG( + { dbgs() << "Seen instruction reference to illegal operand\n"; }); + } } // else: NewID is left as None. } else if (PHIIt != DebugPHINumToValue.end() && PHIIt->InstrNum == InstNo) { @@ -1249,7 +1319,16 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) { const MachineOperand &MO = MI.getOperand(0); unsigned InstrNum = MI.getOperand(1).getImm(); - if (MO.isReg()) { + auto EmitBadPHI = [this, &MI, InstrNum](void) -> bool { + // Helper lambda to do any accounting when we fail to find a location for + // a DBG_PHI. This can happen if DBG_PHIs are malformed, or refer to a + // dead stack slot, for example. + // Record a DebugPHIRecord with an empty value + location. + DebugPHINumToValue.push_back({InstrNum, MI.getParent(), None, None}); + return true; + }; + + if (MO.isReg() && MO.getReg()) { // The value is whatever's currently in the register. Read and record it, // to be analysed later. Register Reg = MO.getReg(); @@ -1261,15 +1340,14 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) { // Ensure this register is tracked. for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI) MTracker->lookupOrTrackRegister(*RAI); - } else { + } else if (MO.isFI()) { // The value is whatever's in this stack slot. - assert(MO.isFI()); unsigned FI = MO.getIndex(); // If the stack slot is dead, then this was optimized away. // FIXME: stack slot colouring should account for slots that get merged. if (MFI->isDeadObjectIndex(FI)) - return true; + return EmitBadPHI(); // Identify this spill slot, ensure it's tracked. Register Base; @@ -1280,43 +1358,27 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) { // We might be able to find a value, but have chosen not to, to avoid // tracking too much stack information. if (!SpillNo) - return true; + return EmitBadPHI(); - // Problem: what value should we extract from the stack? LLVM does not - // record what size the last store to the slot was, and it would become - // sketchy after stack slot colouring anyway. Take a look at what values - // are stored on the stack, and pick the largest one that wasn't def'd - // by a spill (i.e., the value most likely to have been def'd in a register - // and then spilt. - std::array<unsigned, 4> CandidateSizes = {64, 32, 16, 8}; - Optional<ValueIDNum> Result = None; - Optional<LocIdx> SpillLoc = None; - for (unsigned CS : CandidateSizes) { - unsigned SpillID = MTracker->getLocID(*SpillNo, {CS, 0}); - SpillLoc = MTracker->getSpillMLoc(SpillID); - ValueIDNum Val = MTracker->readMLoc(*SpillLoc); - // If this value was defined in it's own position, then it was probably - // an aliasing index of a small value that was spilt. - if (Val.getLoc() != SpillLoc->asU64()) { - Result = Val; - break; - } - } + // Any stack location DBG_PHI should have an associate bit-size. + assert(MI.getNumOperands() == 3 && "Stack DBG_PHI with no size?"); + unsigned slotBitSize = MI.getOperand(2).getImm(); - // If we didn't find anything, we're probably looking at a PHI, or a memory - // store folded into an instruction. FIXME: Take a guess that's it's 64 - // bits. This isn't ideal, but tracking the size that the spill is - // "supposed" to be is more complex, and benefits a small number of - // locations. - if (!Result) { - unsigned SpillID = MTracker->getLocID(*SpillNo, {64, 0}); - SpillLoc = MTracker->getSpillMLoc(SpillID); - Result = MTracker->readMLoc(*SpillLoc); - } + unsigned SpillID = MTracker->getLocID(*SpillNo, {slotBitSize, 0}); + LocIdx SpillLoc = MTracker->getSpillMLoc(SpillID); + ValueIDNum Result = MTracker->readMLoc(SpillLoc); // Record this DBG_PHI for later analysis. - auto DbgPHI = DebugPHIRecord({InstrNum, MI.getParent(), *Result, *SpillLoc}); + auto DbgPHI = DebugPHIRecord({InstrNum, MI.getParent(), Result, SpillLoc}); DebugPHINumToValue.push_back(DbgPHI); + } else { + // Else: if the operand is neither a legal register or a stack slot, then + // we're being fed illegal debug-info. Record an empty PHI, so that any + // debug users trying to read this number will be put off trying to + // interpret the value. + LLVM_DEBUG( + { dbgs() << "Seen DBG_PHI with unrecognised operand format\n"; }); + return EmitBadPHI(); } return true; @@ -1614,11 +1676,6 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) { LocIdx SrcIdx = MTracker->getSpillMLoc(SpillID); auto ReadValue = MTracker->readMLoc(SrcIdx); MTracker->setReg(DestReg, ReadValue); - - if (TTracker) { - LocIdx DstLoc = MTracker->getRegMLoc(DestReg); - TTracker->transferMlocs(SrcIdx, DstLoc, MI.getIterator()); - } }; for (MCSubRegIterator SRI(Reg, TRI, false); SRI.isValid(); ++SRI) { @@ -1755,8 +1812,8 @@ void InstrRefBasedLDV::accumulateFragmentMap(MachineInstr &MI) { AllSeenFragments.insert(ThisFragment); } -void InstrRefBasedLDV::process(MachineInstr &MI, ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns) { +void InstrRefBasedLDV::process(MachineInstr &MI, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns) { // Try to interpret an MI as a debug or transfer instruction. Only if it's // none of these should we interpret it's register defs as new value // definitions. @@ -1806,7 +1863,10 @@ void InstrRefBasedLDV::produceMLocTransferFunction( // Step through each instruction in this block. for (auto &MI : MBB) { - process(MI); + // Pass in an empty unique_ptr for the value tables when accumulating the + // machine transfer function. + process(MI, nullptr, nullptr); + // Also accumulate fragment map. if (MI.isDebugValue() || MI.isDebugRef()) accumulateFragmentMap(MI); @@ -1895,7 +1955,7 @@ void InstrRefBasedLDV::produceMLocTransferFunction( bool InstrRefBasedLDV::mlocJoin( MachineBasicBlock &MBB, SmallPtrSet<const MachineBasicBlock *, 16> &Visited, - ValueIDNum **OutLocs, ValueIDNum *InLocs) { + FuncValueTable &OutLocs, ValueTable &InLocs) { LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n"); bool Changed = false; @@ -1996,7 +2056,7 @@ void InstrRefBasedLDV::findStackIndexInterference( void InstrRefBasedLDV::placeMLocPHIs( MachineFunction &MF, SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks, - ValueIDNum **MInLocs, SmallVectorImpl<MLocTransferMap> &MLocTransfer) { + FuncValueTable &MInLocs, SmallVectorImpl<MLocTransferMap> &MLocTransfer) { SmallVector<unsigned, 4> StackUnits; findStackIndexInterference(StackUnits); @@ -2125,7 +2185,7 @@ void InstrRefBasedLDV::placeMLocPHIs( } void InstrRefBasedLDV::buildMLocValueMap( - MachineFunction &MF, ValueIDNum **MInLocs, ValueIDNum **MOutLocs, + MachineFunction &MF, FuncValueTable &MInLocs, FuncValueTable &MOutLocs, SmallVectorImpl<MLocTransferMap> &MLocTransfer) { std::priority_queue<unsigned int, std::vector<unsigned int>, std::greater<unsigned int>> @@ -2267,7 +2327,7 @@ void InstrRefBasedLDV::BlockPHIPlacement( Optional<ValueIDNum> InstrRefBasedLDV::pickVPHILoc( const MachineBasicBlock &MBB, const DebugVariable &Var, - const LiveIdxT &LiveOuts, ValueIDNum **MOutLocs, + const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs, const SmallVectorImpl<const MachineBasicBlock *> &BlockOrders) { // Collect a set of locations from predecessor where its live-out value can // be found. @@ -2535,7 +2595,7 @@ void InstrRefBasedLDV::getBlocksForScope( void InstrRefBasedLDV::buildVLocValueMap( const DILocation *DILoc, const SmallSet<DebugVariable, 4> &VarsWeCareAbout, SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks, LiveInsT &Output, - ValueIDNum **MOutLocs, ValueIDNum **MInLocs, + FuncValueTable &MOutLocs, FuncValueTable &MInLocs, SmallVectorImpl<VLocTracker> &AllTheVLocs) { // This method is much like buildMLocValueMap: but focuses on a single // LexicalScope at a time. Pick out a set of blocks and variables that are @@ -2920,7 +2980,7 @@ void InstrRefBasedLDV::makeDepthFirstEjectionMap( bool InstrRefBasedLDV::depthFirstVLocAndEmit( unsigned MaxNumBlocks, const ScopeToDILocT &ScopeToDILocation, const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToAssignBlocks, - LiveInsT &Output, ValueIDNum **MOutLocs, ValueIDNum **MInLocs, + LiveInsT &Output, FuncValueTable &MOutLocs, FuncValueTable &MInLocs, SmallVectorImpl<VLocTracker> &AllTheVLocs, MachineFunction &MF, DenseMap<DebugVariable, unsigned> &AllVarsNumbering, const TargetPassConfig &TPC) { @@ -2929,15 +2989,8 @@ bool InstrRefBasedLDV::depthFirstVLocAndEmit( VTracker = nullptr; // No scopes? No variable locations. - if (!LS.getCurrentFunctionScope()) { - // FIXME: this is a sticking plaster to prevent a memory leak, these - // pointers will be automagically freed by being unique pointers, shortly. - for (unsigned int I = 0; I < MaxNumBlocks; ++I) { - delete[] MInLocs[I]; - delete[] MOutLocs[I]; - } + if (!LS.getCurrentFunctionScope()) return false; - } // Build map from block number to the last scope that uses the block. SmallVector<unsigned, 16> EjectionMap; @@ -2961,17 +3014,14 @@ bool InstrRefBasedLDV::depthFirstVLocAndEmit( CurBB = BBNum; CurInst = 1; for (auto &MI : MBB) { - process(MI, MOutLocs, MInLocs); + process(MI, MOutLocs.get(), MInLocs.get()); TTracker->checkInstForNewValues(CurInst, MI.getIterator()); ++CurInst; } // Free machine-location tables for this block. - delete[] MInLocs[BBNum]; - delete[] MOutLocs[BBNum]; - // Make ourselves brittle to use-after-free errors. - MInLocs[BBNum] = nullptr; - MOutLocs[BBNum] = nullptr; + MInLocs[BBNum].reset(); + MOutLocs[BBNum].reset(); // We don't need live-in variable values for this block either. Output[BBNum].clear(); AllTheVLocs[BBNum].clear(); @@ -3039,16 +3089,6 @@ bool InstrRefBasedLDV::depthFirstVLocAndEmit( if (MOutLocs[MBB->getNumber()]) EjectBlock(*MBB); - // Finally, there might have been gaps in the block numbering, from dead - // blocks being deleted or folded. In those scenarios, we might allocate a - // block-table that's never ejected, meaning we have to free it at the end. - for (unsigned int I = 0; I < MaxNumBlocks; ++I) { - if (MInLocs[I]) { - delete[] MInLocs[I]; - delete[] MOutLocs[I]; - } - } - return emitTransfers(AllVarsNumbering); } @@ -3135,24 +3175,24 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, assert(MaxNumBlocks >= 0); ++MaxNumBlocks; + initialSetup(MF); + MLocTransfer.resize(MaxNumBlocks); vlocs.resize(MaxNumBlocks, VLocTracker(OverlapFragments, EmptyExpr)); SavedLiveIns.resize(MaxNumBlocks); - initialSetup(MF); - produceMLocTransferFunction(MF, MLocTransfer, MaxNumBlocks); // Allocate and initialize two array-of-arrays for the live-in and live-out // machine values. The outer dimension is the block number; while the inner // dimension is a LocIdx from MLocTracker. - ValueIDNum **MOutLocs = new ValueIDNum *[MaxNumBlocks]; - ValueIDNum **MInLocs = new ValueIDNum *[MaxNumBlocks]; + FuncValueTable MOutLocs = std::make_unique<ValueTable[]>(MaxNumBlocks); + FuncValueTable MInLocs = std::make_unique<ValueTable[]>(MaxNumBlocks); unsigned NumLocs = MTracker->getNumLocs(); for (int i = 0; i < MaxNumBlocks; ++i) { // These all auto-initialize to ValueIDNum::EmptyValue - MOutLocs[i] = new ValueIDNum[NumLocs]; - MInLocs[i] = new ValueIDNum[NumLocs]; + MOutLocs[i] = std::make_unique<ValueIDNum[]>(NumLocs); + MInLocs[i] = std::make_unique<ValueIDNum[]>(NumLocs); } // Solve the machine value dataflow problem using the MLocTransfer function, @@ -3165,7 +3205,10 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, // either live-through machine values, or PHIs. for (auto &DBG_PHI : DebugPHINumToValue) { // Identify unresolved block-live-ins. - ValueIDNum &Num = DBG_PHI.ValueRead; + if (!DBG_PHI.ValueRead) + continue; + + ValueIDNum &Num = *DBG_PHI.ValueRead; if (!Num.isPHI()) continue; @@ -3186,7 +3229,7 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, MTracker->loadFromArray(MInLocs[CurBB], CurBB); CurInst = 1; for (auto &MI : MBB) { - process(MI, MOutLocs, MInLocs); + process(MI, MOutLocs.get(), MInLocs.get()); ++CurInst; } MTracker->reset(); @@ -3241,12 +3284,6 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, << " has " << MaxNumBlocks << " basic blocks and " << VarAssignCount << " variable assignments, exceeding limits.\n"); - - // Perform memory cleanup that emitLocations would do otherwise. - for (int Idx = 0; Idx < MaxNumBlocks; ++Idx) { - delete[] MOutLocs[Idx]; - delete[] MInLocs[Idx]; - } } else { // Optionally, solve the variable value problem and emit to blocks by using // a lexical-scope-depth search. It should be functionally identical to @@ -3256,10 +3293,6 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, SavedLiveIns, MOutLocs, MInLocs, vlocs, MF, AllVarsNumbering, *TPC); } - // Elements of these arrays will be deleted by emitLocations. - delete[] MOutLocs; - delete[] MInLocs; - delete MTracker; delete TTracker; MTracker = nullptr; @@ -3376,9 +3409,10 @@ public: /// Machine location where any PHI must occur. LocIdx Loc; /// Table of live-in machine value numbers for blocks / locations. - ValueIDNum **MLiveIns; + const ValueTable *MLiveIns; - LDVSSAUpdater(LocIdx L, ValueIDNum **MLiveIns) : Loc(L), MLiveIns(MLiveIns) {} + LDVSSAUpdater(LocIdx L, const ValueTable *MLiveIns) + : Loc(L), MLiveIns(MLiveIns) {} void reset() { for (auto &Block : BlockMap) @@ -3535,11 +3569,13 @@ public: } // end namespace llvm -Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIs(MachineFunction &MF, - ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns, - MachineInstr &Here, - uint64_t InstrNum) { +Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIs( + MachineFunction &MF, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns, MachineInstr &Here, uint64_t InstrNum) { + assert(MLiveOuts && MLiveIns && + "Tried to resolve DBG_PHI before location " + "tables allocated?"); + // This function will be called twice per DBG_INSTR_REF, and might end up // computing lots of SSA information: memoize it. auto SeenDbgPHIIt = SeenDbgPHIs.find(&Here); @@ -3553,8 +3589,8 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIs(MachineFunction &MF, } Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( - MachineFunction &MF, ValueIDNum **MLiveOuts, ValueIDNum **MLiveIns, - MachineInstr &Here, uint64_t InstrNum) { + MachineFunction &MF, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns, MachineInstr &Here, uint64_t InstrNum) { // Pick out records of DBG_PHI instructions that have been observed. If there // are none, then we cannot compute a value number. auto RangePair = std::equal_range(DebugPHINumToValue.begin(), @@ -3566,17 +3602,24 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( if (LowerIt == UpperIt) return None; + // If any DBG_PHIs referred to a location we didn't understand, don't try to + // compute a value. There might be scenarios where we could recover a value + // for some range of DBG_INSTR_REFs, but at this point we can have high + // confidence that we've seen a bug. + auto DBGPHIRange = make_range(LowerIt, UpperIt); + for (const DebugPHIRecord &DBG_PHI : DBGPHIRange) + if (!DBG_PHI.ValueRead) + return None; + // If there's only one DBG_PHI, then that is our value number. if (std::distance(LowerIt, UpperIt) == 1) - return LowerIt->ValueRead; - - auto DBGPHIRange = make_range(LowerIt, UpperIt); + return *LowerIt->ValueRead; // Pick out the location (physreg, slot) where any PHIs must occur. It's // technically possible for us to merge values in different registers in each // block, but highly unlikely that LLVM will generate such code after register // allocation. - LocIdx Loc = LowerIt->ReadLoc; + LocIdx Loc = *LowerIt->ReadLoc; // We have several DBG_PHIs, and a use position (the Here inst). All each // DBG_PHI does is identify a value at a program position. We can treat each @@ -3595,7 +3638,7 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( // for the SSAUpdater. for (const auto &DBG_PHI : DBGPHIRange) { LDVSSABlock *Block = Updater.getSSALDVBlock(DBG_PHI.MBB); - const ValueIDNum &Num = DBG_PHI.ValueRead; + const ValueIDNum &Num = *DBG_PHI.ValueRead; AvailableValues.insert(std::make_pair(Block, Num.asU64())); } @@ -3629,7 +3672,7 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( // Define all the input DBG_PHI values in ValidatedValues. for (const auto &DBG_PHI : DBGPHIRange) { LDVSSABlock *Block = Updater.getSSALDVBlock(DBG_PHI.MBB); - const ValueIDNum &Num = DBG_PHI.ValueRead; + const ValueIDNum &Num = *DBG_PHI.ValueRead; ValidatedValues.insert(std::make_pair(Block, Num)); } @@ -3654,7 +3697,7 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( return None; ValueIDNum ValueToCheck; - ValueIDNum *BlockLiveOuts = MLiveOuts[PHIIt.first->BB.getNumber()]; + const ValueTable &BlockLiveOuts = MLiveOuts[PHIIt.first->BB.getNumber()]; auto VVal = ValidatedValues.find(PHIIt.first); if (VVal == ValidatedValues.end()) { diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h index d778561db471..70aae47c8bdc 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h +++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h @@ -10,17 +10,14 @@ #define LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_INSTRREFBASEDLDV_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/UniqueVector.h" #include "llvm/CodeGen/LexicalScopes.h" #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/TargetFrameLowering.h" -#include "llvm/CodeGen/TargetInstrInfo.h" -#include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/IR/DebugInfoMetadata.h" #include "LiveDebugValues.h" @@ -171,6 +168,13 @@ public: static ValueIDNum TombstoneValue; }; +/// Type for a table of values in a block. +using ValueTable = std::unique_ptr<ValueIDNum[]>; + +/// Type for a table-of-table-of-values, i.e., the collection of either +/// live-in or live-out values for each block in the function. +using FuncValueTable = std::unique_ptr<ValueTable[]>; + /// Thin wrapper around an integer -- designed to give more type safety to /// spill location numbers. class SpillLocationNo { @@ -192,7 +196,7 @@ public: }; /// Meta qualifiers for a value. Pair of whatever expression is used to qualify -/// the the value, and Boolean of whether or not it's indirect. +/// the value, and Boolean of whether or not it's indirect. class DbgValueProperties { public: DbgValueProperties(const DIExpression *DIExpr, bool Indirect) @@ -507,7 +511,7 @@ public: /// Load values for each location from array of ValueIDNums. Take current /// bbnum just in case we read a value from a hitherto untouched register. - void loadFromArray(ValueIDNum *Locs, unsigned NewCurBB) { + void loadFromArray(ValueTable &Locs, unsigned NewCurBB) { CurBB = NewCurBB; // Iterate over all tracked locations, and load each locations live-in // value into our local index. @@ -629,6 +633,19 @@ public: /// Return true if Idx is a spill machine location. bool isSpill(LocIdx Idx) const { return LocIdxToLocID[Idx] >= NumRegs; } + /// How large is this location (aka, how wide is a value defined there?). + unsigned getLocSizeInBits(LocIdx L) const { + unsigned ID = LocIdxToLocID[L]; + if (!isSpill(L)) { + return TRI.getRegSizeInBits(Register(ID), MF.getRegInfo()); + } else { + // The slot location on the stack is uninteresting, we care about the + // position of the value within the slot (which comes with a size). + StackSlotPos Pos = locIDToSpillIdx(ID); + return Pos.first; + } + } + MLocIterator begin() { return MLocIterator(LocIdxToIDNum, 0); } MLocIterator end() { @@ -851,10 +868,16 @@ private: /// Record of where we observed a DBG_PHI instruction. class DebugPHIRecord { public: - uint64_t InstrNum; ///< Instruction number of this DBG_PHI. - MachineBasicBlock *MBB; ///< Block where DBG_PHI occurred. - ValueIDNum ValueRead; ///< The value number read by the DBG_PHI. - LocIdx ReadLoc; ///< Register/Stack location the DBG_PHI reads. + /// Instruction number of this DBG_PHI. + uint64_t InstrNum; + /// Block where DBG_PHI occurred. + MachineBasicBlock *MBB; + /// The value number read by the DBG_PHI -- or None if it didn't refer to + /// a value. + Optional<ValueIDNum> ValueRead; + /// Register/Stack location the DBG_PHI reads -- or None if it referred to + /// something unexpected. + Optional<LocIdx> ReadLoc; operator unsigned() const { return InstrNum; } }; @@ -909,8 +932,8 @@ private: extractSpillBaseRegAndOffset(const MachineInstr &MI); /// Observe a single instruction while stepping through a block. - void process(MachineInstr &MI, ValueIDNum **MLiveOuts = nullptr, - ValueIDNum **MLiveIns = nullptr); + void process(MachineInstr &MI, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns); /// Examines whether \p MI is a DBG_VALUE and notifies trackers. /// \returns true if MI was recognized and processed. @@ -918,8 +941,8 @@ private: /// Examines whether \p MI is a DBG_INSTR_REF and notifies trackers. /// \returns true if MI was recognized and processed. - bool transferDebugInstrRef(MachineInstr &MI, ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns); + bool transferDebugInstrRef(MachineInstr &MI, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns); /// Stores value-information about where this PHI occurred, and what /// instruction number is associated with it. @@ -951,13 +974,13 @@ private: /// \p InstrNum Debug instruction number defined by DBG_PHI instructions. /// \returns The machine value number at position Here, or None. Optional<ValueIDNum> resolveDbgPHIs(MachineFunction &MF, - ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns, MachineInstr &Here, - uint64_t InstrNum); + const ValueTable *MLiveOuts, + const ValueTable *MLiveIns, + MachineInstr &Here, uint64_t InstrNum); Optional<ValueIDNum> resolveDbgPHIsImpl(MachineFunction &MF, - ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns, + const ValueTable *MLiveOuts, + const ValueTable *MLiveIns, MachineInstr &Here, uint64_t InstrNum); @@ -975,8 +998,8 @@ private: /// live-out arrays to the (initialized to zero) multidimensional arrays in /// \p MInLocs and \p MOutLocs. The outer dimension is indexed by block /// number, the inner by LocIdx. - void buildMLocValueMap(MachineFunction &MF, ValueIDNum **MInLocs, - ValueIDNum **MOutLocs, + void buildMLocValueMap(MachineFunction &MF, FuncValueTable &MInLocs, + FuncValueTable &MOutLocs, SmallVectorImpl<MLocTransferMap> &MLocTransfer); /// Examine the stack indexes (i.e. offsets within the stack) to find the @@ -987,7 +1010,7 @@ private: /// the IDF of each register. void placeMLocPHIs(MachineFunction &MF, SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks, - ValueIDNum **MInLocs, + FuncValueTable &MInLocs, SmallVectorImpl<MLocTransferMap> &MLocTransfer); /// Propagate variable values to blocks in the common case where there's @@ -1018,7 +1041,7 @@ private: /// is true, revisiting this block is necessary. bool mlocJoin(MachineBasicBlock &MBB, SmallPtrSet<const MachineBasicBlock *, 16> &Visited, - ValueIDNum **OutLocs, ValueIDNum *InLocs); + FuncValueTable &OutLocs, ValueTable &InLocs); /// Produce a set of blocks that are in the current lexical scope. This means /// those blocks that contain instructions "in" the scope, blocks where @@ -1046,11 +1069,11 @@ private: /// scope, but which do contain DBG_VALUEs, which VarLocBasedImpl tracks /// locations through. void buildVLocValueMap(const DILocation *DILoc, - const SmallSet<DebugVariable, 4> &VarsWeCareAbout, - SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks, - LiveInsT &Output, ValueIDNum **MOutLocs, - ValueIDNum **MInLocs, - SmallVectorImpl<VLocTracker> &AllTheVLocs); + const SmallSet<DebugVariable, 4> &VarsWeCareAbout, + SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks, + LiveInsT &Output, FuncValueTable &MOutLocs, + FuncValueTable &MInLocs, + SmallVectorImpl<VLocTracker> &AllTheVLocs); /// Attempt to eliminate un-necessary PHIs on entry to a block. Examines the /// live-in values coming from predecessors live-outs, and replaces any PHIs @@ -1068,7 +1091,7 @@ private: /// \returns Value ID of a machine PHI if an appropriate one is available. Optional<ValueIDNum> pickVPHILoc(const MachineBasicBlock &MBB, const DebugVariable &Var, - const LiveIdxT &LiveOuts, ValueIDNum **MOutLocs, + const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs, const SmallVectorImpl<const MachineBasicBlock *> &BlockOrders); /// Take collections of DBG_VALUE instructions stored in TTracker, and @@ -1098,7 +1121,7 @@ private: bool depthFirstVLocAndEmit( unsigned MaxNumBlocks, const ScopeToDILocT &ScopeToDILocation, const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToBlocks, - LiveInsT &Output, ValueIDNum **MOutLocs, ValueIDNum **MInLocs, + LiveInsT &Output, FuncValueTable &MOutLocs, FuncValueTable &MInLocs, SmallVectorImpl<VLocTracker> &AllTheVLocs, MachineFunction &MF, DenseMap<DebugVariable, unsigned> &AllVarsNumbering, const TargetPassConfig &TPC); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp index 40770b15aa35..141008ac2296 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp @@ -8,14 +8,16 @@ #include "LiveDebugValues.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" +#include "llvm/PassRegistry.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Target/TargetMachine.h" /// \file LiveDebugValues.cpp /// @@ -65,7 +67,7 @@ public: static char ID; LiveDebugValues(); - ~LiveDebugValues() {} + ~LiveDebugValues() = default; /// Calculate the liveness information for the given machine function. bool runOnMachineFunction(MachineFunction &MF) override; diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h index 8f0b2ec3e1fc..6cc1685c0022 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h +++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h @@ -9,12 +9,11 @@ #ifndef LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_LIVEDEBUGVALUES_H #define LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_LIVEDEBUGVALUES_H -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/TargetPassConfig.h" -#include "llvm/ADT/Triple.h" - namespace llvm { +class MachineDominatorTree; +class MachineFunction; +class TargetPassConfig; +class Triple; // Inline namespace for types / symbols shared between different // LiveDebugValues implementations. @@ -28,7 +27,7 @@ public: virtual bool ExtendRanges(MachineFunction &MF, MachineDominatorTree *DomTree, TargetPassConfig *TPC, unsigned InputBBLimit, unsigned InputDbgValLimit) = 0; - virtual ~LDVImpl() {} + virtual ~LDVImpl() = default; }; } // namespace SharedLiveDebugValues diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp index 42a0967bce3f..24c00b8a10ec 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp @@ -118,18 +118,15 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/UniqueVector.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/LexicalScopes.h" #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/PseudoSourceValue.h" -#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetLowering.h" @@ -137,16 +134,11 @@ #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Config/llvm-config.h" -#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Function.h" -#include "llvm/IR/Module.h" -#include "llvm/InitializePasses.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/Pass.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/TypeSize.h" #include "llvm/Support/raw_ostream.h" @@ -922,14 +914,14 @@ private: std::unique_ptr<VarLocSet> &VLS = Locs[MBB]; if (!VLS) VLS = std::make_unique<VarLocSet>(Alloc); - return *VLS.get(); + return *VLS; } const VarLocSet &getVarLocsInMBB(const MachineBasicBlock *MBB, const VarLocInMBB &Locs) const { auto It = Locs.find(MBB); assert(It != Locs.end() && "MBB not in map"); - return *It->second.get(); + return *It->second; } /// Tests whether this instruction is a spill to a stack location. @@ -1035,9 +1027,9 @@ public: // Implementation //===----------------------------------------------------------------------===// -VarLocBasedLDV::VarLocBasedLDV() { } +VarLocBasedLDV::VarLocBasedLDV() = default; -VarLocBasedLDV::~VarLocBasedLDV() { } +VarLocBasedLDV::~VarLocBasedLDV() = default; /// Erase a variable from the set of open ranges, and additionally erase any /// fragments that may overlap it. If the VarLoc is a backup location, erase @@ -1948,7 +1940,7 @@ bool VarLocBasedLDV::join( // Just copy over the Out locs to incoming locs for the first visited // predecessor, and for all other predecessors join the Out locs. - VarLocSet &OutLocVLS = *OL->second.get(); + VarLocSet &OutLocVLS = *OL->second; if (!NumVisited) InLocsT = OutLocVLS; else @@ -2007,7 +1999,7 @@ void VarLocBasedLDV::flushPendingLocs(VarLocInMBB &PendingInLocs, for (auto &Iter : PendingInLocs) { // Map is keyed on a constant pointer, unwrap it so we can insert insts. auto &MBB = const_cast<MachineBasicBlock &>(*Iter.first); - VarLocSet &Pending = *Iter.second.get(); + VarLocSet &Pending = *Iter.second; SmallVector<VarLoc, 32> VarLocs; collectAllVarLocs(VarLocs, Pending, VarLocIDs); |