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

Robinson, Paul via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 28 16:03:39 PST 2017


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