AddDiscriminators.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //===- AddDiscriminators.cpp - Insert DWARF path discriminators -----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file adds DWARF discriminators to the IR. Path discriminators are
  11. // used to decide what CFG path was taken inside sub-graphs whose instructions
  12. // share the same line and column number information.
  13. //
  14. // The main user of this is the sample profiler. Instruction samples are
  15. // mapped to line number information. Since a single line may be spread
  16. // out over several basic blocks, discriminators add more precise location
  17. // for the samples.
  18. //
  19. // For example,
  20. //
  21. // 1 #define ASSERT(P)
  22. // 2 if (!(P))
  23. // 3 abort()
  24. // ...
  25. // 100 while (true) {
  26. // 101 ASSERT (sum < 0);
  27. // 102 ...
  28. // 130 }
  29. //
  30. // when converted to IR, this snippet looks something like:
  31. //
  32. // while.body: ; preds = %entry, %if.end
  33. // %0 = load i32* %sum, align 4, !dbg !15
  34. // %cmp = icmp slt i32 %0, 0, !dbg !15
  35. // br i1 %cmp, label %if.end, label %if.then, !dbg !15
  36. //
  37. // if.then: ; preds = %while.body
  38. // call void @abort(), !dbg !15
  39. // br label %if.end, !dbg !15
  40. //
  41. // Notice that all the instructions in blocks 'while.body' and 'if.then'
  42. // have exactly the same debug information. When this program is sampled
  43. // at runtime, the profiler will assume that all these instructions are
  44. // equally frequent. This, in turn, will consider the edge while.body->if.then
  45. // to be frequently taken (which is incorrect).
  46. //
  47. // By adding a discriminator value to the instructions in block 'if.then',
  48. // we can distinguish instructions at line 101 with discriminator 0 from
  49. // the instructions at line 101 with discriminator 1.
  50. //
  51. // For more details about DWARF discriminators, please visit
  52. // http://wiki.dwarfstd.org/index.php?title=Path_Discriminators
  53. //===----------------------------------------------------------------------===//
  54. #include "llvm/Transforms/Scalar.h"
  55. #include "llvm/IR/BasicBlock.h"
  56. #include "llvm/IR/Constants.h"
  57. #include "llvm/IR/DIBuilder.h"
  58. #include "llvm/IR/DebugInfo.h"
  59. #include "llvm/IR/Instructions.h"
  60. #include "llvm/IR/LLVMContext.h"
  61. #include "llvm/IR/Module.h"
  62. #include "llvm/Pass.h"
  63. #include "llvm/Support/CommandLine.h"
  64. #include "llvm/Support/Debug.h"
  65. #include "llvm/Support/raw_ostream.h"
  66. using namespace llvm;
  67. #define DEBUG_TYPE "add-discriminators"
  68. namespace {
  69. struct AddDiscriminators : public FunctionPass {
  70. static char ID; // Pass identification, replacement for typeid
  71. AddDiscriminators() : FunctionPass(ID) {
  72. initializeAddDiscriminatorsPass(*PassRegistry::getPassRegistry());
  73. }
  74. bool runOnFunction(Function &F) override;
  75. // HLSL Change Starts
  76. bool NoDiscriminators = false;
  77. void applyOptions(PassOptions O) override {
  78. GetPassOptionBool(O, "no-discriminators", &NoDiscriminators, false);
  79. }
  80. void dumpConfig(raw_ostream &OS) override {
  81. FunctionPass::dumpConfig(OS);
  82. OS << ",no-discriminators=" << NoDiscriminators;
  83. }
  84. // HLSL Change Ends
  85. };
  86. }
  87. char AddDiscriminators::ID = 0;
  88. INITIALIZE_PASS_BEGIN(AddDiscriminators, "add-discriminators",
  89. "Add DWARF path discriminators", false, false)
  90. INITIALIZE_PASS_END(AddDiscriminators, "add-discriminators",
  91. "Add DWARF path discriminators", false, false)
  92. #ifdef HLSL_GLOBAL_OPT // HLSL Change Starts
  93. // Command line option to disable discriminator generation even in the
  94. // presence of debug information. This is only needed when debugging
  95. // debug info generation issues.
  96. static cl::opt<bool>
  97. NoDiscriminators("no-discriminators", cl::init(false),
  98. cl::desc("Disable generation of discriminator information."));
  99. #endif // HLSL_GLOBAL_OPT HLSL Change Ends
  100. FunctionPass *llvm::createAddDiscriminatorsPass() {
  101. return new AddDiscriminators();
  102. }
  103. static bool hasDebugInfo(const Function &F) {
  104. NamedMDNode *CUNodes = F.getParent()->getNamedMetadata("llvm.dbg.cu");
  105. return CUNodes != nullptr;
  106. }
  107. /// \brief Assign DWARF discriminators.
  108. ///
  109. /// To assign discriminators, we examine the boundaries of every
  110. /// basic block and its successors. Suppose there is a basic block B1
  111. /// with successor B2. The last instruction I1 in B1 and the first
  112. /// instruction I2 in B2 are located at the same file and line number.
  113. /// This situation is illustrated in the following code snippet:
  114. ///
  115. /// if (i < 10) x = i;
  116. ///
  117. /// entry:
  118. /// br i1 %cmp, label %if.then, label %if.end, !dbg !10
  119. /// if.then:
  120. /// %1 = load i32* %i.addr, align 4, !dbg !10
  121. /// store i32 %1, i32* %x, align 4, !dbg !10
  122. /// br label %if.end, !dbg !10
  123. /// if.end:
  124. /// ret void, !dbg !12
  125. ///
  126. /// Notice how the branch instruction in block 'entry' and all the
  127. /// instructions in block 'if.then' have the exact same debug location
  128. /// information (!dbg !10).
  129. ///
  130. /// To distinguish instructions in block 'entry' from instructions in
  131. /// block 'if.then', we generate a new lexical block for all the
  132. /// instruction in block 'if.then' that share the same file and line
  133. /// location with the last instruction of block 'entry'.
  134. ///
  135. /// This new lexical block will have the same location information as
  136. /// the previous one, but with a new DWARF discriminator value.
  137. ///
  138. /// One of the main uses of this discriminator value is in runtime
  139. /// sample profilers. It allows the profiler to distinguish instructions
  140. /// at location !dbg !10 that execute on different basic blocks. This is
  141. /// important because while the predicate 'if (x < 10)' may have been
  142. /// executed millions of times, the assignment 'x = i' may have only
  143. /// executed a handful of times (meaning that the entry->if.then edge is
  144. /// seldom taken).
  145. ///
  146. /// If we did not have discriminator information, the profiler would
  147. /// assign the same weight to both blocks 'entry' and 'if.then', which
  148. /// in turn will make it conclude that the entry->if.then edge is very
  149. /// hot.
  150. ///
  151. /// To decide where to create new discriminator values, this function
  152. /// traverses the CFG and examines instruction at basic block boundaries.
  153. /// If the last instruction I1 of a block B1 is at the same file and line
  154. /// location as instruction I2 of successor B2, then it creates a new
  155. /// lexical block for I2 and all the instruction in B2 that share the same
  156. /// file and line location as I2. This new lexical block will have a
  157. /// different discriminator number than I1.
  158. bool AddDiscriminators::runOnFunction(Function &F) {
  159. // If the function has debug information, but the user has disabled
  160. // discriminators, do nothing.
  161. // Simlarly, if the function has no debug info, do nothing.
  162. // Finally, if this module is built with dwarf versions earlier than 4,
  163. // do nothing (discriminator support is a DWARF 4 feature).
  164. if (NoDiscriminators ||
  165. !hasDebugInfo(F) ||
  166. F.getParent()->getDwarfVersion() < 4)
  167. return false;
  168. bool Changed = false;
  169. Module *M = F.getParent();
  170. LLVMContext &Ctx = M->getContext();
  171. DIBuilder Builder(*M, /*AllowUnresolved*/ false);
  172. // Traverse all the blocks looking for instructions in different
  173. // blocks that are at the same file:line location.
  174. for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
  175. BasicBlock *B = I;
  176. TerminatorInst *Last = B->getTerminator();
  177. const DILocation *LastDIL = Last->getDebugLoc();
  178. if (!LastDIL)
  179. continue;
  180. for (unsigned I = 0; I < Last->getNumSuccessors(); ++I) {
  181. BasicBlock *Succ = Last->getSuccessor(I);
  182. Instruction *First = Succ->getFirstNonPHIOrDbgOrLifetime();
  183. const DILocation *FirstDIL = First->getDebugLoc();
  184. if (!FirstDIL)
  185. continue;
  186. // If the first instruction (First) of Succ is at the same file
  187. // location as B's last instruction (Last), add a new
  188. // discriminator for First's location and all the instructions
  189. // in Succ that share the same location with First.
  190. if (!FirstDIL->canDiscriminate(*LastDIL)) {
  191. // Create a new lexical scope and compute a new discriminator
  192. // number for it.
  193. StringRef Filename = FirstDIL->getFilename();
  194. auto *Scope = FirstDIL->getScope();
  195. auto *File = Builder.createFile(Filename, Scope->getDirectory());
  196. // FIXME: Calculate the discriminator here, based on local information,
  197. // and delete DILocation::computeNewDiscriminator(). The current
  198. // solution gives different results depending on other modules in the
  199. // same context. All we really need is to discriminate between
  200. // FirstDIL and LastDIL -- a local map would suffice.
  201. unsigned Discriminator = FirstDIL->computeNewDiscriminator();
  202. auto *NewScope =
  203. Builder.createLexicalBlockFile(Scope, File, Discriminator);
  204. auto *NewDIL =
  205. DILocation::get(Ctx, FirstDIL->getLine(), FirstDIL->getColumn(),
  206. NewScope, FirstDIL->getInlinedAt());
  207. DebugLoc newDebugLoc = NewDIL;
  208. // Attach this new debug location to First and every
  209. // instruction following First that shares the same location.
  210. for (BasicBlock::iterator I1(*First), E1 = Succ->end(); I1 != E1;
  211. ++I1) {
  212. if (I1->getDebugLoc().get() != FirstDIL)
  213. break;
  214. I1->setDebugLoc(newDebugLoc);
  215. DEBUG(dbgs() << NewDIL->getFilename() << ":" << NewDIL->getLine()
  216. << ":" << NewDIL->getColumn() << ":"
  217. << NewDIL->getDiscriminator() << *I1 << "\n");
  218. }
  219. DEBUG(dbgs() << "\n");
  220. Changed = true;
  221. }
  222. }
  223. }
  224. return Changed;
  225. }