llvm.org GIT mirror llvm / 976af3f
[CodeExtractor] Add debug locations for new call and branch instrs. Summary: If a partially inlined function has debug info, we have to add debug locations to the call instruction calling the outlined function. We use the debug location of the first instruction in the outlined function, as the introduced call transfers control to this statement and there is no other equivalent line in the source code. We also use the same debug location for the branch instruction added to jump from artificial entry block for the outlined function, which just jumps to the first actual basic block of the outlined function. Reviewers: davide, aprantl, rriddle, dblaikie, danielcdh, wmi Reviewed By: aprantl, rriddle, danielcdh Subscribers: eraman, JDevlieghere, llvm-commits Differential Revision: https://reviews.llvm.org/D40413 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320199 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 1 year, 9 months ago
2 changed file(s) with 128 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
745745 // Emit the call to the function
746746 CallInst *call = CallInst::Create(newFunction, params,
747747 NumExitBlocks > 1 ? "targetBlock" : "");
748 // Add debug location to the new call, if the original function has debug
749 // info. In that case, the terminator of the entry block of the extracted
750 // function contains the first debug location of the extracted function,
751 // set in extractCodeRegion.
752 if (codeReplacer->getParent()->getSubprogram()) {
753 if (auto DL = newFunction->getEntryBlock().getTerminator()->getDebugLoc())
754 call->setDebugLoc(DL);
755 }
748756 codeReplacer->getInstList().push_back(call);
749757
750758 Function::arg_iterator OutputArgBegin = newFunction->arg_begin();
10221030 // head of the region, but the entry node of a function cannot have preds.
10231031 BasicBlock *newFuncRoot = BasicBlock::Create(header->getContext(),
10241032 "newFuncRoot");
1025 newFuncRoot->getInstList().push_back(BranchInst::Create(header));
1033 auto *BranchI = BranchInst::Create(header);
1034 // If the original function has debug info, we have to add a debug location
1035 // to the new branch instruction from the artificial entry block.
1036 // We use the debug location of the first instruction in the extracted
1037 // blocks, as there is no other equivalent line in the source code.
1038 if (oldFunction->getSubprogram()) {
1039 any_of(Blocks, [&BranchI](const BasicBlock *BB) {
1040 return any_of(*BB, [&BranchI](const Instruction &I) {
1041 if (!I.getDebugLoc())
1042 return false;
1043 BranchI->setDebugLoc(I.getDebugLoc());
1044 return true;
1045 });
1046 });
1047 }
1048 newFuncRoot->getInstList().push_back(BranchI);
10261049
10271050 findAllocas(SinkingCands, HoistingCands, CommonExit);
10281051 assert(HoistingCands.empty() || CommonExit);
0 ; RUN: opt < %s -S -partial-inliner -skip-partial-inlining-cost-analysis=true | FileCheck %s
1
2 ; CHECK-LABEL: @callee
3 ; CHECK: %mul = mul nsw i32 %v, 10, !dbg ![[DBG1:[0-9]+]]
4 define i32 @callee(i32 %v) !dbg !16 {
5 entry:
6 %cmp = icmp sgt i32 %v, 2000
7 br i1 %cmp, label %if.then, label %if.end
8
9 if.then: ; preds = %entry
10 %mul = mul nsw i32 %v, 10, !dbg !17
11 br label %if.then2
12
13 if.then2:
14 %sub = sub i32 %v, 10, !dbg !23
15 br label %if.end
16
17 if.end: ; preds = %if.then, %entry
18 %v2 = phi i32 [ %v, %entry ], [ %mul, %if.then2 ]
19 %add = add nsw i32 %v2, 200
20 ret i32 %add
21 }
22
23 ; CHECK-LABEL: @caller
24 ; CHECK: codeRepl.i:
25 ; CHECK-NEXT: call void @callee.2_if.then(i32 %v, i32* %mul.loc.i), !dbg ![[DBG2:[0-9]+]]
26 define i32 @caller(i32 %v) !dbg !8 {
27 entry:
28 %call = call i32 @callee(i32 %v), !dbg !14
29 ret i32 %call
30 }
31
32
33 ; CHECK-LABEL: @callee2
34 ; CHECK: %sub = sub i32 %v, 10, !dbg ![[DBG3:[0-9]+]]
35 define i32 @callee2(i32 %v) !dbg !18 {
36 entry:
37 %cmp = icmp sgt i32 %v, 2000
38 br i1 %cmp, label %if.then, label %if.end
39
40 if.then:
41 br label %if.then2
42
43 if.then2:
44 %sub = sub i32 %v, 10, !dbg !20
45 br label %if.end
46
47 if.end:
48 %v2 = phi i32 [ %v, %entry ], [ %sub, %if.then2 ]
49 %add = add nsw i32 %v2, 200
50 ret i32 %add
51 }
52
53 ; CHECK-LABEL: @caller2
54 ; CHECK: codeRepl.i:
55 ; CHECK-NEXT: call void @callee2.1_if.then(i32 %v, i32* %sub.loc.i), !dbg ![[DBG4:[0-9]+]]
56 define i32 @caller2(i32 %v) !dbg !21 {
57 entry:
58 %call = call i32 @callee2(i32 %v), !dbg !22
59 ret i32 %call
60 }
61
62 ; CHECK-LABEL: define internal void @callee2.1_if.then
63 ; CHECK: br label %if.then, !dbg ![[DBG5:[0-9]+]]
64
65 ; CHECK-LABEL: define internal void @callee.2_if.then
66 ; CHECK: br label %if.then, !dbg ![[DBG6:[0-9]+]]
67
68 ; CHECK: ![[DBG1]] = !DILocation(line: 10, column: 7,
69 ; CHECK: ![[DBG2]] = !DILocation(line: 10, column: 7,
70 ; CHECK: ![[DBG3]] = !DILocation(line: 110, column: 17,
71 ; CHECK: ![[DBG4]] = !DILocation(line: 110, column: 17,
72 ; CHECK: ![[DBG5]] = !DILocation(line: 110, column: 17,
73 ; CHECK: ![[DBG6]] = !DILocation(line: 10, column: 7,
74
75
76 !llvm.dbg.cu = !{!0}
77 !llvm.module.flags = !{!3, !4, !5, !6}
78 !llvm.ident = !{!7}
79
80 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 (trunk 177881)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
81 !1 = !DIFile(filename: "test.c", directory: "/tmp")
82 !2 = !{}
83 !3 = !{i32 2, !"Dwarf Version", i32 4}
84 !4 = !{i32 2, !"Debug Info Version", i32 3}
85 !5 = !{i32 1, !"wchar_size", i32 4}
86 !6 = !{i32 1, !"min_enum_size", i32 4}
87 !7 = !{!"clang version 6.0.0"}
88 !8 = distinct !DISubprogram(name: "caller", scope: !1, file: !1, line: 3, type: !9, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
89 !9 = !DISubroutineType(types: !10)
90 !10 = !{!11, !11}
91 !11 = !DIBasicType(name: "int", size: 19, encoding: DW_ATE_signed)
92 !12 = !{!13}
93 !13 = !DILocalVariable(name: "v", arg: 1, scope: !8, file: !1, line: 3, type: !11)
94 !14 = !DILocation(line: 5, column: 10, scope: !8)
95 !15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 9, column: 7)
96 !16 = distinct !DISubprogram(name: "callee", scope: !1, file: !1, line: 8, type: !9, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
97 !17 = !DILocation(line: 10, column: 7, scope: !15)
98 !18 = distinct !DISubprogram(name: "callee2", scope: !1, file: !1, line: 8, type: !9, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
99 !19 = distinct !DILexicalBlock(scope: !18, file: !1, line: 100, column: 1)
100 !20 = !DILocation(line: 110, column: 17, scope: !19)
101 !21 = distinct !DISubprogram(name: "caller2", scope: !1, file: !1, line: 8, type: !9, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
102 !22 = !DILocation(line: 110, column: 17, scope: !21)
103 !23 = !DILocation(line: 15, column: 7, scope: !15)