Index: llvm/lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -210,6 +210,10 @@ EmitStartPt = EmitStartPt->getPrevNode(); LLVM_DEBUG(dbgs() << "removing dead local value materialization" << LocalMI); + auto CalleesMap = MF->getCallSitesInfo(); + if (LocalMI.isCandidateForCallSiteEntry() && + CalleesMap.find(&LocalMI) != CalleesMap.end()) + MF->eraseCallSiteInfo(&LocalMI); LocalMI.eraseFromParent(); } } @@ -470,6 +474,10 @@ MachineInstr *Dead = &*I; ++I; + auto CalleesMap = MF->getCallSitesInfo(); + if (Dead->isCandidateForCallSiteEntry() && + CalleesMap.find(Dead) != CalleesMap.end()) + MF->eraseCallSiteInfo(Dead); Dead->eraseFromParent(); ++NumFastIselDead; } @@ -941,6 +949,10 @@ MIB->setPhysRegsDeadExcept(CLI.InRegs, TRI); + auto CalleesMap = FuncInfo.MF->getCallSitesInfo(); + if (CLI.Call->isCandidateForCallSiteEntry() && + CalleesMap.find(CLI.Call) != CalleesMap.end()) + FuncInfo.MF->eraseCallSiteInfo(CLI.Call); // Delete the original call instruction. CLI.Call->eraseFromParent(); Index: llvm/lib/Target/X86/X86FastISel.cpp =================================================================== --- llvm/lib/Target/X86/X86FastISel.cpp +++ llvm/lib/Target/X86/X86FastISel.cpp @@ -3218,6 +3218,8 @@ bool Is64Bit = Subtarget->is64Bit(); bool IsWin64 = Subtarget->isCallingConvWin64(CC); + MachineFunction::CallSiteInfo CSInfo; + // Call / invoke instructions with NoCfCheck attribute require special // handling. if (CB && CB->doesNoCfCheck()) @@ -3433,6 +3435,8 @@ if (VA.isRegLoc()) { BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::COPY), VA.getLocReg()).addReg(ArgReg); + + CSInfo.emplace_back(VA.getLocReg(), i); OutRegs.push_back(VA.getLocReg()); } else { assert(VA.isMemLoc() && "Unknown value location!"); @@ -3546,6 +3550,9 @@ MIB.addReg(0); } + if (MIB->isCandidateForCallSiteEntry() && TM.Options.EmitCallSiteInfo) + MF->addCallArgsForwardingRegs(&*MIB, std::move(CSInfo)); + // Add a register mask operand representing the call-preserved registers. // Proper defs for return values will be added by setPhysRegsDeadExcept(). MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC)); Index: llvm/test/CodeGen/X86/call-site-info-output.ll =================================================================== --- llvm/test/CodeGen/X86/call-site-info-output.ll +++ llvm/test/CodeGen/X86/call-site-info-output.ll @@ -18,6 +18,14 @@ ; PARSER-NEXT: arg: 0, reg: '$edi' ; PARSER-NEXT: arg: 1, reg: '$esi' ; PARSER-NEXT: arg: 2, reg: '$edx' +; RUN: llc -emit-call-site-info %s -stop-before=finalize-isel -fast-isel=true -o - | FileCheck %s --check-prefix=FASTISEL +; Verify that callSites entry are generated for fastIsel. +; FASTISEL: name: fn2 +; FASTISEL: callSites: +; FASTISEL-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; FASTISEL-NEXT: arg: 0, reg: '$edi' +; FASTISEL-NEXT: arg: 1, reg: '$esi' +; FASTISEL-NEXT: arg: 2, reg: '$edx' ; ModuleID = 'test/CodeGen/X86/call-site-info-output.c' source_filename = "test/CodeGen/X86/call-site-info-output.c" Index: llvm/test/DebugInfo/X86/callsitepar-fastisel.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/callsitepar-fastisel.ll @@ -0,0 +1,317 @@ +;; This test checks if DW_TAG_GNU_call_site_parameter is generated for fastIsel. +; REQUIRES: x86_64-linux +;RUN: llc -O0 -mtriple=x86_64-pc-linux-gnu -emit-call-site-info -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s + +;; This should be genenerated now. +;CHECK: DW_TAG_GNU_call_site +;CHECK: DW_AT_abstract_origin +;CHECK-SAME: "foo" +;CHECK: DW_AT_low_pc +;CHECK: DW_TAG_GNU_call_site_parameter +;CHECK: DW_AT_location (DW_OP_reg4 RSI) +;CHECK: DW_AT_GNU_call_site_value + +;; This was already being generated. +;CHECK: DW_OP_GNU_entry_value + +;;The IR is generated from below source program +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;subroutine foo (array) +;; integer :: array(:,:) +;; array(:,:) = 5 +;; array(1,1) = 30 +;;end subroutine +;; +;;program vla_sub +;; interface +;; subroutine foo (array) +;; integer :: array (:,:) +;; end subroutine +;; end interface +;; +;; integer :: sub_arr(42,42) +;; sub_arr(:,:) = 1 +;; call foo(sub_arr) +;;end program vla_sub +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; ModuleID = 'fast.ll' +source_filename = "/tmp/fast.ll" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.BSS2 = type <{ [7056 x i8] }> + +@.BSS2 = internal global %struct.BSS2 zeroinitializer, align 32, !dbg !0 +@.C359_MAIN_ = internal constant i64 42 +@.C333_MAIN_ = internal constant i64 1 +@.C368_MAIN_ = internal constant i64 4 +@.C367_MAIN_ = internal constant i64 25 +@.C331_MAIN_ = internal constant i64 0 +@.C330_MAIN_ = internal constant i32 0 + +define void @foo_(i64* noalias %array, i64* noalias %"array$sd") !dbg !15 { +L.entry: + %z_b_1_350 = alloca i64, align 8 + %z_b_2_351 = alloca i64, align 8 + %z_b_4_352 = alloca i64, align 8 + %z_b_6_354 = alloca i64, align 8 + %.dY0001_373 = alloca i64, align 8 + %"i$a_368" = alloca i64, align 8 + %.dY0002_376 = alloca i64, align 8 + %"i$b_369" = alloca i64, align 8 + call void @llvm.dbg.value(metadata i64* %array, metadata !28, metadata !DIExpression()), !dbg !29 + call void @llvm.dbg.declare(metadata i64* %"array$sd", metadata !30, metadata !DIExpression()), !dbg !29 + %0 = bitcast i64* %"array$sd" to i8* + %1 = getelementptr i8, i8* %0, i64 88 + %2 = bitcast i8* %1 to i64* + %3 = load i64, i64* %2, align 8 + call void @llvm.dbg.declare(metadata i64* %z_b_1_350, metadata !21, metadata !DIExpression()), !dbg !29 + store i64 %3, i64* %z_b_1_350, align 8 + %4 = bitcast i64* %"array$sd" to i8* + %5 = getelementptr i8, i8* %4, i64 160 + %6 = bitcast i8* %5 to i64* + %7 = load i64, i64* %6, align 8 + call void @llvm.dbg.declare(metadata i64* %z_b_2_351, metadata !35, metadata !DIExpression()), !dbg !29 + store i64 %7, i64* %z_b_2_351, align 8 + %8 = bitcast i64* %"array$sd" to i8* + %9 = getelementptr i8, i8* %8, i64 136 + %10 = bitcast i8* %9 to i64* + %11 = load i64, i64* %10, align 8 + call void @llvm.dbg.declare(metadata i64* %z_b_4_352, metadata !24, metadata !DIExpression()), !dbg !29 + store i64 %11, i64* %z_b_4_352, align 8 + %12 = bitcast i64* %"array$sd" to i8* + %13 = getelementptr i8, i8* %12, i64 56 + %14 = bitcast i8* %13 to i64* + %15 = load i64, i64* %14, align 8 + %16 = bitcast i64* %"array$sd" to i8* + %17 = getelementptr i8, i8* %16, i64 160 + %18 = bitcast i8* %17 to i64* + %19 = load i64, i64* %18, align 8 + %20 = bitcast i64* %"array$sd" to i8* + %21 = getelementptr i8, i8* %20, i64 128 + %22 = bitcast i8* %21 to i64* + %23 = load i64, i64* %22, align 8 + %24 = sub nsw i64 %23, 1 + %25 = mul nsw i64 %19, %24 + %26 = bitcast i64* %"array$sd" to i8* + %27 = getelementptr i8, i8* %26, i64 80 + %28 = bitcast i8* %27 to i64* + %29 = load i64, i64* %28, align 8 + %30 = sub nsw i64 %29, 1 + %31 = add nsw i64 %25, %30 + %32 = add nsw i64 %15, %31 + call void @llvm.dbg.declare(metadata i64* %z_b_6_354, metadata !36, metadata !DIExpression()), !dbg !29 + store i64 %32, i64* %z_b_6_354, align 8 + %33 = load i64, i64* %z_b_4_352, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %z_b_4_352, metadata !38, metadata !DIExpression()), !dbg !29 + store i64 %33, i64* %.dY0001_373, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %"i$a_368", metadata !39, metadata !DIExpression()), !dbg !29 + store i64 1, i64* %"i$a_368", align 8, !dbg !37 + %34 = load i64, i64* %z_b_1_350, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %z_b_1_350, metadata !40, metadata !DIExpression()), !dbg !29 + %35 = icmp sle i64 %34, 0, !dbg !37 + %36 = sext i1 %35 to i32, !dbg !37 + %37 = load i64, i64* %z_b_4_352, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %z_b_4_352, metadata !41, metadata !DIExpression()), !dbg !29 + %38 = icmp sle i64 %37, 0, !dbg !37 + %39 = sext i1 %38 to i32, !dbg !37 + %40 = or i32 %36, %39, !dbg !37 + %41 = icmp ne i32 %40, 0, !dbg !37 + br i1 %41, label %L.LB1_372, label %L.LB1_371, !dbg !37 + +L.LB1_371: ; preds = %L.LB1_426, %L.LB1_415 + %42 = load i64, i64* %z_b_1_350, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %z_b_1_350, metadata !42, metadata !DIExpression()), !dbg !29 + store i64 %42, i64* %.dY0002_376, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %"i$b_369", metadata !43, metadata !DIExpression()), !dbg !29 + store i64 1, i64* %"i$b_369", align 8, !dbg !37 + br label %L.LB1_374 + +L.LB1_374: ; preds = %L.LB1_374, %L.LB1_371 + %43 = load i64, i64* %"i$b_369", align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %"i$b_369", metadata !44, metadata !DIExpression()), !dbg !29 + %44 = load i64, i64* %"i$a_368", align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %"i$a_368", metadata !45, metadata !DIExpression()), !dbg !29 + %45 = load i64, i64* %z_b_2_351, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata i64* %z_b_2_351, metadata !46, metadata !DIExpression()), !dbg !29 + %46 = mul nsw i64 %44, %45, !dbg !37 + %47 = add nsw i64 %43, %46, !dbg !37 + %48 = load i64, i64* %z_b_6_354, align 8, !dbg !37 + %49 = add nsw i64 %47, %48, !dbg !37 + %50 = bitcast i64* %array to i8*, !dbg !37 + %51 = getelementptr i8, i8* %50, i64 -4, !dbg !37 + %52 = bitcast i8* %51 to i32*, !dbg !37 + %53 = getelementptr i32, i32* %52, i64 %49, !dbg !37 + store i32 5, i32* %53, align 4, !dbg !37 + %54 = load i64, i64* %"i$b_369", align 8, !dbg !37 + %55 = add nsw i64 %54, 1, !dbg !37 + store i64 %55, i64* %"i$b_369", align 8, !dbg !37 + %56 = load i64, i64* %.dY0002_376, align 8, !dbg !37 + %57 = sub nsw i64 %56, 1, !dbg !37 + store i64 %57, i64* %.dY0002_376, align 8, !dbg !37 + %58 = load i64, i64* %.dY0002_376, align 8, !dbg !37 + %59 = icmp sgt i64 %58, 0, !dbg !37 + br i1 %59, label %L.LB1_374, label %L.LB1_426, !dbg !37 + +L.LB1_426: ; preds = %L.LB1_374 + %60 = load i64, i64* %"i$a_368", align 8, !dbg !37 + %61 = add nsw i64 %60, 1, !dbg !37 + store i64 %61, i64* %"i$a_368", align 8, !dbg !37 + %62 = load i64, i64* %.dY0001_373, align 8, !dbg !37 + %63 = sub nsw i64 %62, 1, !dbg !37 + store i64 %63, i64* %.dY0001_373, align 8, !dbg !37 + %64 = load i64, i64* %.dY0001_373, align 8, !dbg !37 + %65 = icmp sgt i64 %64, 0, !dbg !37 + br i1 %65, label %L.LB1_371, label %L.LB1_372, !dbg !37 + +L.LB1_372: ; preds = %L.LB1_426, %L.entry + %66 = load i64, i64* %z_b_2_351, align 8, !dbg !47 + %67 = load i64, i64* %z_b_6_354, align 8, !dbg !47 + %68 = add nsw i64 %66, %67, !dbg !47 + %69 = bitcast i64* %array to i32*, !dbg !47 + %70 = getelementptr i32, i32* %69, i64 %68, !dbg !47 + store i32 30, i32* %70, align 4, !dbg !47 + ret void, !dbg !48 +} + +define void @MAIN_() !dbg !2 { +L.entry: + %"sub_arr$sd1_366" = alloca [22 x i64], align 8 + %.dY0001_376 = alloca i64, align 8 + %"i$a_363" = alloca i64, align 8 + %.dY0002_379 = alloca i64, align 8 + %"i$b_364" = alloca i64, align 8 + %0 = bitcast i32* @.C330_MAIN_ to i8* + %1 = bitcast void (...)* @fort_init to void (i8*, ...)* + call void (i8*, ...) %1(i8* %0) + %2 = bitcast [22 x i64]* %"sub_arr$sd1_366" to i8* + %3 = bitcast i64* @.C331_MAIN_ to i8* + %4 = bitcast i64* @.C367_MAIN_ to i8* + %5 = bitcast i64* @.C368_MAIN_ to i8* + %6 = bitcast i64* @.C333_MAIN_ to i8* + %7 = bitcast i64* @.C359_MAIN_ to i8* + %8 = bitcast i64* @.C333_MAIN_ to i8* + %9 = bitcast i64* @.C359_MAIN_ to i8* + %10 = bitcast void (...)* @f90_template2_i8 to void (i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, ...)* + call void (i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, ...) %10(i8* %2, i8* %3, i8* %4, i8* %5, i8* %6, i8* %7, i8* %8, i8* %9) + %11 = bitcast [22 x i64]* %"sub_arr$sd1_366" to i8* + %12 = bitcast void (...)* @f90_set_intrin_type_i8 to void (i8*, i32, ...)* + call void (i8*, i32, ...) %12(i8* %11, i32 25) + br label %L.LB2_389 + +L.LB2_389: ; preds = %L.entry + store i64 42, i64* %.dY0001_376, align 8, !dbg !49 + store i64 1, i64* %"i$a_363", align 8, !dbg !49 + br label %L.LB2_374 + +L.LB2_374: ; preds = %L.LB2_402, %L.LB2_389 + store i64 42, i64* %.dY0002_379, align 8, !dbg !49 + store i64 1, i64* %"i$b_364", align 8, !dbg !49 + br label %L.LB2_377 + +L.LB2_377: ; preds = %L.LB2_377, %L.LB2_374 + %13 = load i64, i64* %"i$b_364", align 8, !dbg !49 + %14 = load i64, i64* %"i$a_363", align 8, !dbg !49 + %15 = mul nsw i64 %14, 42, !dbg !49 + %16 = add nsw i64 %13, %15, !dbg !49 + %17 = bitcast %struct.BSS2* @.BSS2 to i8*, !dbg !49 + %18 = getelementptr i8, i8* %17, i64 -172, !dbg !49 + %19 = bitcast i8* %18 to i32*, !dbg !49 + %20 = getelementptr i32, i32* %19, i64 %16, !dbg !49 + store i32 1, i32* %20, align 4, !dbg !49 + %21 = load i64, i64* %"i$b_364", align 8, !dbg !49 + %22 = add nsw i64 %21, 1, !dbg !49 + store i64 %22, i64* %"i$b_364", align 8, !dbg !49 + %23 = load i64, i64* %.dY0002_379, align 8, !dbg !49 + %24 = sub nsw i64 %23, 1, !dbg !49 + store i64 %24, i64* %.dY0002_379, align 8, !dbg !49 + %25 = load i64, i64* %.dY0002_379, align 8, !dbg !49 + %26 = icmp sgt i64 %25, 0, !dbg !49 + br i1 %26, label %L.LB2_377, label %L.LB2_402, !dbg !49 + +L.LB2_402: ; preds = %L.LB2_377 + %27 = load i64, i64* %"i$a_363", align 8, !dbg !49 + %28 = add nsw i64 %27, 1, !dbg !49 + store i64 %28, i64* %"i$a_363", align 8, !dbg !49 + %29 = load i64, i64* %.dY0001_376, align 8, !dbg !49 + %30 = sub nsw i64 %29, 1, !dbg !49 + store i64 %30, i64* %.dY0001_376, align 8, !dbg !49 + %31 = load i64, i64* %.dY0001_376, align 8, !dbg !49 + %32 = icmp sgt i64 %31, 0, !dbg !49 + br i1 %32, label %L.LB2_374, label %L.LB2_403, !dbg !49 + +L.LB2_403: ; preds = %L.LB2_402 + %33 = bitcast %struct.BSS2* @.BSS2 to i64*, !dbg !50 + %34 = bitcast [22 x i64]* %"sub_arr$sd1_366" to i64*, !dbg !50 + call void @foo_(i64* %33, i64* %34), !dbg !50 + ret void, !dbg !51 +} + +declare void @f90_set_intrin_type_i8(...) + +declare void @f90_template2_i8(...) + +declare void @fort_init(...) + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.module.flags = !{!13, !14} +!llvm.dbg.cu = !{!4} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "sub_arr", linkageName: ".BSS2", scope: !2, file: !3, line: 14, type: !9, isLocal: true, isDefinition: true) +!2 = distinct !DISubprogram(name: "vla_sub", scope: !4, file: !3, line: 7, type: !7, scopeLine: 7, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4) +!3 = !DIFile(filename: "fast.f90", directory: "/dir") +!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5, nameTableKind: None) +!5 = !{} +!6 = !{!0} +!7 = !DISubroutineType(cc: DW_CC_program, types: !8) +!8 = !{null} +!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 56448, align: 32, elements: !11) +!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!11 = !{!12, !12} +!12 = !DISubrange(lowerBound: 1, upperBound: 42) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = distinct !DISubprogram(name: "foo", scope: !4, file: !3, line: 1, type: !16, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition, unit: !4) +!16 = !DISubroutineType(types: !17) +!17 = !{null, !18, !25} +!18 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !19) +!19 = !{!20, !23} +!20 = !DISubrange(lowerBound: 1, upperBound: !21) +!21 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!22 = !DIBasicType(name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed) +!23 = !DISubrange(lowerBound: 1, upperBound: !24) +!24 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!25 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 1408, align: 64, elements: !26) +!26 = !{!27} +!27 = !DISubrange(lowerBound: 1, upperBound: 22) +!28 = !DILocalVariable(arg: 1, scope: !15, file: !3, line: 1, type: !22) +!29 = !DILocation(line: 0, scope: !15) +!30 = !DILocalVariable(name: "array", arg: 2, scope: !15, file: !3, line: 1, type: !31) +!31 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !32, dataLocation: !28) +!32 = !{!33, !34} +!33 = !DISubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 88, DW_OP_deref), lowerBound: 1, stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 112, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref, DW_OP_mul)) +!34 = !DISubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 136, DW_OP_deref), lowerBound: 1, stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 160, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref, DW_OP_mul)) +!35 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!36 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!37 = !DILocation(line: 3, column: 1, scope: !15) +!38 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!39 = distinct !DILocalVariable(scope: !15, file: !3, line: 3, type: !22, flags: DIFlagArtificial) +!40 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!41 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!42 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!43 = distinct !DILocalVariable(scope: !15, file: !3, line: 3, type: !22, flags: DIFlagArtificial) +!44 = distinct !DILocalVariable(scope: !15, file: !3, line: 3, type: !22, flags: DIFlagArtificial) +!45 = distinct !DILocalVariable(scope: !15, file: !3, line: 3, type: !22, flags: DIFlagArtificial) +!46 = distinct !DILocalVariable(scope: !15, file: !3, line: 2, type: !22, flags: DIFlagArtificial) +!47 = !DILocation(line: 4, column: 1, scope: !15) +!48 = !DILocation(line: 5, column: 1, scope: !15) +!49 = !DILocation(line: 15, column: 1, scope: !2) +!50 = !DILocation(line: 16, column: 1, scope: !2) +!51 = !DILocation(line: 17, column: 1, scope: !2)