AddDiscriminators.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. };
  76. }
  77. char AddDiscriminators::ID = 0;
  78. INITIALIZE_PASS_BEGIN(AddDiscriminators, "add-discriminators",
  79. "Add DWARF path discriminators", false, false)
  80. INITIALIZE_PASS_END(AddDiscriminators, "add-discriminators",
  81. "Add DWARF path discriminators", false, false)
  82. // Command line option to disable discriminator generation even in the
  83. // presence of debug information. This is only needed when debugging
  84. // debug info generation issues.
  85. static cl::opt<bool>
  86. NoDiscriminators("no-discriminators", cl::init(false),
  87. cl::desc("Disable generation of discriminator information."));
  88. FunctionPass *llvm::createAddDiscriminatorsPass() {
  89. return new AddDiscriminators();
  90. }
  91. static bool hasDebugInfo(const Function &F) {
  92. NamedMDNode *CUNodes = F.getParent()->getNamedMetadata("llvm.dbg.cu");
  93. return CUNodes != nullptr;
  94. }
  95. /// \brief Assign DWARF discriminators.
  96. ///
  97. /// To assign discriminators, we examine the boundaries of every
  98. /// basic block and its successors. Suppose there is a basic block B1
  99. /// with successor B2. The last instruction I1 in B1 and the first
  100. /// instruction I2 in B2 are located at the same file and line number.
  101. /// This situation is illustrated in the following code snippet:
  102. ///
  103. /// if (i < 10) x = i;
  104. ///
  105. /// entry:
  106. /// br i1 %cmp, label %if.then, label %if.end, !dbg !10
  107. /// if.then:
  108. /// %1 = load i32* %i.addr, align 4, !dbg !10
  109. /// store i32 %1, i32* %x, align 4, !dbg !10
  110. /// br label %if.end, !dbg !10
  111. /// if.end:
  112. /// ret void, !dbg !12
  113. ///
  114. /// Notice how the branch instruction in block 'entry' and all the
  115. /// instructions in block 'if.then' have the exact same debug location
  116. /// information (!dbg !10).
  117. ///
  118. /// To distinguish instructions in block 'entry' from instructions in
  119. /// block 'if.then', we generate a new lexical block for all the
  120. /// instruction in block 'if.then' that share the same file and line
  121. /// location with the last instruction of block 'entry'.
  122. ///
  123. /// This new lexical block will have the same location information as
  124. /// the previous one, but with a new DWARF discriminator value.
  125. ///
  126. /// One of the main uses of this discriminator value is in runtime
  127. /// sample profilers. It allows the profiler to distinguish instructions
  128. /// at location !dbg !10 that execute on different basic blocks. This is
  129. /// important because while the predicate 'if (x < 10)' may have been
  130. /// executed millions of times, the assignment 'x = i' may have only
  131. /// executed a handful of times (meaning that the entry->if.then edge is
  132. /// seldom taken).
  133. ///
  134. /// If we did not have discriminator information, the profiler would
  135. /// assign the same weight to both blocks 'entry' and 'if.then', which
  136. /// in turn will make it conclude that the entry->if.then edge is very
  137. /// hot.
  138. ///
  139. /// To decide where to create new discriminator values, this function
  140. /// traverses the CFG and examines instruction at basic block boundaries.
  141. /// If the last instruction I1 of a block B1 is at the same file and line
  142. /// location as instruction I2 of successor B2, then it creates a new
  143. /// lexical block for I2 and all the instruction in B2 that share the same
  144. /// file and line location as I2. This new lexical block will have a
  145. /// different discriminator number than I1.
  146. bool AddDiscriminators::runOnFunction(Function &F) {
  147. // If the function has debug information, but the user has disabled
  148. // discriminators, do nothing.
  149. // Simlarly, if the function has no debug info, do nothing.
  150. // Finally, if this module is built with dwarf versions earlier than 4,
  151. // do nothing (discriminator support is a DWARF 4 feature).
  152. if (NoDiscriminators ||
  153. !hasDebugInfo(F) ||
  154. F.getParent()->getDwarfVersion() < 4)
  155. return false;
  156. bool Changed = false;
  157. Module *M = F.getParent();
  158. LLVMContext &Ctx = M->getContext();
  159. DIBuilder Builder(*M, /*AllowUnresolved*/ false);
  160. // Traverse all the blocks looking for instructions in different
  161. // blocks that are at the same file:line location.
  162. for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
  163. BasicBlock *B = I;
  164. TerminatorInst *Last = B->getTerminator();
  165. DebugLoc LastLoc = Last->getDebugLoc();
  166. if (LastLoc.isUnknown()) continue;
  167. DILocation LastDIL(LastLoc.getAsMDNode(Ctx));
  168. for (unsigned I = 0; I < Last->getNumSuccessors(); ++I) {
  169. BasicBlock *Succ = Last->getSuccessor(I);
  170. Instruction *First = Succ->getFirstNonPHIOrDbgOrLifetime();
  171. DebugLoc FirstLoc = First->getDebugLoc();
  172. if (FirstLoc.isUnknown()) continue;
  173. DILocation FirstDIL(FirstLoc.getAsMDNode(Ctx));
  174. // If the first instruction (First) of Succ is at the same file
  175. // location as B's last instruction (Last), add a new
  176. // discriminator for First's location and all the instructions
  177. // in Succ that share the same location with First.
  178. if (FirstDIL.atSameLineAs(LastDIL)) {
  179. // Create a new lexical scope and compute a new discriminator
  180. // number for it.
  181. StringRef Filename = FirstDIL.getFilename();
  182. DIScope Scope = FirstDIL.getScope();
  183. DIFile File = Builder.createFile(Filename, Scope.getDirectory());
  184. unsigned Discriminator = FirstDIL.computeNewDiscriminator(Ctx);
  185. DILexicalBlockFile NewScope =
  186. Builder.createLexicalBlockFile(Scope, File, Discriminator);
  187. DILocation NewDIL = FirstDIL.copyWithNewScope(Ctx, NewScope);
  188. DebugLoc newDebugLoc = DebugLoc::getFromDILocation(NewDIL);
  189. // Attach this new debug location to First and every
  190. // instruction following First that shares the same location.
  191. for (BasicBlock::iterator I1(*First), E1 = Succ->end(); I1 != E1;
  192. ++I1) {
  193. if (I1->getDebugLoc() != FirstLoc) break;
  194. I1->setDebugLoc(newDebugLoc);
  195. DEBUG(dbgs() << NewDIL.getFilename() << ":" << NewDIL.getLineNumber()
  196. << ":" << NewDIL.getColumnNumber() << ":"
  197. << NewDIL.getDiscriminator() << *I1 << "\n");
  198. }
  199. DEBUG(dbgs() << "\n");
  200. Changed = true;
  201. }
  202. }
  203. }
  204. return Changed;
  205. }