1e8d8bef9SDimitry Andric //===- LiveDebugValues.cpp - Tracking Debug Value MIs ---------------------===// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric 9e8d8bef9SDimitry Andric #include "LiveDebugValues.h" 10e8d8bef9SDimitry Andric 1181ad6265SDimitry Andric #include "llvm/ADT/Triple.h" 1281ad6265SDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 1381ad6265SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 14e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 15e8d8bef9SDimitry Andric #include "llvm/CodeGen/Passes.h" 1681ad6265SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 17e8d8bef9SDimitry Andric #include "llvm/InitializePasses.h" 18e8d8bef9SDimitry Andric #include "llvm/Pass.h" 1981ad6265SDimitry Andric #include "llvm/PassRegistry.h" 20fe6060f1SDimitry Andric #include "llvm/Support/CommandLine.h" 21*bdd1243dSDimitry Andric #include "llvm/Target/TargetMachine.h" 22e8d8bef9SDimitry Andric 23e8d8bef9SDimitry Andric /// \file LiveDebugValues.cpp 24e8d8bef9SDimitry Andric /// 25e8d8bef9SDimitry Andric /// The LiveDebugValues pass extends the range of variable locations 26e8d8bef9SDimitry Andric /// (specified by DBG_VALUE instructions) from single blocks to successors 27e8d8bef9SDimitry Andric /// and any other code locations where the variable location is valid. 28e8d8bef9SDimitry Andric /// There are currently two implementations: the "VarLoc" implementation 29e8d8bef9SDimitry Andric /// explicitly tracks the location of a variable, while the "InstrRef" 30e8d8bef9SDimitry Andric /// implementation tracks the values defined by instructions through locations. 31e8d8bef9SDimitry Andric /// 32e8d8bef9SDimitry Andric /// This file implements neither; it merely registers the pass, allows the 33e8d8bef9SDimitry Andric /// user to pick which implementation will be used to propagate variable 34e8d8bef9SDimitry Andric /// locations. 35e8d8bef9SDimitry Andric 36e8d8bef9SDimitry Andric #define DEBUG_TYPE "livedebugvalues" 37e8d8bef9SDimitry Andric 38e8d8bef9SDimitry Andric using namespace llvm; 39e8d8bef9SDimitry Andric 40fe6060f1SDimitry Andric static cl::opt<bool> 41fe6060f1SDimitry Andric ForceInstrRefLDV("force-instr-ref-livedebugvalues", cl::Hidden, 42fe6060f1SDimitry Andric cl::desc("Use instruction-ref based LiveDebugValues with " 43fe6060f1SDimitry Andric "normal DBG_VALUE inputs"), 44fe6060f1SDimitry Andric cl::init(false)); 45fe6060f1SDimitry Andric 4604eeddc0SDimitry Andric static cl::opt<cl::boolOrDefault> ValueTrackingVariableLocations( 4704eeddc0SDimitry Andric "experimental-debug-variable-locations", 4804eeddc0SDimitry Andric cl::desc("Use experimental new value-tracking variable locations")); 4904eeddc0SDimitry Andric 50349cc55cSDimitry Andric // Options to prevent pathological compile-time behavior. If InputBBLimit and 51349cc55cSDimitry Andric // InputDbgValueLimit are both exceeded, range extension is disabled. 52349cc55cSDimitry Andric static cl::opt<unsigned> InputBBLimit( 53349cc55cSDimitry Andric "livedebugvalues-input-bb-limit", 54349cc55cSDimitry Andric cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"), 55349cc55cSDimitry Andric cl::init(10000), cl::Hidden); 56349cc55cSDimitry Andric static cl::opt<unsigned> InputDbgValueLimit( 57349cc55cSDimitry Andric "livedebugvalues-input-dbg-value-limit", 58349cc55cSDimitry Andric cl::desc( 59349cc55cSDimitry Andric "Maximum input DBG_VALUE insts supported by debug range extension"), 60349cc55cSDimitry Andric cl::init(50000), cl::Hidden); 61349cc55cSDimitry Andric 62349cc55cSDimitry Andric namespace { 63e8d8bef9SDimitry Andric /// Generic LiveDebugValues pass. Calls through to VarLocBasedLDV or 64e8d8bef9SDimitry Andric /// InstrRefBasedLDV to perform location propagation, via the LDVImpl 65e8d8bef9SDimitry Andric /// base class. 66e8d8bef9SDimitry Andric class LiveDebugValues : public MachineFunctionPass { 67e8d8bef9SDimitry Andric public: 68e8d8bef9SDimitry Andric static char ID; 69e8d8bef9SDimitry Andric 70e8d8bef9SDimitry Andric LiveDebugValues(); 7181ad6265SDimitry Andric ~LiveDebugValues() = default; 72e8d8bef9SDimitry Andric 73e8d8bef9SDimitry Andric /// Calculate the liveness information for the given machine function. 74e8d8bef9SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 75e8d8bef9SDimitry Andric 76e8d8bef9SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 77e8d8bef9SDimitry Andric AU.setPreservesCFG(); 78e8d8bef9SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 79e8d8bef9SDimitry Andric } 80e8d8bef9SDimitry Andric 81e8d8bef9SDimitry Andric private: 82349cc55cSDimitry Andric std::unique_ptr<LDVImpl> InstrRefImpl; 83349cc55cSDimitry Andric std::unique_ptr<LDVImpl> VarLocImpl; 84e8d8bef9SDimitry Andric TargetPassConfig *TPC; 85349cc55cSDimitry Andric MachineDominatorTree MDT; 86e8d8bef9SDimitry Andric }; 87349cc55cSDimitry Andric } // namespace 88e8d8bef9SDimitry Andric 89e8d8bef9SDimitry Andric char LiveDebugValues::ID = 0; 90e8d8bef9SDimitry Andric 91e8d8bef9SDimitry Andric char &llvm::LiveDebugValuesID = LiveDebugValues::ID; 92e8d8bef9SDimitry Andric 93e8d8bef9SDimitry Andric INITIALIZE_PASS(LiveDebugValues, DEBUG_TYPE, "Live DEBUG_VALUE analysis", false, 94e8d8bef9SDimitry Andric false) 95e8d8bef9SDimitry Andric 96e8d8bef9SDimitry Andric /// Default construct and initialize the pass. 97e8d8bef9SDimitry Andric LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) { 98e8d8bef9SDimitry Andric initializeLiveDebugValuesPass(*PassRegistry::getPassRegistry()); 99349cc55cSDimitry Andric InstrRefImpl = 100349cc55cSDimitry Andric std::unique_ptr<LDVImpl>(llvm::makeInstrRefBasedLiveDebugValues()); 101349cc55cSDimitry Andric VarLocImpl = std::unique_ptr<LDVImpl>(llvm::makeVarLocBasedLiveDebugValues()); 102e8d8bef9SDimitry Andric } 103e8d8bef9SDimitry Andric 104e8d8bef9SDimitry Andric bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) { 105*bdd1243dSDimitry Andric // Except for Wasm, all targets should be only using physical register at this 106*bdd1243dSDimitry Andric // point. Wasm only use virtual registers throught its pipeline, but its 107*bdd1243dSDimitry Andric // virtual registers don't participate in this LiveDebugValues analysis; only 108*bdd1243dSDimitry Andric // its target indices do. 109*bdd1243dSDimitry Andric assert(MF.getTarget().getTargetTriple().isWasm() || 110*bdd1243dSDimitry Andric MF.getProperties().hasProperty( 111*bdd1243dSDimitry Andric MachineFunctionProperties::Property::NoVRegs)); 112*bdd1243dSDimitry Andric 113349cc55cSDimitry Andric bool InstrRefBased = MF.useDebugInstrRef(); 114fe6060f1SDimitry Andric // Allow the user to force selection of InstrRef LDV. 115fe6060f1SDimitry Andric InstrRefBased |= ForceInstrRefLDV; 116fe6060f1SDimitry Andric 117349cc55cSDimitry Andric TPC = getAnalysisIfAvailable<TargetPassConfig>(); 118349cc55cSDimitry Andric LDVImpl *TheImpl = &*VarLocImpl; 119349cc55cSDimitry Andric 120349cc55cSDimitry Andric MachineDominatorTree *DomTree = nullptr; 121349cc55cSDimitry Andric if (InstrRefBased) { 122349cc55cSDimitry Andric DomTree = &MDT; 123349cc55cSDimitry Andric MDT.calculate(MF); 124349cc55cSDimitry Andric TheImpl = &*InstrRefImpl; 125e8d8bef9SDimitry Andric } 126e8d8bef9SDimitry Andric 127349cc55cSDimitry Andric return TheImpl->ExtendRanges(MF, DomTree, TPC, InputBBLimit, 128349cc55cSDimitry Andric InputDbgValueLimit); 129e8d8bef9SDimitry Andric } 13004eeddc0SDimitry Andric 13104eeddc0SDimitry Andric bool llvm::debuginfoShouldUseDebugInstrRef(const Triple &T) { 132d56accc7SDimitry Andric // Enable by default on x86_64, disable if explicitly turned off on cmdline. 133d56accc7SDimitry Andric if (T.getArch() == llvm::Triple::x86_64 && 134d56accc7SDimitry Andric ValueTrackingVariableLocations != cl::boolOrDefault::BOU_FALSE) 135d56accc7SDimitry Andric return true; 136d56accc7SDimitry Andric 13704eeddc0SDimitry Andric // Enable if explicitly requested on command line. 13804eeddc0SDimitry Andric return ValueTrackingVariableLocations == cl::boolOrDefault::BOU_TRUE; 13904eeddc0SDimitry Andric } 140