[clang] 170ac4b - [CSInfo][ISEL] Call site info generation support for Mips

Djordje Todorovic via cfe-commits cfe-commits at lists.llvm.org
Fri May 15 01:13:35 PDT 2020


Author: Djordje Todorovic
Date: 2020-05-15T10:13:15+02:00
New Revision: 170ac4be3392201d5f5e124e8a1b7d78de3f82c8

URL: https://github.com/llvm/llvm-project/commit/170ac4be3392201d5f5e124e8a1b7d78de3f82c8
DIFF: https://github.com/llvm/llvm-project/commit/170ac4be3392201d5f5e124e8a1b7d78de3f82c8.diff

LOG: [CSInfo][ISEL] Call site info generation support for Mips

Debug entry values functionality provides debug information about
call sites and function parameters values at the call entry spot.
Condition for generating this type of information is
compiling with -g option and optimization level higher
than zero(-O0).

In ISEL phase, while lowering call instructions, collect info
about registers that forward arguments into following
function frame. We store such info into MachineFunction of
the caller function. This is used very late, when dumping DWARF
info about call site parameters.

The call site info is visible at MIR level, as callSites attribute
of MachineFunction. Also, when using unmodified parameter value
inside callee it could be described as DW_OP_entry_value expression.
To deal with callSites attribute, we should pass
-emit-call-site-info option to llc.

This patch enables functionality in clang frontend and adds
call site info generation support for MIPS targets
(mips, mipsel, mips64, mips64el).

Patch by Nikola Tesic

Differential Revision: https://reviews.llvm.org/D78105

Added: 
    llvm/test/CodeGen/Mips/call-site-info-output.ll
    llvm/test/CodeGen/Mips/dbg-call-site-info-reg-d-split.ll
    llvm/test/DebugInfo/Mips/dw_op_entry_value_32bit.ll
    llvm/test/DebugInfo/Mips/dw_op_entry_value_64bit.ll

