diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -1684,7 +1684,8 @@ /// RPOT block ordering. void initialSetup(MachineFunction &MF); - bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) override; + bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC, + unsigned InputBBLimit, unsigned InputDbgValLimit) override; public: /// Default construct and initialize the pass. @@ -3523,8 +3524,9 @@ /// Calculate the liveness information for the given machine function and /// extend ranges across basic blocks. -bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, - TargetPassConfig *TPC) { +bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC, + unsigned InputBBLimit, + unsigned InputDbgValLimit) { // No subprogram means this function contains no debuginfo. if (!MF.getFunction().getSubprogram()) return false; @@ -3626,6 +3628,7 @@ // To mirror old LiveDebugValues, enumerate variables in RPOT order. Otherwise // the order is unimportant, it just has to be stable. + unsigned VarAssignCount = 0; for (unsigned int I = 0; I < OrderToBB.size(); ++I) { auto *MBB = OrderToBB[I]; auto *VTracker = &vlocs[MBB->getNumber()]; @@ -3643,24 +3646,42 @@ ScopeToVars[Scope].insert(Var); ScopeToBlocks[Scope].insert(VTracker->MBB); ScopeToDILocation[Scope] = ScopeLoc; + ++VarAssignCount; } } - // OK. Iterate over scopes: there might be something to be said for - // ordering them by size/locality, but that's for the future. For each scope, - // solve the variable value problem, producing a map of variables to values - // in SavedLiveIns. - for (auto &P : ScopeToVars) { - vlocDataflow(P.first, ScopeToDILocation[P.first], P.second, - ScopeToBlocks[P.first], SavedLiveIns, MOutLocs, MInLocs, - vlocs); - } + bool Changed = false; + + // If we have an extremely large number of variable assignments and blocks, + // bail out at this point. We've burnt some time doing analysis already, + // however we should cut our losses. + if ((unsigned)MaxNumBlocks > InputBBLimit && + VarAssignCount > InputDbgValLimit) { + LLVM_DEBUG(dbgs() << "Disabling InstrRefBasedLDV: " << MF.getName() + << " has " << MaxNumBlocks << " basic blocks and " + << VarAssignCount + << " variable assignments, exceeding limits.\n"); + } else { + // Compute the extended ranges, iterating over scopes. There might be + // something to be said for ordering them by size/locality, but that's for + // the future. For each scope, solve the variable value problem, producing + // a map of variables to values in SavedLiveIns. + for (auto &P : ScopeToVars) { + vlocDataflow(P.first, ScopeToDILocation[P.first], P.second, + ScopeToBlocks[P.first], SavedLiveIns, MOutLocs, MInLocs, + vlocs); + } + + // Using the computed value locations and variable values for each block, + // create the DBG_VALUE instructions representing the extended variable + // locations. + emitLocations(MF, SavedLiveIns, MOutLocs, MInLocs, AllVarsNumbering, *TPC); - // Using the computed value locations and variable values for each block, - // create the DBG_VALUE instructions representing the extended variable - // locations. - emitLocations(MF, SavedLiveIns, MOutLocs, MInLocs, AllVarsNumbering, *TPC); + // Did we actually make any changes? If we created any DBG_VALUEs, then yes. + Changed = TTracker->Transfers.size() != 0; + } + // Common clean-up of memory. for (int Idx = 0; Idx < MaxNumBlocks; ++Idx) { delete[] MOutLocs[Idx]; delete[] MInLocs[Idx]; @@ -3668,9 +3689,6 @@ delete[] MOutLocs; delete[] MInLocs; - // Did we actually make any changes? If we created any DBG_VALUEs, then yes. - bool Changed = TTracker->Transfers.size() != 0; - delete MTracker; delete TTracker; MTracker = nullptr; diff --git a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h --- a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h +++ b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.h @@ -23,7 +23,9 @@ // implementation. class LDVImpl { public: - virtual bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) = 0; + virtual bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC, + unsigned InputBBLimit, + unsigned InputDbgValLimit) = 0; virtual ~LDVImpl() {} }; diff --git a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp --- a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp @@ -40,6 +40,18 @@ "normal DBG_VALUE inputs"), cl::init(false)); +// Options to prevent pathological compile-time behavior. If InputBBLimit and +// InputDbgValueLimit are both exceeded, range extension is disabled. +static cl::opt InputBBLimit( + "livedebugvalues-input-bb-limit", + cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"), + cl::init(10000), cl::Hidden); +static cl::opt InputDbgValueLimit( + "livedebugvalues-input-dbg-value-limit", + cl::desc( + "Maximum input DBG_VALUE insts supported by debug range extension"), + cl::init(50000), cl::Hidden); + /// Generic LiveDebugValues pass. Calls through to VarLocBasedLDV or /// InstrRefBasedLDV to perform location propagation, via the LDVImpl /// base class. @@ -103,5 +115,5 @@ TheImpl = llvm::makeVarLocBasedLiveDebugValues(); } - return TheImpl->ExtendRanges(MF, TPC); + return TheImpl->ExtendRanges(MF, TPC, InputBBLimit, InputDbgValueLimit); } diff --git a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp --- a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp @@ -166,18 +166,6 @@ STATISTIC(NumInserted, "Number of DBG_VALUE instructions inserted"); -// Options to prevent pathological compile-time behavior. If InputBBLimit and -// InputDbgValueLimit are both exceeded, range extension is disabled. -static cl::opt InputBBLimit( - "livedebugvalues-input-bb-limit", - cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"), - cl::init(10000), cl::Hidden); -static cl::opt InputDbgValueLimit( - "livedebugvalues-input-dbg-value-limit", - cl::desc( - "Maximum input DBG_VALUE insts supported by debug range extension"), - cl::init(50000), cl::Hidden); - /// If \p Op is a stack or frame register return true, otherwise return false. /// This is used to avoid basing the debug entry values on the registers, since /// we do not support it at the moment. @@ -1007,7 +995,8 @@ /// had their instruction creation deferred. void flushPendingLocs(VarLocInMBB &PendingInLocs, VarLocMap &VarLocIDs); - bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) override; + bool ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC, + unsigned InputBBLimit, unsigned InputDbgValLimit) override; public: /// Default construct and initialize the pass. @@ -2048,7 +2037,9 @@ /// Calculate the liveness information for the given machine function and /// extend ranges across basic blocks. -bool VarLocBasedLDV::ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC) { +bool VarLocBasedLDV::ExtendRanges(MachineFunction &MF, TargetPassConfig *TPC, + unsigned InputBBLimit, + unsigned InputDbgValLimit) { LLVM_DEBUG(dbgs() << "\nDebug Range Extension\n"); if (!MF.getFunction().getSubprogram()) @@ -2141,7 +2132,7 @@ for (auto &MI : MBB) if (MI.isDebugValue()) ++NumInputDbgValues; - if (NumInputDbgValues > InputDbgValueLimit) { + if (NumInputDbgValues > InputDbgValLimit) { LLVM_DEBUG(dbgs() << "Disabling VarLocBasedLDV: " << MF.getName() << " has " << RPONumber << " basic blocks and " << NumInputDbgValues diff --git a/llvm/test/DebugInfo/MIR/X86/live-debug-values-cutoffs.mir b/llvm/test/DebugInfo/MIR/X86/live-debug-values-cutoffs.mir --- a/llvm/test/DebugInfo/MIR/X86/live-debug-values-cutoffs.mir +++ b/llvm/test/DebugInfo/MIR/X86/live-debug-values-cutoffs.mir @@ -5,21 +5,41 @@ # RUN: -livedebugvalues-input-bb-limit=1 \ # RUN: -livedebugvalues-input-dbg-value-limit=1 \ # RUN: | FileCheck %s -check-prefix=LDV-DISABLED +# RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown \ +# RUN: -experimental-debug-variable-locations \ +# RUN: -livedebugvalues-input-bb-limit=1 \ +# RUN: -livedebugvalues-input-dbg-value-limit=1 \ +# RUN: | FileCheck %s -check-prefix=LDV-DISABLED # RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown \ # RUN: -livedebugvalues-input-bb-limit=1 \ # RUN: -livedebugvalues-input-dbg-value-limit=10 \ # RUN: | FileCheck %s -check-prefix=LDV-ENABLED +# RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown \ +# RUN: -experimental-debug-variable-locations \ +# RUN: -livedebugvalues-input-bb-limit=1 \ +# RUN: -livedebugvalues-input-dbg-value-limit=10 \ +# RUN: | FileCheck %s -check-prefix=LDV-ENABLED # RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown \ # RUN: -livedebugvalues-input-bb-limit=10 \ # RUN: -livedebugvalues-input-dbg-value-limit=1 \ # RUN: | FileCheck %s -check-prefix=LDV-ENABLED +# RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown \ +# RUN: -experimental-debug-variable-locations \ +# RUN: -livedebugvalues-input-bb-limit=10 \ +# RUN: -livedebugvalues-input-dbg-value-limit=1 \ +# RUN: | FileCheck %s -check-prefix=LDV-ENABLED # RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown \ # RUN: -livedebugvalues-input-bb-limit=10 \ # RUN: -livedebugvalues-input-dbg-value-limit=10 \ # RUN: | FileCheck %s -check-prefix=LDV-ENABLED +# RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown \ +# RUN: -experimental-debug-variable-locations \ +# RUN: -livedebugvalues-input-bb-limit=10 \ +# RUN: -livedebugvalues-input-dbg-value-limit=10 \ +# RUN: | FileCheck %s -check-prefix=LDV-ENABLED # LDV-DISABLED-LABEL: bb.1.exit # LDV-DISABLED-NEXT: $edi = MOV32rm