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