Modified: 
    clang/lib/Frontend/CompilerInvocation.cpp
    llvm/lib/Target/Mips/MipsISelLowering.cpp
    llvm/lib/Target/Mips/MipsTargetMachine.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 7e4bb6ea97e3..2ce71a96c35f 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -783,7 +783,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
 
   const llvm::Triple::ArchType DebugEntryValueArchs[] = {
       llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64,
-      llvm::Triple::arm, llvm::Triple::armeb};
+      llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips,
+      llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el};
 
   llvm::Triple T(TargetOpts.Triple);
   if (Opts.OptimizationLevel > 0 && Opts.hasReducedDebugInfo() &&

diff  --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index f0b88cd63f4b..3018d8d77c19 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3217,6 +3217,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
   // Get a count of how many bytes are to be pushed on the stack.
   unsigned NextStackOffset = CCInfo.getNextStackOffset();
 
+  // Call site info for function parameters tracking.
+  MachineFunction::CallSiteInfo CSInfo;
+
   // Check if it's really possible to do a tail call. Restrict it to functions
   // that are part of this compilation unit.
   bool InternalLinkage = false;
@@ -3343,6 +3346,17 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
     // RegsToPass vector
     if (VA.isRegLoc()) {
       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
+
+      // If the parameter is passed through reg $D, which splits into
+      // two physical registers, avoid creating call site info.
+      if (Mips::AFGR64RegClass.contains(VA.getLocReg()))
+        continue;
+
+      // Collect CSInfo about which register passes which parameter.
+      const TargetOptions &Options = DAG.getTarget().Options;
+      if (Options.SupportsDebugEntryValues)
+        CSInfo.emplace_back(VA.getLocReg(), i);
+
       continue;
     }
 
@@ -3447,12 +3461,16 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
 
   if (IsTailCall) {
     MF.getFrameInfo().setHasTailCall();
-    return DAG.getNode(MipsISD::TailCall, DL, MVT::Other, Ops);
+    SDValue Ret = DAG.getNode(MipsISD::TailCall, DL, MVT::Other, Ops);
+    DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
+    return Ret;
   }
 
   Chain = DAG.getNode(MipsISD::JmpLink, DL, NodeTys, Ops);
   SDValue InFlag = Chain.getValue(1);
 
+  DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
+
   // Create the CALLSEQ_END node in the case of where it is not a call to
   // memcpy.
   if (!(MemcpyInByVal)) {

diff  --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
index 8fec6db00cb9..80cb6ce7ac0c 100644
--- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -131,6 +131,9 @@ MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT,
                       MaybeAlign(Options.StackAlignmentOverride)) {
   Subtarget = &DefaultSubtarget;
   initAsmInfo();
+
+  // Mips supports the debug entry values.
+  setSupportsDebugEntryValues(true);
 }
 
 MipsTargetMachine::~MipsTargetMachine() = default;

diff  --git a/llvm/test/CodeGen/Mips/call-site-info-output.ll b/llvm/test/CodeGen/Mips/call-site-info-output.ll
new file mode 100644
index 000000000000..c87087cbc097
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/call-site-info-output.ll
@@ -0,0 +1,65 @@
+;; Test mips32:
+; RUN: llc -mtriple=mips-linux-gnu -emit-call-site-info %s -stop-before=finalize-isel -o -| \
+; RUN: llc -mtriple=mips-linux-gnu -emit-call-site-info -x='mir' -run-pass=finalize-isel -o -| FileCheck %s
+;; Test mips64:
+; RUN: llc -mtriple=mips64-linux-gnu -emit-call-site-info %s -stop-before=finalize-isel -o -| \
+; RUN: llc -mtriple=mips64-linux-gnu -emit-call-site-info -x='mir' -run-pass=finalize-isel -o -| FileCheck %s --check-prefix=CHECK64
+;; Test mipsel:
+; RUN: llc -mtriple=mipsel-linux-gnu -emit-call-site-info %s -stop-before=finalize-isel -o -| \
+; RUN: llc -mtriple=mipsel-linux-gnu -emit-call-site-info -x='mir' -run-pass=finalize-isel -o -| FileCheck %s
+;; Test mips64el:
+; RUN: llc -mtriple=mips64el-linux-gnu -emit-call-site-info %s -stop-before=finalize-isel -o -| \
+; RUN: llc -mtriple=mips64el-linux-gnu -emit-call-site-info -x='mir' -run-pass=finalize-isel -o -| FileCheck %s --check-prefix=CHECK64
+
+;; Test call site info MIR parser and printer. Parser assertions and machine
+;; verifier will check the rest.
+;; There is no need to verify call instruction location since it will be
+;; checked by the MIR parser.
+;; Verify that we are able to parse output mir and that we are getting valid call site info.
+
+;; Source:
+;; extern int fn1(int,int,int);
+;; int fn2(int a, int b, int c) {
+;;   int local = fn1(a+b, c, 10);
+;;   if (local > 10)
+;;     return local + 10;
+;;   return local;
+;; }
+
+;; Test mips32 and mips32el:
+; CHECK: name: fn2
+; CHECK: callSites:
+; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; CHECK-NEXT:   arg: 0, reg: '$a0'
+; CHECK-NEXT:   arg: 1, reg: '$a1'
+; CHECK-NEXT:   arg: 2, reg: '$a2'
+
+;; Test mips64 and mips64el:
+; CHECK64: name: fn2
+; CHECK64: callSites:
+; CHECK64-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; CHECK64-NEXT:   arg: 0, reg: '$a0_64'
+; CHECK64-NEXT:   arg: 1, reg: '$a1_64'
+; CHECK64-NEXT:   arg: 2, reg: '$a2_64'
+
+; ModuleID = 'test/CodeGen/Mips/call-site-info-output.c'
+source_filename = "test/CodeGen/Mips/call-site-info-output.c"
+target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
+target triple = "mips-unknown-linux-gnu"
+; Function Attrs: nounwind
+define dso_local i32 @fn2(i32 signext %a, i32 signext %b, i32 signext %c) local_unnamed_addr {
+entry:
+  %add = add nsw i32 %b, %a
+  %call = tail call i32 @fn1(i32 signext %add, i32 signext %c, i32 signext 10)
+  %cmp = icmp sgt i32 %call, 10
+  %add1 = add nsw i32 %call, 10
+  %retval.0 = select i1 %cmp, i32 %add1, i32 %call
+  ret i32 %retval.0
+}
+declare dso_local i32 @fn1(i32 signext, i32 signext, i32 signext) local_unnamed_addr
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!"clang version 11.0.0"}

