mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
Reimplement discriminator assignment algorithm.
Summary: The new algorithm is more efficient (O(n), n is number of basic blocks). And it is guaranteed to cover all cases of multiple BB mapped to same line. Reviewers: dblaikie, davidxl, dnovillo Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D14738 llvm-svn: 253594
This commit is contained in:
parent
73a83d035c
commit
52b358f670
@ -52,7 +52,7 @@
|
||||
// http://wiki.dwarfstd.org/index.php?title=Path_Discriminators
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DIBuilder.h"
|
||||
@ -65,6 +65,7 @@
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -169,60 +170,44 @@ bool AddDiscriminators::runOnFunction(Function &F) {
|
||||
LLVMContext &Ctx = M->getContext();
|
||||
DIBuilder Builder(*M, /*AllowUnresolved*/ false);
|
||||
|
||||
// Traverse all the blocks looking for instructions in different
|
||||
// blocks that are at the same file:line location.
|
||||
typedef std::pair<StringRef, unsigned> Location;
|
||||
typedef DenseMap<const BasicBlock *, Metadata *> BBScopeMap;
|
||||
typedef DenseMap<Location, BBScopeMap> LocationBBMap;
|
||||
|
||||
LocationBBMap LBM;
|
||||
|
||||
// Traverse all instructions in the function. If the source line location
|
||||
// of the instruction appears in other basic block, assign a new
|
||||
// discriminator for this instruction.
|
||||
for (BasicBlock &B : F) {
|
||||
TerminatorInst *Last = B.getTerminator();
|
||||
const DILocation *LastDIL = Last->getDebugLoc();
|
||||
if (!LastDIL)
|
||||
continue;
|
||||
|
||||
for (unsigned I = 0; I < Last->getNumSuccessors(); ++I) {
|
||||
BasicBlock *Succ = Last->getSuccessor(I);
|
||||
Instruction *First = Succ->getFirstNonPHIOrDbgOrLifetime();
|
||||
const DILocation *FirstDIL = First->getDebugLoc();
|
||||
if (!FirstDIL || FirstDIL->getDiscriminator())
|
||||
for (auto &I : B.getInstList()) {
|
||||
if (isa<DbgInfoIntrinsic>(&I))
|
||||
continue;
|
||||
|
||||
// If the first instruction (First) of Succ is at the same file
|
||||
// location as B's last instruction (Last), add a new
|
||||
// discriminator for First's location and all the instructions
|
||||
// in Succ that share the same location with First.
|
||||
if (!FirstDIL->canDiscriminate(*LastDIL)) {
|
||||
// Create a new lexical scope and compute a new discriminator
|
||||
// number for it.
|
||||
StringRef Filename = FirstDIL->getFilename();
|
||||
auto *Scope = FirstDIL->getScope();
|
||||
auto *File = Builder.createFile(Filename, Scope->getDirectory());
|
||||
|
||||
// FIXME: Calculate the discriminator here, based on local information,
|
||||
// and delete DILocation::computeNewDiscriminator(). The current
|
||||
// solution gives different results depending on other modules in the
|
||||
// same context. All we really need is to discriminate between
|
||||
// FirstDIL and LastDIL -- a local map would suffice.
|
||||
unsigned Discriminator = FirstDIL->computeNewDiscriminator();
|
||||
auto *NewScope =
|
||||
Builder.createLexicalBlockFile(Scope, File, Discriminator);
|
||||
|
||||
// Attach this new debug location to First and every
|
||||
// instruction following First that shares the same location.
|
||||
for (BasicBlock::iterator I1(*First), E1 = Succ->end(); I1 != E1;
|
||||
++I1) {
|
||||
const DILocation *CurrentDIL = I1->getDebugLoc();
|
||||
if (CurrentDIL && CurrentDIL->getLine() == FirstDIL->getLine() &&
|
||||
CurrentDIL->getFilename() == FirstDIL->getFilename()) {
|
||||
I1->setDebugLoc(DILocation::get(Ctx, CurrentDIL->getLine(),
|
||||
CurrentDIL->getColumn(), NewScope,
|
||||
CurrentDIL->getInlinedAt()));
|
||||
DEBUG(dbgs() << CurrentDIL->getFilename() << ":"
|
||||
<< CurrentDIL->getLine() << ":"
|
||||
<< CurrentDIL->getColumn() << ":"
|
||||
<< CurrentDIL->getDiscriminator() << *I1 << "\n");
|
||||
}
|
||||
}
|
||||
DEBUG(dbgs() << "\n");
|
||||
Changed = true;
|
||||
const DILocation *DIL = I.getDebugLoc();
|
||||
if (!DIL)
|
||||
continue;
|
||||
Location L = std::make_pair(DIL->getFilename(), DIL->getLine());
|
||||
auto &BBMap = LBM[L];
|
||||
auto R = BBMap.insert(std::make_pair(&B, (Metadata *)nullptr));
|
||||
if (BBMap.size() == 1)
|
||||
continue;
|
||||
bool InsertSuccess = R.second;
|
||||
Metadata *&NewScope = R.first->second;
|
||||
// If we could insert a different block in the same location, a
|
||||
// discriminator is needed to distinguish both instructions.
|
||||
if (InsertSuccess) {
|
||||
auto *Scope = DIL->getScope();
|
||||
auto *File =
|
||||
Builder.createFile(DIL->getFilename(), Scope->getDirectory());
|
||||
NewScope = Builder.createLexicalBlockFile(
|
||||
Scope, File, DIL->computeNewDiscriminator());
|
||||
}
|
||||
I.setDebugLoc(DILocation::get(Ctx, DIL->getLine(), DIL->getColumn(),
|
||||
NewScope, DIL->getInlinedAt()));
|
||||
DEBUG(dbgs() << DIL->getFilename() << ":" << DIL->getLine() << ":"
|
||||
<< DIL->getColumn() << ":" << NewScope->getDiscriminator()
|
||||
<< I << "\n");
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
72
test/Transforms/AddDiscriminators/diamond.ll
Normal file
72
test/Transforms/AddDiscriminators/diamond.ll
Normal file
@ -0,0 +1,72 @@
|
||||
; RUN: opt < %s -add-discriminators -S | FileCheck %s
|
||||
|
||||
; Discriminator support for diamond-shaped CFG.:
|
||||
; #1 void bar(int);
|
||||
; #2
|
||||
; #3 void foo(int i) {
|
||||
; #4 if (i > 10)
|
||||
; #5 bar(5); else bar(3);
|
||||
; #6 }
|
||||
|
||||
; bar(5): discriminator 0
|
||||
; bar(3): discriminator 1
|
||||
|
||||
; Function Attrs: uwtable
|
||||
define void @_Z3fooi(i32 %i) #0 !dbg !4 {
|
||||
%1 = alloca i32, align 4
|
||||
store i32 %i, i32* %1, align 4
|
||||
call void @llvm.dbg.declare(metadata i32* %1, metadata !11, metadata !12), !dbg !13
|
||||
%2 = load i32, i32* %1, align 4, !dbg !14
|
||||
%3 = icmp sgt i32 %2, 10, !dbg !16
|
||||
br i1 %3, label %4, label %5, !dbg !17
|
||||
|
||||
; <label>:4 ; preds = %0
|
||||
call void @_Z3bari(i32 5), !dbg !18
|
||||
br label %6, !dbg !18
|
||||
|
||||
; <label>:5 ; preds = %0
|
||||
call void @_Z3bari(i32 3), !dbg !19
|
||||
; CHECK: call void @_Z3bari(i32 3), !dbg ![[ELSE:[0-9]+]]
|
||||
br label %6
|
||||
|
||||
; <label>:6 ; preds = %5, %4
|
||||
ret void, !dbg !20
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
|
||||
|
||||
declare void @_Z3bari(i32) #2
|
||||
|
||||
attributes #0 = { uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { nounwind readnone }
|
||||
attributes #2 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!8, !9}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 253273)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)
|
||||
!1 = !DIFile(filename: "a.cc", directory: "/tmp")
|
||||
!2 = !{}
|
||||
!3 = !{!4}
|
||||
!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, variables: !2)
|
||||
!5 = !DISubroutineType(types: !6)
|
||||
!6 = !{null, !7}
|
||||
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!8 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!9 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!10 = !{!"clang version 3.8.0 (trunk 253273)"}
|
||||
!11 = !DILocalVariable(name: "i", arg: 1, scope: !4, file: !1, line: 3, type: !7)
|
||||
!12 = !DIExpression()
|
||||
!13 = !DILocation(line: 3, column: 14, scope: !4)
|
||||
!14 = !DILocation(line: 4, column: 7, scope: !15)
|
||||
!15 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 7)
|
||||
!16 = !DILocation(line: 4, column: 9, scope: !15)
|
||||
!17 = !DILocation(line: 4, column: 7, scope: !4)
|
||||
!18 = !DILocation(line: 5, column: 5, scope: !15)
|
||||
!19 = !DILocation(line: 5, column: 18, scope: !15)
|
||||
!20 = !DILocation(line: 6, column: 1, scope: !4)
|
||||
|
||||
; CHECK: ![[ELSE]] = !DILocation(line: 5, column: 18, scope: ![[ELSEBLOCK:[0-9]+]])
|
||||
; CHECK: ![[ELSEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 1)
|
@ -6,8 +6,8 @@
|
||||
; #3 }
|
||||
|
||||
; i == 3: discriminator 0
|
||||
; i == 5: discriminator 2
|
||||
; return 100: discriminator 1
|
||||
; i == 5: discriminator 1
|
||||
; return 100: discriminator 2
|
||||
; return 99: discriminator 3
|
||||
|
||||
define i32 @_Z3fooi(i32 %i) #0 !dbg !4 {
|
||||
@ -93,10 +93,10 @@ attributes #1 = { nounwind readnone }
|
||||
!28 = !DILocation(line: 3, column: 1, scope: !4)
|
||||
|
||||
; CHECK: ![[THEN1]] = !DILocation(line: 2, column: 17, scope: ![[THENBLOCK:[0-9]+]])
|
||||
; CHECK: ![[THENBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 2)
|
||||
; CHECK: ![[THENBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 1)
|
||||
; CHECK: ![[THEN2]] = !DILocation(line: 2, column: 19, scope: ![[THENBLOCK]])
|
||||
; CHECK: ![[THEN3]] = !DILocation(line: 2, column: 7, scope: ![[THENBLOCK]])
|
||||
; CHECK: ![[ELSE]] = !DILocation(line: 2, column: 25, scope: ![[ELSEBLOCK:[0-9]+]])
|
||||
; CHECK: ![[ELSEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 1)
|
||||
; CHECK: ![[ELSEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 2)
|
||||
; CHECK: ![[COMBINE]] = !DILocation(line: 2, column: 42, scope: ![[COMBINEBLOCK:[0-9]+]])
|
||||
; CHECK: ![[COMBINEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 3)
|
||||
|
Loading…
Reference in New Issue
Block a user