LLVM  14.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/IR/Function.h"
20 #include "llvm/Support/Debug.h"
23 #include <unordered_map>
24 
25 using namespace llvm;
26 using namespace sampleprof;
27 using namespace sampleprofutil;
28 
29 #define DEBUG_TYPE "mirfs-discriminators"
30 
32 
34  "Add MIR Flow Sensitive Discriminators",
35  /* cfg = */ false, /* is_analysis = */ false)
36 
38 
40  return new MIRAddFSDiscriminators(P);
41 }
42 
43 // Compute a hash value using debug line number, and the line numbers from the
44 // inline stack.
46  const MachineInstr &MI,
47  const DILocation *DIL) {
48  auto updateHash = [](const StringRef &Str) -> uint64_t {
49  if (Str.empty())
50  return 0;
51  return MD5Hash(Str);
52  };
53  uint64_t Ret = updateHash(std::to_string(DIL->getLine()));
54  Ret ^= updateHash(BB.getName());
55  Ret ^= updateHash(DIL->getScope()->getSubprogram()->getLinkageName());
56  for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
57  Ret ^= updateHash(std::to_string(DIL->getLine()));
58  Ret ^= updateHash(DIL->getScope()->getSubprogram()->getLinkageName());
59  }
60  return Ret;
61 }
62 
63 // Traverse the CFG and assign FD discriminators. If two instructions
64 // have the same lineno and discriminator, but residing in different BBs,
65 // the latter instruction will get a new discriminator value. The new
66 // discriminator keeps the existing discriminator value but sets new bits
67 // b/w LowBit and HighBit.
68 bool MIRAddFSDiscriminators::runOnMachineFunction(MachineFunction &MF) {
70  return false;
71 
72  bool Changed = false;
73  using LocationDiscriminator = std::tuple<StringRef, unsigned, unsigned>;
75  using LocationDiscriminatorBBMap = DenseMap<LocationDiscriminator, BBSet>;
76  using LocationDiscriminatorCurrPassMap =
78 
79  LocationDiscriminatorBBMap LDBM;
80  LocationDiscriminatorCurrPassMap LDCM;
81 
82  // Mask of discriminators before this pass.
83  unsigned BitMaskBefore = getN1Bits(LowBit);
84  // Mask of discriminators including this pass.
85  unsigned BitMaskNow = getN1Bits(HighBit);
86  // Mask of discriminators for bits specific to this pass.
87  unsigned BitMaskThisPass = BitMaskNow ^ BitMaskBefore;
88  unsigned NumNewD = 0;
89 
90  LLVM_DEBUG(dbgs() << "MIRAddFSDiscriminators working on Func: "
91  << MF.getFunction().getName() << "\n");
92  for (MachineBasicBlock &BB : MF) {
93  for (MachineInstr &I : BB) {
94  const DILocation *DIL = I.getDebugLoc().get();
95  if (!DIL)
96  continue;
97  unsigned LineNo = DIL->getLine();
98  if (LineNo == 0)
99  continue;
100  unsigned Discriminator = DIL->getDiscriminator();
101  LocationDiscriminator LD{DIL->getFilename(), LineNo, Discriminator};
102  auto &BBMap = LDBM[LD];
103  auto R = BBMap.insert(&BB);
104  if (BBMap.size() == 1)
105  continue;
106 
107  unsigned DiscriminatorCurrPass;
108  DiscriminatorCurrPass = R.second ? ++LDCM[LD] : LDCM[LD];
109  DiscriminatorCurrPass = DiscriminatorCurrPass << LowBit;
110  DiscriminatorCurrPass += getCallStackHash(BB, I, DIL);
111  DiscriminatorCurrPass &= BitMaskThisPass;
112  unsigned NewD = Discriminator | DiscriminatorCurrPass;
113  const auto *const NewDIL = DIL->cloneWithDiscriminator(NewD);
114  if (!NewDIL) {
115  LLVM_DEBUG(dbgs() << "Could not encode discriminator: "
116  << DIL->getFilename() << ":" << DIL->getLine() << ":"
117  << DIL->getColumn() << ":" << Discriminator << " "
118  << I << "\n");
119  continue;
120  }
121 
122  I.setDebugLoc(NewDIL);
123  NumNewD++;
124  LLVM_DEBUG(dbgs() << DIL->getFilename() << ":" << DIL->getLine() << ":"
125  << DIL->getColumn() << ": add FS discriminator, from "
126  << Discriminator << " -> " << NewD << "\n");
127  Changed = true;
128  }
129  }
130 
131  if (Changed) {
132  createFSDiscriminatorVariable(MF.getFunction().getParent());
133  LLVM_DEBUG(dbgs() << "Num of FS Discriminators: " << NumNewD << "\n");
134  }
135 
136  return Changed;
137 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::MIRAddFSDiscriminators::ID
static char ID
Definition: MIRFSDiscriminator.h:51
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:382
llvm::DILocation
Debug location.
Definition: DebugInfoMetadata.h:1580
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:2213
llvm::MIRAddFSDiscriminatorsID
char & MIRAddFSDiscriminatorsID
This pass adds flow sensitive discriminators.
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
getCallStackHash
static uint64_t getCallStackHash(const MachineBasicBlock &BB, const MachineInstr &MI, const DILocation *DIL)
Definition: MIRFSDiscriminator.cpp:45
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:198
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:163
SampleProfileLoaderBaseUtil.h
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
uint64_t
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::MachineFunction
Definition: MachineFunction.h:234
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:309
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:600
Function.h
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:63
DEBUG_TYPE
#define DEBUG_TYPE
Definition: MIRFSDiscriminator.cpp:29
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
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:45
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:122
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37