diff  --git a/llvm/test/CodeGen/Mips/dbg-call-site-info-reg-d-split.ll b/llvm/test/CodeGen/Mips/dbg-call-site-info-reg-d-split.ll
new file mode 100644
index 000000000000..5878b040bada
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/dbg-call-site-info-reg-d-split.ll
@@ -0,0 +1,68 @@
+;; Test mips:
+; RUN: llc -mtriple=mips-linux-gnu -emit-call-site-info %s -stop-after=finalize-isel -o -| FileCheck %s
+;; Test mipsel:
+; RUN: llc -mtriple=mipsel-linux-gnu -emit-call-site-info %s -stop-after=finalize-isel -o -| FileCheck %s
+
+;; Verify that call site info is not emitted for parameter passed through 64-bit register $d
+;; which splits into two 32-bit physical regs.
+;; Source:
+;; extern double bar(double,int);
+;; double foo(double self){
+;;   int b = 1;
+;;   double a = bar(self,b);
+;;   return a;
+;; }
+
+;; Test mips and mipsel:
+; CHECK: name:            foo
+; CHECK: callSites:
+; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; CHECK-NOT:   arg: 0, reg: '$a0'
+; CHECK-NOT:   arg: 0, reg: '$d6'
+; CHECK-NEXT:   arg: 1, reg: '$a2'
+
+; ModuleID = 'm.c'
+source_filename = "m.c"
+target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
+target triple = "mips-unknown-linux-gnu"
+
+; Function Attrs: nounwind
+define dso_local double @foo(double %self) local_unnamed_addr !dbg !13 {
+entry:
+  call void @llvm.dbg.value(metadata double %self, metadata !17, metadata !DIExpression()), !dbg !20
+  call void @llvm.dbg.value(metadata i32 1, metadata !18, metadata !DIExpression()), !dbg !20
+  %call = tail call double @bar(double %self, i32 signext 1), !dbg !20
+  call void @llvm.dbg.value(metadata double %call, metadata !19, metadata !DIExpression()), !dbg !20
+  ret double %call, !dbg !20
+}
+
+declare !dbg !4 dso_local double @bar(double, i32 signext) local_unnamed_addr
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!9, !10, !11}
+!llvm.ident = !{!12}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "m.c", directory: "/dir")
+!2 = !{}
+!3 = !{!4}
+!4 = !DISubprogram(name: "bar", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
+!5 = !DISubroutineType(types: !6)
+!6 = !{!7, !7, !8}
+!7 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
+!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!9 = !{i32 7, !"Dwarf Version", i32 4}
+!10 = !{i32 2, !"Debug Info Version", i32 3}
+!11 = !{i32 1, !"wchar_size", i32 4}
+!12 = !{!"clang version 11.0.0"}
+!13 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !14, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16)
+!14 = !DISubroutineType(types: !15)
+!15 = !{!7, !7}
+!16 = !{!17, !18, !19}
+!17 = !DILocalVariable(name: "self", arg: 1, scope: !13, file: !1, line: 3, type: !7)
+!18 = !DILocalVariable(name: "b", scope: !13, file: !1, line: 4, type: !8)
+!19 = !DILocalVariable(name: "a", scope: !13, file: !1, line: 5, type: !7)
+!20 = !DILocation(line: 0, scope: !13)

