xref: /src/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1b60736ecSDimitry Andric //===- LiveDebugValues.cpp - Tracking Debug Value MIs ---------------------===//
2b60736ecSDimitry Andric //
3b60736ecSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b60736ecSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5b60736ecSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b60736ecSDimitry Andric //
7b60736ecSDimitry Andric //===----------------------------------------------------------------------===//
8b60736ecSDimitry Andric 
9b60736ecSDimitry Andric #include "LiveDebugValues.h"
10b60736ecSDimitry Andric 
11145449b1SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
12145449b1SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
13b60736ecSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
14b60736ecSDimitry Andric #include "llvm/CodeGen/Passes.h"
15145449b1SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
16b60736ecSDimitry Andric #include "llvm/InitializePasses.h"
17b60736ecSDimitry Andric #include "llvm/Pass.h"
18145449b1SDimitry Andric #include "llvm/PassRegistry.h"
19344a3780SDimitry Andric #include "llvm/Support/CommandLine.h"
20e3b55780SDimitry Andric #include "llvm/Target/TargetMachine.h"
217fa27ce4SDimitry Andric #include "llvm/TargetParser/Triple.h"
22b60736ecSDimitry Andric 
23b60736ecSDimitry Andric /// \file LiveDebugValues.cpp
24b60736ecSDimitry Andric ///
25b60736ecSDimitry Andric /// The LiveDebugValues pass extends the range of variable locations
26b60736ecSDimitry Andric /// (specified by DBG_VALUE instructions) from single blocks to successors
27b60736ecSDimitry Andric /// and any other code locations where the variable location is valid.
28b60736ecSDimitry Andric /// There are currently two implementations: the "VarLoc" implementation
29b60736ecSDimitry Andric /// explicitly tracks the location of a variable, while the "InstrRef"
30b60736ecSDimitry Andric /// implementation tracks the values defined by instructions through locations.
31b60736ecSDimitry Andric ///
32b60736ecSDimitry Andric /// This file implements neither; it merely registers the pass, allows the
33b60736ecSDimitry Andric /// user to pick which implementation will be used to propagate variable
34b60736ecSDimitry Andric /// locations.
35b60736ecSDimitry Andric 
36b60736ecSDimitry Andric #define DEBUG_TYPE "livedebugvalues"
37b60736ecSDimitry Andric 
38b60736ecSDimitry Andric using namespace llvm;
39b60736ecSDimitry Andric 
40344a3780SDimitry Andric static cl::opt<bool>
41344a3780SDimitry Andric     ForceInstrRefLDV("force-instr-ref-livedebugvalues", cl::Hidden,
42344a3780SDimitry Andric                      cl::desc("Use instruction-ref based LiveDebugValues with "
43344a3780SDimitry Andric                               "normal DBG_VALUE inputs"),
44344a3780SDimitry Andric                      cl::init(false));
45344a3780SDimitry Andric 
466f8fc217SDimitry Andric static cl::opt<cl::boolOrDefault> ValueTrackingVariableLocations(
476f8fc217SDimitry Andric     "experimental-debug-variable-locations",
486f8fc217SDimitry Andric     cl::desc("Use experimental new value-tracking variable locations"));
496f8fc217SDimitry Andric 
50c0981da4SDimitry Andric // Options to prevent pathological compile-time behavior. If InputBBLimit and
51c0981da4SDimitry Andric // InputDbgValueLimit are both exceeded, range extension is disabled.
52c0981da4SDimitry Andric static cl::opt<unsigned> InputBBLimit(
53c0981da4SDimitry Andric     "livedebugvalues-input-bb-limit",
54c0981da4SDimitry Andric     cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"),
55c0981da4SDimitry Andric     cl::init(10000), cl::Hidden);
56c0981da4SDimitry Andric static cl::opt<unsigned> InputDbgValueLimit(
57c0981da4SDimitry Andric     "livedebugvalues-input-dbg-value-limit",
58c0981da4SDimitry Andric     cl::desc(
59c0981da4SDimitry Andric         "Maximum input DBG_VALUE insts supported by debug range extension"),
60c0981da4SDimitry Andric     cl::init(50000), cl::Hidden);
61c0981da4SDimitry Andric 
62c0981da4SDimitry Andric namespace {
63b60736ecSDimitry Andric /// Generic LiveDebugValues pass. Calls through to VarLocBasedLDV or
64b60736ecSDimitry Andric /// InstrRefBasedLDV to perform location propagation, via the LDVImpl
65b60736ecSDimitry Andric /// base class.
66b60736ecSDimitry Andric class LiveDebugValues : public MachineFunctionPass {
67b60736ecSDimitry Andric public:
68b60736ecSDimitry Andric   static char ID;
69b60736ecSDimitry Andric 
70b60736ecSDimitry Andric   LiveDebugValues();
71145449b1SDimitry Andric   ~LiveDebugValues() = default;
72b60736ecSDimitry Andric 
73b60736ecSDimitry Andric   /// Calculate the liveness information for the given machine function.
74b60736ecSDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
75b60736ecSDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const76b60736ecSDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
77b60736ecSDimitry Andric     AU.setPreservesCFG();
78b60736ecSDimitry Andric     MachineFunctionPass::getAnalysisUsage(AU);
79b60736ecSDimitry Andric   }
80b60736ecSDimitry Andric 
81b60736ecSDimitry Andric private:
82c0981da4SDimitry Andric   std::unique_ptr<LDVImpl> InstrRefImpl;
83c0981da4SDimitry Andric   std::unique_ptr<LDVImpl> VarLocImpl;
847fa27ce4SDimitry Andric   TargetPassConfig *TPC = nullptr;
85c0981da4SDimitry Andric   MachineDominatorTree MDT;
86b60736ecSDimitry Andric };
87c0981da4SDimitry Andric } // namespace
88b60736ecSDimitry Andric 
89b60736ecSDimitry Andric char LiveDebugValues::ID = 0;
90b60736ecSDimitry Andric 
91b60736ecSDimitry Andric char &llvm::LiveDebugValuesID = LiveDebugValues::ID;
92b60736ecSDimitry Andric 
93b60736ecSDimitry Andric INITIALIZE_PASS(LiveDebugValues, DEBUG_TYPE, "Live DEBUG_VALUE analysis", false,
94b60736ecSDimitry Andric                 false)
95b60736ecSDimitry Andric 
96b60736ecSDimitry Andric /// Default construct and initialize the pass.
LiveDebugValues()97b60736ecSDimitry Andric LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) {
98b60736ecSDimitry Andric   initializeLiveDebugValuesPass(*PassRegistry::getPassRegistry());
99c0981da4SDimitry Andric   InstrRefImpl =
100c0981da4SDimitry Andric       std::unique_ptr<LDVImpl>(llvm::makeInstrRefBasedLiveDebugValues());
101c0981da4SDimitry Andric   VarLocImpl = std::unique_ptr<LDVImpl>(llvm::makeVarLocBasedLiveDebugValues());
102b60736ecSDimitry Andric }
103b60736ecSDimitry Andric 
runOnMachineFunction(MachineFunction & MF)104b60736ecSDimitry Andric bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
105e3b55780SDimitry Andric   // Except for Wasm, all targets should be only using physical register at this
106e3b55780SDimitry Andric   // point. Wasm only use virtual registers throught its pipeline, but its
107e3b55780SDimitry Andric   // virtual registers don't participate  in this LiveDebugValues analysis; only
108e3b55780SDimitry Andric   // its target indices do.
109e3b55780SDimitry Andric   assert(MF.getTarget().getTargetTriple().isWasm() ||
110e3b55780SDimitry Andric          MF.getProperties().hasProperty(
111e3b55780SDimitry Andric              MachineFunctionProperties::Property::NoVRegs));
112e3b55780SDimitry Andric 
113c0981da4SDimitry Andric   bool InstrRefBased = MF.useDebugInstrRef();
114344a3780SDimitry Andric   // Allow the user to force selection of InstrRef LDV.
115344a3780SDimitry Andric   InstrRefBased |= ForceInstrRefLDV;
116344a3780SDimitry Andric 
117c0981da4SDimitry Andric   TPC = getAnalysisIfAvailable<TargetPassConfig>();
118c0981da4SDimitry Andric   LDVImpl *TheImpl = &*VarLocImpl;
119c0981da4SDimitry Andric 
120c0981da4SDimitry Andric   MachineDominatorTree *DomTree = nullptr;
121c0981da4SDimitry Andric   if (InstrRefBased) {
122c0981da4SDimitry Andric     DomTree = &MDT;
123c0981da4SDimitry Andric     MDT.calculate(MF);
124c0981da4SDimitry Andric     TheImpl = &*InstrRefImpl;
125b60736ecSDimitry Andric   }
126b60736ecSDimitry Andric 
127c0981da4SDimitry Andric   return TheImpl->ExtendRanges(MF, DomTree, TPC, InputBBLimit,
128c0981da4SDimitry Andric                                InputDbgValueLimit);
129b60736ecSDimitry Andric }
1306f8fc217SDimitry Andric 
debuginfoShouldUseDebugInstrRef(const Triple & T)1316f8fc217SDimitry Andric bool llvm::debuginfoShouldUseDebugInstrRef(const Triple &T) {
132145449b1SDimitry Andric   // Enable by default on x86_64, disable if explicitly turned off on cmdline.
133145449b1SDimitry Andric   if (T.getArch() == llvm::Triple::x86_64 &&
134145449b1SDimitry Andric       ValueTrackingVariableLocations != cl::boolOrDefault::BOU_FALSE)
135145449b1SDimitry Andric     return true;
136145449b1SDimitry Andric 
1376f8fc217SDimitry Andric   // Enable if explicitly requested on command line.
1386f8fc217SDimitry Andric   return ValueTrackingVariableLocations == cl::boolOrDefault::BOU_TRUE;
1396f8fc217SDimitry Andric }
140