[llvm] r296488 - Strip debug info when inlining into a nodebug function.

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 2 10:19:10 PST 2017


Done in r296776.

thanks,
adrian


> On Feb 28, 2017, at 4:03 PM, Robinson, Paul <paul.robinson at sony.com> wrote:
> 
> I wonder if this should be documented somehow?  The only good place that
> comes to mind would be the 'nodebug' attribute documentation in Clang.
> --paulr
> 
>> -----Original Message-----
>> From: llvm-commits [mailto:llvm-commits-bounces at lists.llvm.org] On Behalf
>> Of Adrian Prantl via llvm-commits
>> Sent: Tuesday, February 28, 2017 8:58 AM
>> To: llvm-commits at lists.llvm.org
>> Subject: [llvm] r296488 - Strip debug info when inlining into a nodebug
>> function.
>> 
>> Author: adrian
>> Date: Tue Feb 28 10:58:13 2017
>> New Revision: 296488
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=296488&view=rev
>> Log:
>> Strip debug info when inlining into a nodebug function.
>> 
>> The LLVM backend cannot produce any debug info for an llvm::Function
>> without a DISubprogram attachment. When inlining a debug-info-carrying
>> function into a nodebug function, there is therefore no reason to keep
>> any debug info intrinsic calls or debug locations on the instructions.
>> 
>> This fixes a problem discovered in PR32042.
>> 
>> rdar://problem/30679307
>> 
>> Added:
>>    llvm/trunk/test/Transforms/Inline/nodebug.ll
>> Modified:
>>    llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
>>    llvm/trunk/test/Transforms/Inline/local-as-metadata-undominated-use.ll
>> 
>> Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=296488&r1=2
>> 96487&r2=296488&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Tue Feb 28 10:58:13
>> 2017
>> @@ -1343,22 +1343,26 @@ static bool allocaWouldBeStaticInEntry(c
>>   return isa<Constant>(AI->getArraySize()) && !AI->isUsedWithInAlloca();
>> }
>> 
>> -/// Update inlined instructions' line numbers to
>> -/// to encode location where these instructions are inlined.
>> -static void fixupLineNumbers(Function *Fn, Function::iterator FI,
>> -                             Instruction *TheCall, bool
>> CalleeHasDebugInfo) {
>> +/// Update inlined instructions' line numbers to to encode location where
>> these
>> +/// instructions are inlined.  Also strip all debug intrinsics that were
>> inlined
>> +/// into a nodebug function; there is no debug info the backend could
>> produce
>> +/// for a function without a DISubprogram attachment.
>> +static void fixupDebugInfo(Function *Fn, Function::iterator FI,
>> +                           Instruction *TheCall, bool CalleeHasDebugInfo)
>> {
>> +  bool CallerHasDebugInfo = Fn->getSubprogram();
>> +  bool StripDebugInfo = !CallerHasDebugInfo && CalleeHasDebugInfo;
>> +  SmallVector<DbgInfoIntrinsic *, 8> IntrinsicsToErase;
>>   const DebugLoc &TheCallDL = TheCall->getDebugLoc();
>> -  if (!TheCallDL)
>> -    return;
>> 
>>   auto &Ctx = Fn->getContext();
>> -  DILocation *InlinedAtNode = TheCallDL;
>> +  DILocation *InlinedAtNode = nullptr;
>> 
>>   // Create a unique call site, not to be confused with any other call
>> from the
>>   // same location.
>> -  InlinedAtNode = DILocation::getDistinct(
>> -      Ctx, InlinedAtNode->getLine(), InlinedAtNode->getColumn(),
>> -      InlinedAtNode->getScope(), InlinedAtNode->getInlinedAt());
>> +  if (TheCallDL)
>> +    InlinedAtNode = DILocation::getDistinct(
>> +        Ctx, TheCallDL->getLine(), TheCallDL->getColumn(),
>> +        TheCallDL->getScope(), TheCallDL->getInlinedAt());
>> 
>>   // Cache the inlined-at nodes as they're built so they are reused,
>> without
>>   // this every instruction's inlined-at chain would become distinct from
>> each
>> @@ -1368,6 +1372,17 @@ static void fixupLineNumbers(Function *F
>>   for (; FI != Fn->end(); ++FI) {
>>     for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
>>          BI != BE; ++BI) {
>> +      if (StripDebugInfo) {
>> +        // Inlining into a nodebug function.
>> +        if (auto *DI = dyn_cast<DbgInfoIntrinsic>(BI))
>> +          // Mark dead debug intrinsics for deletion.
>> +          IntrinsicsToErase.push_back(DI);
>> +        else
>> +          // Remove the dangling debug location.
>> +          BI->setDebugLoc(DebugLoc());
>> +        continue;
>> +      }
>> +
>>       if (DebugLoc DL = BI->getDebugLoc()) {
>>         BI->setDebugLoc(
>>             updateInlinedAtInfo(DL, InlinedAtNode, BI->getContext(),
>> IANodes));
>> @@ -1390,6 +1405,9 @@ static void fixupLineNumbers(Function *F
>>       BI->setDebugLoc(TheCallDL);
>>     }
>>   }
>> +
>> +  for (auto *DI : IntrinsicsToErase)
>> +    DI->eraseFromParent();
>> }
>> /// Update the block frequencies of the caller after a callee has been
>> inlined.
>> ///
>> @@ -1710,8 +1728,8 @@ bool llvm::InlineFunction(CallSite CS, I
>>     // For 'nodebug' functions, the associated DISubprogram is always
>> null.
>>     // Conservatively avoid propagating the callsite debug location to
>>     // instructions inlined from a function whose DISubprogram is not
>> null.
>> -    fixupLineNumbers(Caller, FirstNewBlock, TheCall,
>> -                     CalledFunc->getSubprogram() != nullptr);
>> +    fixupDebugInfo(Caller, FirstNewBlock, TheCall,
>> +                   CalledFunc->getSubprogram() != nullptr);
>> 
>>     // Clone existing noalias metadata if necessary.
>>     CloneAliasScopeMetadata(CS, VMap);
>> 
>> Modified: llvm/trunk/test/Transforms/Inline/local-as-metadata-undominated-
>> use.ll
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/test/Transforms/Inline/local-as-metadata-undominated-
>> use.ll?rev=296488&r1=296487&r2=296488&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/test/Transforms/Inline/local-as-metadata-undominated-use.ll
>> (original)
>> +++ llvm/trunk/test/Transforms/Inline/local-as-metadata-undominated-use.ll
>> Tue Feb 28 10:58:13 2017
>> @@ -16,14 +16,14 @@ entry:
>> }
>> 
>> ; CHECK-LABEL: define i32 @caller(
>> -define i32 @caller(i32 %i) {
>> +define i32 @caller(i32 %i) !dbg !3 {
>> ; CHECK-NEXT: entry:
>> entry:
>> ; Although the inliner shouldn't crash, it can't be expected to get the
>> ; "correct" SSA value since its assumptions have been violated.
>> ; CHECK-NEXT:   tail call void @llvm.dbg.value(metadata ![[EMPTY:[0-
>> 9]+]],
>> ; CHECK-NEXT:   %{{.*}} = add nsw
>> -  %call = tail call i32 @foo(i32 %i)
>> +  %call = tail call i32 @foo(i32 %i), !dbg !14
>>   ret i32 %call
>> }
>> 
>> @@ -34,9 +34,9 @@ declare void @llvm.dbg.value(metadata, i
>> 
>> !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer:
>> "clang version 3.9.0 (trunk 265634) (llvm/trunk 265637)", isOptimized:
>> true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
>> !1 = !DIFile(filename: "t.c", directory: "/path/to/tests")
>> -
>> ; CHECK: ![[EMPTY]] = !{}
>> !2 = !{}
>> +!3 = distinct !DISubprogram(name: "caller", scope: !1, file: !1, line: 3,
>> type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags:
>> DIFlagPrototyped, isOptimized: true, unit: !0)
>> !4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 2,
>> type: !5, isLocal: false, isDefinition: true, scopeLine: 2, flags:
>> DIFlagPrototyped, isOptimized: true, unit: !0)
>> !5 = !DISubroutineType(types: !6)
>> !6 = !{!7, !7}
>> @@ -47,3 +47,4 @@ declare void @llvm.dbg.value(metadata, i
>> !11 = !DILocation(line: 2, column: 13, scope: !4)
>> !12 = !DILocation(line: 2, column: 27, scope: !4)
>> !13 = !DILocation(line: 2, column: 18, scope: !4)
>> +!14 = !DILocation(line: 3, scope: !3)
>> 
>> Added: llvm/trunk/test/Transforms/Inline/nodebug.ll
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/test/Transforms/Inline/nodebug.ll?rev=296488&view=auto
>> ==========================================================================
>> ====
>> --- llvm/trunk/test/Transforms/Inline/nodebug.ll (added)
>> +++ llvm/trunk/test/Transforms/Inline/nodebug.ll Tue Feb 28 10:58:13 2017
>> @@ -0,0 +1,36 @@
>> +; RUN: opt -inline -S -o - < %s | FileCheck %s
>> +; Check that debug info is stripped when inlining into a nodebug
>> function.
>> +
>> +declare void @llvm.dbg.declare(metadata, metadata, metadata)
>> +declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
>> +
>> +define void @foo() !dbg !2 {
>> +entry:
>> +  %a = alloca i32
>> +  call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !3, metadata
>> !DIExpression()), !dbg !6
>> +  store i32 0, i32* %a, !dbg !6
>> +  ret void, !dbg !6
>> +}
>> +
>> +; CHECK: define void @bar()
>> +define void @bar() {
>> +; CHECK-NEXT: entry
>> +entry:
>> +; CHECK-NEXT: alloca i32
>> +; CHECK-NOT: dbg
>> +; CHECK: ret void
>> +  call void @foo()
>> +  ret void
>> +}
>> +
>> +!llvm.dbg.cu = !{!0}
>> +!llvm.module.flags = !{!7, !8}
>> +
>> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer:
>> "clang", emissionKind: FullDebug)
>> +!1 = !DIFile(filename: "x.c", directory: "/")
>> +!2 = distinct !DISubprogram(name: "foo", scope: !0, isDefinition: true,
>> unit: !0)
>> +!3 = !DILocalVariable(name: "a", arg: 1, scope: !2, file: !1, line: 1,
>> type: !5)
>> +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
>> +!6 = !DILocation(line: 1, scope: !2)
>> +!7 = !{i32 2, !"Dwarf Version", i32 4}
>> +!8 = !{i32 1, !"Debug Info Version", i32 3}
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list