LLVM  15.0.0git
MIRFSDiscriminator.cpp
Go to the documentation of this file.
1 //===-------- MIRFSDiscriminator.cpp: Flow Sensitive Discriminator --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides the implementation of a machine pass that adds the flow
10 // sensitive discriminator to the instruction debug information.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/DenseSet.h"
18 #include "llvm/CodeGen/Passes.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/InitializePasses.h"
23 #include "llvm/Support/Debug.h"
26 
27 using namespace llvm;
28 using namespace sampleprof;
29 using namespace sampleprofutil;
30 
31 #define DEBUG_TYPE "mirfs-discriminators"
32 
34 
36  "Add MIR Flow Sensitive Discriminators",
37  /* cfg = */ false, /* is_analysis = */ false)
38 
40 
42  return new MIRAddFSDiscriminators(P);
43 }
44 
45 // Compute a hash value using debug line number, and the line numbers from the
46 // inline stack.
48  const MachineInstr &MI,
49  const DILocation *DIL) {
50  auto updateHash = [](const StringRef &Str) -> uint64_t {
51  if (Str.empty())
52  return 0;
53  return MD5Hash(Str);
54  };
55  uint64_t Ret = updateHash(std::to_string(DIL->getLine()));
56  Ret ^= updateHash(BB.getName());
57  Ret ^= updateHash(DIL->getScope()->getSubprogram()->getLinkageName());
58  for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
59  Ret ^= updateHash(std::to_string(DIL->getLine()));
60  Ret ^= updateHash(DIL->getScope()->getSubprogram()->getLinkageName());
61  }
62  return Ret;
63 }
64 
65 // Traverse the CFG and assign FD discriminators. If two instructions
66 // have the same lineno and discriminator, but residing in different BBs,
67 // the latter instruction will get a new discriminator value. The new
68 // discriminator keeps the existing discriminator value but sets new bits
69 // b/w LowBit and HighBit.
70 bool MIRAddFSDiscriminators::runOnMachineFunction(MachineFunction &MF) {
72  return false;
74  return false;
75 
76  bool Changed = false;
77  using LocationDiscriminator = std::tuple<StringRef, unsigned, unsigned>;
79  using LocationDiscriminatorBBMap = DenseMap<LocationDiscriminator, BBSet>;
80  using LocationDiscriminatorCurrPassMap =
82 
83  LocationDiscriminatorBBMap LDBM;
84  LocationDiscriminatorCurrPassMap LDCM;
85 
86  // Mask of discriminators before this pass.
87  unsigned BitMaskBefore = getN1Bits(LowBit);
88  // Mask of discriminators including this pass.
89  unsigned BitMaskNow = getN1Bits(HighBit);
90  // Mask of discriminators for bits specific to this pass.
91  unsigned BitMaskThisPass = BitMaskNow ^ BitMaskBefore;
92  unsigned NumNewD = 0;
93 
94  LLVM_DEBUG(dbgs() << "MIRAddFSDiscriminators working on Func: "
95  << MF.getFunction().getName() << "\n");
96  for (MachineBasicBlock &BB : MF) {
97  for (MachineInstr &I : BB) {
98  const DILocation *DIL = I.getDebugLoc().get();
99  if (!DIL)
100  continue;
101  unsigned LineNo = DIL->getLine();
102  if (LineNo == 0)
103  continue;
104  unsigned Discriminator = DIL->getDiscriminator();
105  LocationDiscriminator LD{DIL->getFilename(), LineNo, Discriminator};
106  auto &BBMap = LDBM[LD];
107  auto R = BBMap.insert(&BB);
108  if (BBMap.size() == 1)
109  continue;
110 
111  unsigned DiscriminatorCurrPass;
112  DiscriminatorCurrPass = R.second ? ++LDCM[LD] : LDCM[LD];
113  DiscriminatorCurrPass = DiscriminatorCurrPass << LowBit;
114  DiscriminatorCurrPass += getCallStackHash(BB, I, DIL);
115  DiscriminatorCurrPass &= BitMaskThisPass;
116  unsigned NewD = Discriminator | DiscriminatorCurrPass;
117  const auto *const NewDIL = DIL->cloneWithDiscriminator(NewD);
118  if (!NewDIL) {
119  LLVM_DEBUG(dbgs() << "Could not encode discriminator: "
120  << DIL->getFilename() << ":" << DIL->getLine() << ":"
121  << DIL->getColumn() << ":" << Discriminator << " "
122  << I << "\n");
123  continue;
124  }
125 
126  I.setDebugLoc(NewDIL);
127  NumNewD++;
128  LLVM_DEBUG(dbgs() << DIL->getFilename() << ":" << DIL->getLine() << ":"
129  << DIL->getColumn() << ": add FS discriminator, from "
130  << Discriminator << " -> " << NewD << "\n");
131  Changed = true;
132  }
133  }
134 
135  if (Changed) {
136  createFSDiscriminatorVariable(MF.getFunction().getParent());
137  LLVM_DEBUG(dbgs() << "Num of FS Discriminators: " << NumNewD << "\n");
138  (void) NumNewD;
139  }
140 
141  return Changed;
142 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::MIRAddFSDiscriminators::ID
static char ID
Definition: MIRFSDiscriminator.h:38
DebugInfoMetadata.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::ARM_MB::LD
@ LD
Definition: ARMBaseInfo.h:72
llvm::EnableFSDiscriminator
cl::opt< bool > EnableFSDiscriminator
Definition: TargetPassConfig.cpp:391
llvm::DILocation
Debug location.
Definition: DebugInfoMetadata.h:1551
llvm::getN1Bits
static unsigned getN1Bits(int N)
Definition: Discriminator.h:123
DenseMap.h
llvm::DILocation::cloneWithDiscriminator
const DILocation * cloneWithDiscriminator(unsigned Discriminator) const
Returns a new DILocation with updated Discriminator.
Definition: DebugInfoMetadata.h:2185
llvm::MIRAddFSDiscriminatorsID
char & MIRAddFSDiscriminatorsID
This pass adds flow sensitive discriminators.
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
getCallStackHash
static uint64_t getCallStackHash(const MachineBasicBlock &BB, const MachineInstr &MI, const DILocation *DIL)
Definition: MIRFSDiscriminator.cpp:47
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:240
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::sampleprof::FSDiscriminatorPass
FSDiscriminatorPass
Definition: Discriminator.h:57
CommandLine.h
BlockFrequencyInfoImpl.h
INITIALIZE_PASS
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:37
DenseSet.h
llvm::sampleprofutil::createFSDiscriminatorVariable
void createFSDiscriminatorVariable(Module *M)
Create a global variable to flag FSDiscriminators are used.
Definition: SampleProfileLoaderBaseUtil.cpp:175
SampleProfileLoaderBaseUtil.h
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
Passes.h
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
uint64_t
llvm::Function::isDebugInfoForProfiling
bool isDebugInfoForProfiling() const
Returns true if we should emit debug info for profiling.
Definition: Metadata.cpp:1577
llvm::DenseMap
Definition: DenseMap.h:716
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::MachineFunction
Definition: MachineFunction.h:241
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:305
MIRFSDiscriminator.h
llvm::createMIRAddFSDiscriminatorsPass
FunctionPass * createMIRAddFSDiscriminatorsPass(sampleprof::FSDiscriminatorPass P)
Add Flow Sensitive Discriminators.
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:606
Function.h
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:86
DEBUG_TYPE
#define DEBUG_TYPE
Definition: MIRFSDiscriminator.cpp:31
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
raw_ostream.h
llvm::MIRAddFSDiscriminators
Definition: MIRFSDiscriminator.h:32
InitializePasses.h
Debug.h
llvm::MD5Hash
uint64_t MD5Hash(StringRef Str)
Helper to compute and return lower 64 bits of the given string's MD5 hash.
Definition: MD5.h:109