1af732203SDimitry Andric //===- LiveDebugValues.cpp - Tracking Debug Value MIs ---------------------===//
2af732203SDimitry Andric //
3af732203SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4af732203SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5af732203SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6af732203SDimitry Andric //
7af732203SDimitry Andric //===----------------------------------------------------------------------===//
8af732203SDimitry Andric 
9af732203SDimitry Andric #include "LiveDebugValues.h"
10af732203SDimitry Andric 
11af732203SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
12af732203SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
13af732203SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
14af732203SDimitry Andric #include "llvm/CodeGen/Passes.h"
15af732203SDimitry Andric #include "llvm/InitializePasses.h"
16af732203SDimitry Andric #include "llvm/Pass.h"
17*5f7ddb14SDimitry Andric #include "llvm/Support/CommandLine.h"
18af732203SDimitry Andric #include "llvm/Target/TargetMachine.h"
19af732203SDimitry Andric 
20af732203SDimitry Andric /// \file LiveDebugValues.cpp
21af732203SDimitry Andric ///
22af732203SDimitry Andric /// The LiveDebugValues pass extends the range of variable locations
23af732203SDimitry Andric /// (specified by DBG_VALUE instructions) from single blocks to successors
24af732203SDimitry Andric /// and any other code locations where the variable location is valid.
25af732203SDimitry Andric /// There are currently two implementations: the "VarLoc" implementation
26af732203SDimitry Andric /// explicitly tracks the location of a variable, while the "InstrRef"
27af732203SDimitry Andric /// implementation tracks the values defined by instructions through locations.
28af732203SDimitry Andric ///
29af732203SDimitry Andric /// This file implements neither; it merely registers the pass, allows the
30af732203SDimitry Andric /// user to pick which implementation will be used to propagate variable
31af732203SDimitry Andric /// locations.
32af732203SDimitry Andric 
33af732203SDimitry Andric #define DEBUG_TYPE "livedebugvalues"
34af732203SDimitry Andric 
35af732203SDimitry Andric using namespace llvm;
36af732203SDimitry Andric 
37*5f7ddb14SDimitry Andric static cl::opt<bool>
38*5f7ddb14SDimitry Andric     ForceInstrRefLDV("force-instr-ref-livedebugvalues", cl::Hidden,
39*5f7ddb14SDimitry Andric                      cl::desc("Use instruction-ref based LiveDebugValues with "
40*5f7ddb14SDimitry Andric                               "normal DBG_VALUE inputs"),
41*5f7ddb14SDimitry Andric                      cl::init(false));
42*5f7ddb14SDimitry Andric 
43af732203SDimitry Andric /// Generic LiveDebugValues pass. Calls through to VarLocBasedLDV or
44af732203SDimitry Andric /// InstrRefBasedLDV to perform location propagation, via the LDVImpl
45af732203SDimitry Andric /// base class.
46af732203SDimitry Andric class LiveDebugValues : public MachineFunctionPass {
47af732203SDimitry Andric public:
48af732203SDimitry Andric   static char ID;
49af732203SDimitry Andric 
50af732203SDimitry Andric   LiveDebugValues();
~LiveDebugValues()51af732203SDimitry Andric   ~LiveDebugValues() {
52af732203SDimitry Andric     if (TheImpl)
53af732203SDimitry Andric       delete TheImpl;
54af732203SDimitry Andric   }
55af732203SDimitry Andric 
56af732203SDimitry Andric   /// Calculate the liveness information for the given machine function.
57af732203SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
58af732203SDimitry Andric 
getRequiredProperties() const59af732203SDimitry Andric   MachineFunctionProperties getRequiredProperties() const override {
60af732203SDimitry Andric     return MachineFunctionProperties().set(
61af732203SDimitry Andric         MachineFunctionProperties::Property::NoVRegs);
62af732203SDimitry Andric   }
63af732203SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const64af732203SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
65af732203SDimitry Andric     AU.setPreservesCFG();
66af732203SDimitry Andric     MachineFunctionPass::getAnalysisUsage(AU);
67af732203SDimitry Andric   }
68af732203SDimitry Andric 
69af732203SDimitry Andric private:
70af732203SDimitry Andric   LDVImpl *TheImpl;
71af732203SDimitry Andric   TargetPassConfig *TPC;
72af732203SDimitry Andric };
73af732203SDimitry Andric 
74af732203SDimitry Andric char LiveDebugValues::ID = 0;
75af732203SDimitry Andric 
76af732203SDimitry Andric char &llvm::LiveDebugValuesID = LiveDebugValues::ID;
77af732203SDimitry Andric 
78af732203SDimitry Andric INITIALIZE_PASS(LiveDebugValues, DEBUG_TYPE, "Live DEBUG_VALUE analysis", false,
79af732203SDimitry Andric                 false)
80af732203SDimitry Andric 
81af732203SDimitry Andric /// Default construct and initialize the pass.
LiveDebugValues()82af732203SDimitry Andric LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) {
83af732203SDimitry Andric   initializeLiveDebugValuesPass(*PassRegistry::getPassRegistry());
84af732203SDimitry Andric   TheImpl = nullptr;
85af732203SDimitry Andric }
86af732203SDimitry Andric 
runOnMachineFunction(MachineFunction & MF)87af732203SDimitry Andric bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
88af732203SDimitry Andric   if (!TheImpl) {
89af732203SDimitry Andric     TPC = getAnalysisIfAvailable<TargetPassConfig>();
90af732203SDimitry Andric 
91af732203SDimitry Andric     bool InstrRefBased = false;
92af732203SDimitry Andric     if (TPC) {
93af732203SDimitry Andric       auto &TM = TPC->getTM<TargetMachine>();
94af732203SDimitry Andric       InstrRefBased = TM.Options.ValueTrackingVariableLocations;
95af732203SDimitry Andric     }
96af732203SDimitry Andric 
97*5f7ddb14SDimitry Andric     // Allow the user to force selection of InstrRef LDV.
98*5f7ddb14SDimitry Andric     InstrRefBased |= ForceInstrRefLDV;
99*5f7ddb14SDimitry Andric 
100af732203SDimitry Andric     if (InstrRefBased)
101af732203SDimitry Andric       TheImpl = llvm::makeInstrRefBasedLiveDebugValues();
102af732203SDimitry Andric     else
103af732203SDimitry Andric       TheImpl = llvm::makeVarLocBasedLiveDebugValues();
104af732203SDimitry Andric   }
105af732203SDimitry Andric 
106af732203SDimitry Andric   return TheImpl->ExtendRanges(MF, TPC);
107af732203SDimitry Andric }
108