diff  --git a/llvm/test/DebugInfo/Mips/dw_op_entry_value_32bit.ll b/llvm/test/DebugInfo/Mips/dw_op_entry_value_32bit.ll
new file mode 100644
index 000000000000..cab1b6e4aa89
--- /dev/null
+++ b/llvm/test/DebugInfo/Mips/dw_op_entry_value_32bit.ll
@@ -0,0 +1,76 @@
+;; Test mips32:
+; RUN: llc -emit-call-site-info -stop-after=livedebugvalues -mtriple=mips-linux-gnu -o - %s | FileCheck %s
+;; Test mipsel:
+; RUN: llc -emit-call-site-info -stop-after=livedebugvalues -mtriple=mipsel-linux-gnu -o - %s | FileCheck %s --check-prefix=CHECKel
+
+;; Built from source:
+;; extern long fn1(long,long,long);
+;; long fn2(long a, long b, long c) {
+;;   long local = fn1(a+b, c, b+10);
+;;   if (local > 10)
+;;     return local + 10;
+;;   return b;
+;; }
+;; Using command:
+;; clang -g -O2 -target mips-linux-gnu  m.c -c -S -emit-llvm
+;; Confirm that info from callSites attribute is used as entry_value in DIExpression.
+
+;; Test mips32:
+; CHECK: $a0 = nsw ADDu $a1, killed renamable $a0,
+; CHECK-NEXT: DBG_VALUE $a0, $noreg, !14, !DIExpression(DW_OP_LLVM_entry_value, 1)
+
+;; Test mipsel:
+; CHECKel: $a0 = nsw ADDu $a1, killed renamable $a0,
+; CHECKel-NEXT: DBG_VALUE $a0, $noreg, !14, !DIExpression(DW_OP_LLVM_entry_value, 1)
+
+; ModuleID = 'm.c'
+source_filename = "m.c"
+target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
+target triple = "mips-unknown-linux-gnu"
+
+; Function Attrs: nounwind
+define dso_local i32 @fn2(i32 signext %a, i32 signext %b, i32 signext %c) local_unnamed_addr !dbg !12 {
+entry:
+  call void @llvm.dbg.value(metadata i32 %a, metadata !14, metadata !DIExpression()), !dbg !18
+  call void @llvm.dbg.value(metadata i32 %b, metadata !15, metadata !DIExpression()), !dbg !18
+  call void @llvm.dbg.value(metadata i32 %c, metadata !16, metadata !DIExpression()), !dbg !18
+  %add = add nsw i32 %b, %a, !dbg !18
+  %add1 = add nsw i32 %b, 10, !dbg !18
+  %call = tail call i32 @fn1(i32 signext %add, i32 signext %c, i32 signext %add1), !dbg !18
+  call void @llvm.dbg.value(metadata i32 %call, metadata !17, metadata !DIExpression()), !dbg !18
+  %cmp = icmp sgt i32 %call, 10, !dbg !22
+  %add2 = add nsw i32 %call, 10, !dbg !18
+  %retval.0 = select i1 %cmp, i32 %add2, i32 %b, !dbg !18
+  ret i32 %retval.0, !dbg !18
+}
+
+declare !dbg !4 dso_local i32 @fn1(i32 signext, i32 signext, i32 signext) local_unnamed_addr
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!8, !9, !10}
+!llvm.ident = !{!11}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "m.c", directory: "/dir")
+!2 = !{}
+!3 = !{!4}
+!4 = !DISubprogram(name: "fn1", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
+!5 = !DISubroutineType(types: !6)
+!6 = !{!7, !7, !7, !7}
+!7 = !DIBasicType(name: "long int", size: 32, encoding: DW_ATE_signed)
+!8 = !{i32 7, !"Dwarf Version", i32 4}
+!9 = !{i32 2, !"Debug Info Version", i32 3}
+!10 = !{i32 1, !"wchar_size", i32 4}
+!11 = !{!"clang version 11.0.0"}
+!12 = distinct !DISubprogram(name: "fn2", scope: !1, file: !1, line: 2, type: !5, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13)
+!13 = !{!14, !15, !16, !17}
+!14 = !DILocalVariable(name: "a", arg: 1, scope: !12, file: !1, line: 2, type: !7)
+!15 = !DILocalVariable(name: "b", arg: 2, scope: !12, file: !1, line: 2, type: !7)
+!16 = !DILocalVariable(name: "c", arg: 3, scope: !12, file: !1, line: 2, type: !7)
+!17 = !DILocalVariable(name: "local", scope: !12, file: !1, line: 3, type: !7)
+!18 = !DILocation(line: 0, scope: !12)
+!22 = !DILocation(line: 4, column: 13, scope: !23)
+!23 = distinct !DILexicalBlock(scope: !12, file: !1, line: 4, column: 7)

diff  --git a/llvm/test/DebugInfo/Mips/dw_op_entry_value_64bit.ll b/llvm/test/DebugInfo/Mips/dw_op_entry_value_64bit.ll
new file mode 100644
index 000000000000..c0f0184f8b2f
--- /dev/null
+++ b/llvm/test/DebugInfo/Mips/dw_op_entry_value_64bit.ll
@@ -0,0 +1,77 @@
+;; Test mips64:
+; RUN: llc -emit-call-site-info -stop-after=livedebugvalues -mtriple=mips64-linux-gnu -o - %s | FileCheck %s --check-prefix=CHECK64
+;; Test mips64el:
+; RUN: llc -emit-call-site-info -stop-after=livedebugvalues -mtriple=mips64el-linux-gnu -o - %s | FileCheck %s --check-prefix=CHECK64el
+
+;; Built from source:
+;; extern long fn1(long,long,long);
+;; long fn2(long a, long b, long c) {
+;;   long local = fn1(a+b, c, b+10);
+;;   if (local > 10)
+;;     return local + 10;
+;;   return b;
+;; }
+;; Using command:
+;; clang -g -O2 -target mips64-linux-gnu m.c -c -S -emit-llvm
+;; Confirm that info from callSites attribute is used as entry_value in DIExpression.
+
+;; Test mips64:
+; CHECK64: $a0_64 = nsw DADDu $a1_64, killed renamable $a0_64,
+; CHECK64-NEXT: DBG_VALUE $a0_64, $noreg, !15, !DIExpression(DW_OP_LLVM_entry_value, 1)
+
+;; Test mips64el:
+; CHECK64el: $a0_64 = nsw DADDu $a1_64, killed renamable $a0_64,
+; CHECK64el-NEXT: DBG_VALUE $a0_64, $noreg, !15, !DIExpression(DW_OP_LLVM_entry_value, 1)
+
+; ModuleID = 'm.c'
+source_filename = "m.c"
+target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+target triple = "mips64-unknown-linux-gnu"
+
+; Function Attrs: nounwind
+define i64 @fn2(i64 signext %a, i64 signext %b, i64 signext %c) local_unnamed_addr !dbg !13 {
+entry:
+  call void @llvm.dbg.value(metadata i64 %a, metadata !15, metadata !DIExpression()), !dbg !19
+  call void @llvm.dbg.value(metadata i64 %b, metadata !16, metadata !DIExpression()), !dbg !19
+  call void @llvm.dbg.value(metadata i64 %c, metadata !17, metadata !DIExpression()), !dbg !19
+  %add = add nsw i64 %b, %a, !dbg !19
+  %add1 = add nsw i64 %b, 10, !dbg !19
+  %call = tail call i64 @fn1(i64 signext %add, i64 signext %c, i64 signext %add1), !dbg !19
+  call void @llvm.dbg.value(metadata i64 %call, metadata !18, metadata !DIExpression()), !dbg !19
+  %cmp = icmp sgt i64 %call, 10, !dbg !23
+  %add2 = add nsw i64 %call, 10, !dbg !19
+  %retval.0 = select i1 %cmp, i64 %add2, i64 %b, !dbg !19
+  ret i64 %retval.0, !dbg !19
+}
+
+declare !dbg !4 i64 @fn1(i64 signext, i64 signext, i64 signext) local_unnamed_addr
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!8, !9, !10, !11}
+!llvm.ident = !{!12}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "m.c", directory: "/dir")
+!2 = !{}
+!3 = !{!4}
+!4 = !DISubprogram(name: "fn1", scope: !1, file: !1, line: 1, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
+!5 = !DISubroutineType(types: !6)
+!6 = !{!7, !7, !7, !7}
+!7 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed)
+!8 = !{i32 7, !"Dwarf Version", i32 4}
+!9 = !{i32 2, !"Debug Info Version", i32 3}
+!10 = !{i32 1, !"wchar_size", i32 4}
+!11 = !{i32 7, !"PIC Level", i32 1}
+!12 = !{!"clang version 11.0.0"}
+!13 = distinct !DISubprogram(name: "fn2", scope: !1, file: !1, line: 2, type: !5, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !14)
+!14 = !{!15, !16, !17, !18}
+!15 = !DILocalVariable(name: "a", arg: 1, scope: !13, file: !1, line: 2, type: !7)
+!16 = !DILocalVariable(name: "b", arg: 2, scope: !13, file: !1, line: 2, type: !7)
+!17 = !DILocalVariable(name: "c", arg: 3, scope: !13, file: !1, line: 2, type: !7)
+!18 = !DILocalVariable(name: "local", scope: !13, file: !1, line: 3, type: !7)
+!19 = !DILocation(line: 0, scope: !13)
+!23 = !DILocation(line: 4, column: 13, scope: !24)
+!24 = distinct !DILexicalBlock(scope: !13, file: !1, line: 4, column: 7)


        


More information about the cfe-commits mailing list