Index: llvm/lib/Transforms/Utils/Debugify.cpp =================================================================== --- llvm/lib/Transforms/Utils/Debugify.cpp +++ llvm/lib/Transforms/Utils/Debugify.cpp @@ -51,6 +51,24 @@ raw_ostream &dbg() { return Quiet ? nulls() : errs(); } +enum class LimitNum : unsigned int { + Zero = 0, + Default = 10000, + Unlimited = UINT_MAX +}; + +// Limit number of processed instructions during collectDebugInfoMetadata +// and checkDebugInfoMetadata. +cl::opt DebugifyInstrLimit( + "debugify-instr-limit", + cl::desc("Set limit for the number of observed instructions per pass."), + cl::values(clEnumValN(LimitNum::Zero, "zero", + "Don't process any instructions"), + clEnumValN(LimitNum::Default, "default", + "Set limit to 10000 instructions"), + clEnumValN(LimitNum::Unlimited, "unlimited", "No limit")), + cl::init(LimitNum::Default)); + uint64_t getAllocSizeInBits(Module &M, Type *Ty) { return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0; } @@ -296,6 +314,18 @@ return false; } + unsigned int InstrCounter; + switch (DebugifyInstrLimit) { + case LimitNum::Default: + InstrCounter = static_cast(LimitNum::Default); + break; + case LimitNum::Unlimited: + InstrCounter = static_cast(LimitNum::Unlimited); + break; + default: + InstrCounter = static_cast(LimitNum::Zero); + } + // Visit each instruction. for (Function &F : Functions) { if (isFunctionSkipped(F)) @@ -319,6 +349,8 @@ // Skip PHIs. if (isa(I)) continue; + if (InstrCounter-- == 0) + return true; // Cllect dbg.values and dbg.declare. if (DebugifyLevel > Level::Locations) { @@ -533,8 +565,22 @@ // Map the debug info holding DIs after a pass. DebugInfoPerPass DebugInfoAfterPass; + unsigned int InstrCounter; + switch (DebugifyInstrLimit) { + case LimitNum::Default: + InstrCounter = static_cast(LimitNum::Default); + break; + case LimitNum::Unlimited: + InstrCounter = static_cast(LimitNum::Unlimited); + break; + default: + InstrCounter = static_cast(LimitNum::Zero); + } + // Visit each instruction. for (Function &F : Functions) { + if (InstrCounter == 0) + break; if (isFunctionSkipped(F)) continue; @@ -553,11 +599,17 @@ } for (BasicBlock &BB : F) { + if (InstrCounter == 0) + break; // Collect debug locations (!dbg) and debug variable intrinsics. for (Instruction &I : BB) { // Skip PHIs. if (isa(I)) continue; + if (InstrCounter == 0) + break; + else + --InstrCounter; // Collect dbg.values and dbg.declares. if (DebugifyLevel > Level::Locations) { Index: llvm/test/Transforms/Util/Debugify/loc-only-original-mode.ll =================================================================== --- llvm/test/Transforms/Util/Debugify/loc-only-original-mode.ll +++ llvm/test/Transforms/Util/Debugify/loc-only-original-mode.ll @@ -2,8 +2,18 @@ ; RUN: -verify-each-debuginfo-preserve \ ; RUN: -debugify-level=locations -S 2>&1 | FileCheck %s +; RUN: opt < %s -deadargelim -enable-new-pm=false \ +; RUN: -verify-each-debuginfo-preserve \ +; RUN: -debugify-instr-limit=zero -S 2>&1 | FileCheck %s + +; RUN: opt < %s -deadargelim -enable-new-pm=false \ +; RUN: -verify-each-debuginfo-preserve -debugify-instr-limit=unlimited \ +; RUN: -S 2>&1 | FileCheck %s --check-prefix=UNLIMITED + ;; Ensure that we check for DILocation potential issues only. ; CHECK-NOT: drops dbg.value()/dbg.declare() +; UNLIMITED: drops dbg.value()/dbg.declare() + target triple = "x86_64-unknown-linux-gnu"