diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp index 8fa2f38818c02..6eb914e67fd54 100644 --- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp +++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp @@ -35,6 +35,7 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -104,6 +105,37 @@ bool debugInfoIsAlreadySet(mlir::Location loc) { return false; } +// Generates the name for the artificial DISubprogram that we are going to +// generate for omp::TargetOp. Its logic is borrowed from +// getTargetEntryUniqueInfo and +// TargetRegionEntryInfo::getTargetRegionEntryFnName to generate the same name. +// But even if there was a slight mismatch, it is not a problem because this +// name is artificial and not important to debug experience. +mlir::StringAttr getTargetFunctionName(mlir::MLIRContext *context, + mlir::Location Loc, + llvm::StringRef parentName) { + auto fileLoc = Loc->findInstanceOf(); + + assert(fileLoc && "No file found from location"); + llvm::StringRef fileName = fileLoc.getFilename().getValue(); + + llvm::sys::fs::UniqueID id; + uint64_t line = fileLoc.getLine(); + size_t fileId; + size_t deviceId; + if (auto ec = llvm::sys::fs::getUniqueID(fileName, id)) { + fileId = llvm::hash_value(fileName.str()); + deviceId = 0xdeadf17e; + } else { + fileId = id.getFile(); + deviceId = id.getDevice(); + } + return mlir::StringAttr::get( + context, + std::string(llvm::formatv("__omp_offloading_{0:x-}_{1:x-}_{2}_l{3}", + deviceId, fileId, parentName, line))); +} + } // namespace bool AddDebugInfoPass::createCommonBlockGlobal( @@ -446,6 +478,79 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp, line - 1, false); } + auto addTargetOpDISP = [&](bool lineTableOnly, + llvm::ArrayRef entities) { + // When we process the DeclareOp inside the OpenMP target region, all the + // variables get the DISubprogram of the parent function of the target op as + // the scope. In the codegen (to llvm ir), OpenMP target op results in the + // creation of a separate function. As the variables in the debug info have + // the DISubprogram of the parent function as the scope, the variables + // need to be updated at codegen time to avoid verification failures. + + // This updating after the fact becomes more and more difficult when types + // are dependent on local variables like in the case of variable size arrays + // or string. We not only have to generate new variables but also new types. + // We can avoid this problem by generating a DISubprogramAttr here for the + // target op and make sure that all the variables inside the target region + // get the correct scope in the first place. + funcOp.walk([&](mlir::omp::TargetOp targetOp) { + unsigned line = getLineFromLoc(targetOp.getLoc()); + mlir::StringAttr name = + getTargetFunctionName(context, targetOp.getLoc(), funcOp.getName()); + mlir::LLVM::DISubprogramFlags flags = + mlir::LLVM::DISubprogramFlags::Definition | + mlir::LLVM::DISubprogramFlags::LocalToUnit; + if (isOptimized) + flags = flags | mlir::LLVM::DISubprogramFlags::Optimized; + + mlir::DistinctAttr id = + mlir::DistinctAttr::create(mlir::UnitAttr::get(context)); + llvm::SmallVector types; + types.push_back(mlir::LLVM::DINullTypeAttr::get(context)); + for (auto arg : targetOp.getRegion().getArguments()) { + auto tyAttr = typeGen.convertType(fir::unwrapRefType(arg.getType()), + fileAttr, cuAttr, /*declOp=*/nullptr); + types.push_back(tyAttr); + } + CC = llvm::dwarf::getCallingConvention("DW_CC_normal"); + mlir::LLVM::DISubroutineTypeAttr spTy = + mlir::LLVM::DISubroutineTypeAttr::get(context, CC, types); + if (lineTableOnly) { + auto spAttr = mlir::LLVM::DISubprogramAttr::get( + context, id, compilationUnit, Scope, name, name, funcFileAttr, line, + line, flags, spTy, /*retainedNodes=*/{}, /*annotations=*/{}); + targetOp->setLoc(builder.getFusedLoc({targetOp.getLoc()}, spAttr)); + return; + } + mlir::DistinctAttr recId = + mlir::DistinctAttr::create(mlir::UnitAttr::get(context)); + auto spAttr = mlir::LLVM::DISubprogramAttr::get( + context, recId, /*isRecSelf=*/true, id, compilationUnit, Scope, name, + name, funcFileAttr, line, line, flags, spTy, /*retainedNodes=*/{}, + /*annotations=*/{}); + + // Make sure that information about the imported modules is copied in the + // new function. + llvm::SmallVector opEntities; + for (mlir::LLVM::DINodeAttr N : entities) { + if (auto entity = mlir::dyn_cast(N)) { + auto importedEntity = mlir::LLVM::DIImportedEntityAttr::get( + context, llvm::dwarf::DW_TAG_imported_module, spAttr, + entity.getEntity(), fileAttr, /*line=*/1, /*name=*/nullptr, + /*elements*/ {}); + opEntities.push_back(importedEntity); + } + } + + id = mlir::DistinctAttr::create(mlir::UnitAttr::get(context)); + spAttr = mlir::LLVM::DISubprogramAttr::get( + context, recId, /*isRecSelf=*/false, id, compilationUnit, Scope, name, + name, funcFileAttr, line, line, flags, spTy, opEntities, + /*annotations=*/{}); + targetOp->setLoc(builder.getFusedLoc({targetOp.getLoc()}, spAttr)); + }); + }; + // Don't process variables if user asked for line tables only. if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly) { auto spAttr = mlir::LLVM::DISubprogramAttr::get( @@ -453,6 +558,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp, line, line, subprogramFlags, subTypeAttr, /*retainedNodes=*/{}, /*annotations=*/{}); funcOp->setLoc(builder.getFusedLoc({l}, spAttr)); + addTargetOpDISP(/*lineTableOnly=*/true, /*entities=*/{}); return; } @@ -510,9 +616,18 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp, funcName, fullName, funcFileAttr, line, line, subprogramFlags, subTypeAttr, entities, /*annotations=*/{}); funcOp->setLoc(builder.getFusedLoc({l}, spAttr)); + addTargetOpDISP(/*lineTableOnly=*/false, entities); funcOp.walk([&](fir::cg::XDeclareOp declOp) { - handleDeclareOp(declOp, fileAttr, spAttr, typeGen, symbolTable); + mlir::LLVM::DISubprogramAttr spTy = spAttr; + if (auto tOp = declOp->getParentOfType()) { + if (auto fusedLoc = llvm::dyn_cast(tOp.getLoc())) { + if (auto sp = llvm::dyn_cast( + fusedLoc.getMetadata())) + spTy = sp; + } + } + handleDeclareOp(declOp, fileAttr, spTy, typeGen, symbolTable); }); // commonBlockMap ensures that we don't create multiple DICommonBlockAttr of // the same name in one function. But it is ok (rather required) to create diff --git a/flang/test/Transforms/debug-omp-target-op-1.fir b/flang/test/Transforms/debug-omp-target-op-1.fir new file mode 100644 index 0000000000000..6b895b732c42b --- /dev/null +++ b/flang/test/Transforms/debug-omp-target-op-1.fir @@ -0,0 +1,40 @@ +// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s +// RUN: fir-opt --add-debug-info="debug-level=LineTablesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=LINETABLE + +module attributes {dlti.dl_spec = #dlti.dl_spec<>} { + func.func @_QQmain() attributes {fir.bindc_name = "test"} { + %c13_i32 = arith.constant 13 : i32 + %c12_i32 = arith.constant 12 : i32 + %c6_i32 = arith.constant 6 : i32 + %c1_i32 = arith.constant 1 : i32 + %c5_i32 = arith.constant 5 : i32 + %0 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFEx"} loc(#loc1) + %1 = fircg.ext_declare %0 {uniq_name = "_QFEx"} : (!fir.ref) -> !fir.ref loc(#loc1) + %2 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"} loc(#loc2) + %3 = fircg.ext_declare %2 {uniq_name = "_QFEy"} : (!fir.ref) -> !fir.ref loc(#loc2) + %4 = omp.map.info var_ptr(%1 : !fir.ref, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref {name = "x"} + %5 = omp.map.info var_ptr(%3 : !fir.ref, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref {name = "y"} + omp.target map_entries(%4 -> %arg0, %5 -> %arg1 : !fir.ref, !fir.ref) { + %16 = fircg.ext_declare %arg0 {uniq_name = "_QFEx"} : (!fir.ref) -> !fir.ref loc(#loc3) + %17 = fircg.ext_declare %arg1 {uniq_name = "_QFEy"} : (!fir.ref) -> !fir.ref loc(#loc4) + omp.terminator + } loc(#loc5) + return + } +} +#loc1 = loc("test.f90":1:1) +#loc2 = loc("test.f90":3:1) +#loc3 = loc("test.f90":7:1) +#loc4 = loc("test.f90":8:1) +#loc5 = loc("test.f90":6:1) + +// CHECK: #[[SP:.*]] = #llvm.di_subprogram<{{.*}}name = "test"{{.*}}> +// CHECK: #[[SP1:.*]] = #llvm.di_subprogram<{{.*}}name = "__omp_offloading_{{.*}}_QQmain_l6"{{.*}}line = 6{{.*}}subprogramFlags = "LocalToUnit|Definition"{{.*}}> +// CHECK: #llvm.di_local_variable +// CHECK: #llvm.di_local_variable +// CHECK: #llvm.di_local_variable +// CHECK: #llvm.di_local_variable + +// LINETABLE: #[[SP:.*]] = #llvm.di_subprogram<{{.*}}name = "test"{{.*}}> +// LINETABLE: #[[SP1:.*]] = #llvm.di_subprogram<{{.*}}name = "__omp_offloading_{{.*}}_QQmain_l6"{{.*}}line = 6{{.*}}subprogramFlags = "LocalToUnit|Definition"{{.*}}> +// LINETABLE-NOT: #llvm.di_local_variable diff --git a/flang/test/Transforms/debug-omp-target-op-2.fir b/flang/test/Transforms/debug-omp-target-op-2.fir new file mode 100644 index 0000000000000..15dcf2389b21d --- /dev/null +++ b/flang/test/Transforms/debug-omp-target-op-2.fir @@ -0,0 +1,53 @@ +// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s + +module attributes {dlti.dl_spec = #dlti.dl_spec<>} { + func.func @fn_(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "c"}, %arg2: !fir.ref {fir.bindc_name = "d"}) { + %c1 = arith.constant 1 : index + %c0 = arith.constant 0 : index + %0 = fir.alloca i32 + %1 = fir.alloca i32 + %2 = fir.undefined !fir.dscope + %3 = fircg.ext_declare %arg1 dummy_scope %2 {uniq_name = "_QFfnEc"} : (!fir.ref, !fir.dscope) -> !fir.ref loc(#loc2) + %4 = fircg.ext_declare %arg2 dummy_scope %2 {uniq_name = "_QFfnEd"} : (!fir.ref, !fir.dscope) -> !fir.ref loc(#loc3) + %5 = fir.load %3 : !fir.ref + %6 = fir.convert %5 : (i32) -> index + %9 = fir.load %4 : !fir.ref + %10 = fir.convert %9 : (i32) -> index + %15 = fircg.ext_declare %arg0(%6, %10) dummy_scope %2 {uniq_name = "_QFfnEb"} : (!fir.ref>, index, index, !fir.dscope) -> !fir.ref> loc(#loc4) + %16 = fircg.ext_embox %15(%6, %10) : (!fir.ref>, index, index) -> !fir.box> + %17:3 = fir.box_dims %16, %c0 : (!fir.box>, index) -> (index, index, index) + %18 = arith.subi %17#1, %c1 : index + %19 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%18 : index) extent(%17#1 : index) stride(%17#2 : index) start_idx(%c1 : index) {stride_in_bytes = true} + %20 = arith.muli %17#2, %17#1 : index + %21:3 = fir.box_dims %16, %c1 : (!fir.box>, index) -> (index, index, index) + %22 = arith.subi %21#1, %c1 : index + %23 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%22 : index) extent(%21#1 : index) stride(%20 : index) start_idx(%c1 : index) {stride_in_bytes = true} + %24 = omp.map.info var_ptr(%15 : !fir.ref>, i32) map_clauses(tofrom) capture(ByRef) bounds(%19, %23) -> !fir.ref> {name = "b"} + %25 = omp.map.info var_ptr(%1 : !fir.ref, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref {name = ""} + %26 = omp.map.info var_ptr(%0 : !fir.ref, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref {name = ""} + omp.target map_entries(%24 -> %arg3, %25 -> %arg4, %26 -> %arg5 : !fir.ref>, !fir.ref, !fir.ref) { + %27 = fir.load %arg5 : !fir.ref + %28 = fir.load %arg4 : !fir.ref + %29 = fir.convert %27 : (i32) -> index + %31 = fir.convert %28 : (i32) -> index + %37 = fircg.ext_declare %arg3(%29, %31) {uniq_name = "_QFfnEb"} : (!fir.ref>, index, index) -> !fir.ref> loc(#loc5) + omp.terminator + } loc(#loc6) + return + } loc(#loc7) +} +#loc1 = loc("test.f90":1:1) +#loc2 = loc("test.f90":3:1) +#loc3 = loc("test.f90":7:1) +#loc4 = loc("test.f90":8:1) +#loc5 = loc("test.f90":6:1) +#loc6 = loc("test.f90":16:1) +#loc7 = loc("test.f90":26:1) + + +// Test that variable size arrays inside target regions get their own +// compiler generated variables for size. + +// CHECK: #[[SP:.*]] = #llvm.di_subprogram<{{.*}}name = "__omp_offloading_{{.*}}_fn__l16"{{.*}}> +// CHECK: #llvm.di_local_variable +// CHECK: #llvm.di_local_variable diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index 85451b1233f96..db792a3b52d24 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -6891,23 +6891,19 @@ static void FixupDebugInfoForOutlinedFunction( if (!NewSP) return; - DenseMap Cache; SmallDenseMap RemappedVariables; auto GetUpdatedDIVariable = [&](DILocalVariable *OldVar, unsigned arg) { - auto NewSP = Func->getSubprogram(); DILocalVariable *&NewVar = RemappedVariables[OldVar]; // Only use cached variable if the arg number matches. This is important // so that DIVariable created for privatized variables are not discarded. if (NewVar && (arg == NewVar->getArg())) return NewVar; - DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram( - *OldVar->getScope(), *NewSP, Builder.getContext(), Cache); NewVar = llvm::DILocalVariable::get( - Builder.getContext(), NewScope, OldVar->getName(), OldVar->getFile(), - OldVar->getLine(), OldVar->getType(), arg, OldVar->getFlags(), - OldVar->getAlignInBits(), OldVar->getAnnotations()); + Builder.getContext(), OldVar->getScope(), OldVar->getName(), + OldVar->getFile(), OldVar->getLine(), OldVar->getType(), arg, + OldVar->getFlags(), OldVar->getAlignInBits(), OldVar->getAnnotations()); return NewVar; }; @@ -6921,7 +6917,8 @@ static void FixupDebugInfoForOutlinedFunction( ArgNo = std::get<1>(Iter->second) + 1; } } - DR->setVariable(GetUpdatedDIVariable(OldVar, ArgNo)); + if (ArgNo != 0) + DR->setVariable(GetUpdatedDIVariable(OldVar, ArgNo)); }; // The location and scope of variable intrinsics and records still point to @@ -7000,36 +6997,9 @@ static Expected createOutlinedFunction( // Save insert point. IRBuilder<>::InsertPointGuard IPG(Builder); - // If there's a DISubprogram associated with current function, then - // generate one for the outlined function. - if (Function *ParentFunc = BB->getParent()) { - if (DISubprogram *SP = ParentFunc->getSubprogram()) { - DICompileUnit *CU = SP->getUnit(); - DIBuilder DB(*M, true, CU); - DebugLoc DL = Builder.getCurrentDebugLocation(); - if (DL) { - // TODO: We are using nullopt for arguments at the moment. This will - // need to be updated when debug data is being generated for variables. - DISubroutineType *Ty = - DB.createSubroutineType(DB.getOrCreateTypeArray({})); - DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagDefinition | - DISubprogram::SPFlagOptimized | - DISubprogram::SPFlagLocalToUnit; - - DISubprogram *OutlinedSP = DB.createFunction( - CU, FuncName, FuncName, SP->getFile(), DL.getLine(), Ty, - DL.getLine(), DINode::DIFlags::FlagArtificial, SPFlags); - - // Attach subprogram to the function. - Func->setSubprogram(OutlinedSP); - // Update the CurrentDebugLocation in the builder so that right scope - // is used for things inside outlined function. - Builder.SetCurrentDebugLocation( - DILocation::get(Func->getContext(), DL.getLine(), DL.getCol(), - OutlinedSP, DL.getInlinedAt())); - } - } - } + // We will generate the entries in the outlined function but the debug + // location may still be pointing to the parent function. Reset it now. + Builder.SetCurrentDebugLocation(llvm::DebugLoc()); // Generate the region into the function. BasicBlock *EntryBB = BasicBlock::Create(Builder.getContext(), "entry", Func); diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp index 3806db3ceab25..c1e1fec3ddef8 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -5324,9 +5324,27 @@ static LogicalResult convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { auto targetOp = cast(opInst); + // The current debug location already has the DISubprogram for the outlined + // function that will be created for the target op. We save it here so that + // we can set it on the outlined function. + llvm::DebugLoc outlinedFnLoc = builder.getCurrentDebugLocation(); if (failed(checkImplementationStatus(opInst))) return failure(); + // During the handling of target op, we will generate instructions in the + // parent function like call to the oulined function or branch to a new + // BasicBlock. We set the debug location here to parent function so that those + // get the correct debug locations. For outlined functions, the normal MLIR op + // conversion will automatically pick the correct location. + llvm::BasicBlock *parentBB = builder.GetInsertBlock(); + assert(parentBB && "No insert block is set for the builder"); + llvm::Function *parentLLVMFn = parentBB->getParent(); + assert(parentLLVMFn && "Parent Function must be valid"); + if (llvm::DISubprogram *SP = parentLLVMFn->getSubprogram()) + builder.SetCurrentDebugLocation(llvm::DILocation::get( + parentLLVMFn->getContext(), outlinedFnLoc.getLine(), + outlinedFnLoc.getCol(), SP, outlinedFnLoc.getInlinedAt())); + llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder(); bool isTargetDevice = ompBuilder->Config.isTargetDevice(); bool isGPU = ompBuilder->Config.isGPU(); @@ -5420,6 +5438,9 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder, assert(llvmParentFn && llvmOutlinedFn && "Both parent and outlined functions must exist at this point"); + if (outlinedFnLoc && llvmParentFn->getSubprogram()) + llvmOutlinedFn->setSubprogram(outlinedFnLoc->getScope()->getSubprogram()); + if (auto attr = llvmParentFn->getFnAttribute("target-cpu"); attr.isStringAttribute()) llvmOutlinedFn->addFnAttr(attr); diff --git a/mlir/test/Target/LLVMIR/omptarget-debug-empty.mlir b/mlir/test/Target/LLVMIR/omptarget-debug-empty.mlir new file mode 100644 index 0000000000000..45e5d2612e2c2 --- /dev/null +++ b/mlir/test/Target/LLVMIR/omptarget-debug-empty.mlir @@ -0,0 +1,27 @@ +// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s + +module attributes {omp.is_target_device = false} { + llvm.func @test() { + omp.target { + omp.terminator + } loc(#loc4) + llvm.return + } loc(#loc3) +} +#file = #llvm.di_file<"target.f90" in ""> +#cu = #llvm.di_compile_unit, + sourceLanguage = DW_LANG_Fortran95, file = #file, isOptimized = false, + emissionKind = Full> +#sp_ty = #llvm.di_subroutine_type +#sp = #llvm.di_subprogram, compileUnit = #cu, scope = #file, + name = "_QQmain", file = #file, subprogramFlags = "Definition", type = #sp_ty> +#sp1 = #llvm.di_subprogram, compileUnit = #cu, scope = #file, + name = "__omp_offloading_target", file = #file, subprogramFlags = "Definition", + type = #sp_ty> +#loc1 = loc("target.f90":1:1) +#loc2 = loc("target.f90":46:3) +#loc3 = loc(fused<#sp>[#loc1]) +#loc4 = loc(fused<#sp1>[#loc2]) + +// CHECK: ![[SP:.*]] = {{.*}}!DISubprogram(name: "__omp_offloading_target"{{.*}}) + diff --git a/mlir/test/Target/LLVMIR/omptarget-debug-loop-loc.mlir b/mlir/test/Target/LLVMIR/omptarget-debug-loop-loc.mlir index a755cef98d7c4..c3320382f8d45 100644 --- a/mlir/test/Target/LLVMIR/omptarget-debug-loop-loc.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-debug-loop-loc.mlir @@ -41,7 +41,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo omp.terminator loc(#loc9) } loc(#loc9) omp.terminator loc(#loc9) - } loc(#loc9) + } loc(#loc15) llvm.return loc(#loc9) } loc(#loc14) llvm.mlir.global internal @_QFEarray() {addr_space = 0 : i32} : !llvm.array<16384 x i32> { @@ -59,7 +59,9 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo #di_compile_unit = #llvm.di_compile_unit, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "flang", isOptimized = true, emissionKind = LineTablesOnly> #di_subroutine_type = #llvm.di_subroutine_type #di_subprogram = #llvm.di_subprogram, compileUnit = #di_compile_unit, scope = #di_file, name = "main", file = #di_file, subprogramFlags = "Definition|Optimized|MainSubprogram", type = #di_subroutine_type> +#di_subprogram1 = #llvm.di_subprogram #loc14 = loc(fused<#di_subprogram>[#loc3]) +#loc15 = loc(fused<#di_subprogram1>[#loc9]) // CHECK: call void @__kmpc_distribute_static{{.*}}!dbg diff --git a/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir b/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir index 4495e1559a889..492610251769c 100644 --- a/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-debug-map-link-loc.mlir @@ -16,7 +16,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo %16 = llvm.load %arg1 : !llvm.ptr -> i32 loc(#loc5) llvm.store %16, %arg0 : i32, !llvm.ptr loc(#loc5) omp.terminator loc(#loc5) - } loc(#loc5) + } loc(#loc16) llvm.return loc(#loc6) } loc(#loc15) } @@ -31,9 +31,13 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo compileUnit = #di_compile_unit, scope = #di_file, name = "main", file = #di_file, subprogramFlags = "Definition|MainSubprogram", type = #di_subroutine_type> +#di_subprogram1 = #llvm.di_subprogram #loc1 = loc("test.f90":3:18) #loc2 = loc("test.f90":7:7) #loc3 = loc("test.f90":9:18) #loc5 = loc("test.f90":11:7) #loc6 = loc("test.f90":12:7) #loc15 = loc(fused<#di_subprogram>[#loc2]) +#loc16 = loc(fused<#di_subprogram1>[#loc5]) diff --git a/mlir/test/Target/LLVMIR/omptarget-debug-nowait.mlir b/mlir/test/Target/LLVMIR/omptarget-debug-nowait.mlir index eaa88d9dd6053..3bd724f42e8ce 100644 --- a/mlir/test/Target/LLVMIR/omptarget-debug-nowait.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-debug-nowait.mlir @@ -20,7 +20,7 @@ module attributes {omp.is_target_device = false} { ^bb3: // pred: ^bb1 llvm.store %13, %arg1 : i32, !llvm.ptr omp.terminator - } + } loc(#loc3) llvm.return } loc(#loc2) } @@ -34,7 +34,10 @@ module attributes {omp.is_target_device = false} { types = #di_null_type> #sp = #llvm.di_subprogram +#sp1 = #llvm.di_subprogram #loc1 = loc("test.f90":6:7) #loc2 = loc(fused<#sp>[#loc1]) +#loc3 = loc(fused<#sp1>[#loc1]) diff --git a/mlir/test/Target/LLVMIR/omptarget-debug-var-1.mlir b/mlir/test/Target/LLVMIR/omptarget-debug-var-1.mlir index ea92589bbd031..8f42995af23a8 100644 --- a/mlir/test/Target/LLVMIR/omptarget-debug-var-1.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-debug-var-1.mlir @@ -19,11 +19,13 @@ #g_var_expr = #llvm.di_global_variable_expression #sp = #llvm.di_subprogram, compileUnit = #cu, scope = #file, name = "test", file = #file, subprogramFlags = "Definition", type = #sp_ty> -#var_arr = #llvm.di_local_variable, compileUnit = #cu, scope = #file, + name = "target", file = #file, subprogramFlags = "Definition", type = #sp_ty> +#var_arr = #llvm.di_local_variable -#var_i = #llvm.di_local_variable -#var_x = #llvm.di_local_variable module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui32>>, llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_target_device = true} { @@ -47,7 +49,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo llvm.intr.dbg.declare #var_arr = %arg1 : !llvm.ptr llvm.intr.dbg.declare #var_i = %arg2 : !llvm.ptr omp.terminator - } + } loc(#loc5) llvm.return } loc(#loc3) llvm.mlir.global internal @_QFEarr() {addr_space = 0 : i32, dbg_exprs = [#g_var_expr]} : !llvm.array<10 x i32> { @@ -57,8 +59,9 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo #loc2 = loc("target.f90":11:7) #loc3 = loc(fused<#sp>[#loc2]) #loc4 = loc(fused<#g_var>[#loc1]) +#loc5 = loc(fused<#sp1>[#loc2]) -// CHECK: ![[SP:[0-9]+]] = distinct !DISubprogram(name: "__omp_offloading{{.*}}test{{.*}}) +// CHECK: ![[SP:[0-9]+]] = distinct !DISubprogram(name: "target"{{.*}}) // CHECK: !DILocalVariable(name: "dyn_ptr", arg: 1, scope: ![[SP]]{{.*}}flags: DIFlagArtificial) // CHECK: !DILocalVariable(name: "x", arg: 2, scope: ![[SP]]{{.*}}) // CHECK: !DILocalVariable(name: "arr", arg: 3, scope: ![[SP]]{{.*}}) diff --git a/mlir/test/Target/LLVMIR/omptarget-debug-var-2.mlir b/mlir/test/Target/LLVMIR/omptarget-debug-var-2.mlir index 22db86fd85e2c..11a07dfd9a180 100644 --- a/mlir/test/Target/LLVMIR/omptarget-debug-var-2.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-debug-var-2.mlir @@ -19,11 +19,13 @@ #g_var_expr = #llvm.di_global_variable_expression #sp = #llvm.di_subprogram, compileUnit = #cu, scope = #file, name = "test", file = #file, subprogramFlags = "Definition", type = #sp_ty> -#var_arr = #llvm.di_local_variable, compileUnit = #cu, scope = #file, + name = "target", file = #file, subprogramFlags = "Definition", type = #sp_ty> +#var_arr = #llvm.di_local_variable -#var_i = #llvm.di_local_variable -#var_x = #llvm.di_local_variable module attributes {omp.is_target_device = false} { @@ -45,7 +47,7 @@ module attributes {omp.is_target_device = false} { llvm.intr.dbg.declare #var_arr = %arg1 : !llvm.ptr llvm.intr.dbg.declare #var_i = %arg2 : !llvm.ptr omp.terminator - } + } loc(#loc5) llvm.return } loc(#loc3) llvm.mlir.global internal @_QFEarr() {addr_space = 0 : i32, dbg_exprs = [#g_var_expr]} : !llvm.array<10 x i32> { @@ -55,8 +57,9 @@ module attributes {omp.is_target_device = false} { #loc2 = loc("target.f90":11:7) #loc3 = loc(fused<#sp>[#loc2]) #loc4 = loc(fused<#g_var>[#loc1]) +#loc5 = loc(fused<#sp1>[#loc2]) -// CHECK: ![[SP:[0-9]+]] = distinct !DISubprogram(name: "__omp_offloading{{.*}}test{{.*}}) +// CHECK: ![[SP:[0-9]+]] = distinct !DISubprogram(name: "target"{{.*}}) // CHECK: !DILocalVariable(name: "x", arg: 1, scope: ![[SP]]{{.*}}) // CHECK: !DILocalVariable(name: "arr", arg: 2, scope: ![[SP]]{{.*}}) // CHECK: !DILocalVariable(name: "i", arg: 3, scope: ![[SP]]{{.*}}) diff --git a/mlir/test/Target/LLVMIR/omptarget-debug.mlir b/mlir/test/Target/LLVMIR/omptarget-debug.mlir index 9c8344d69dc74..ab687f198b9b4 100644 --- a/mlir/test/Target/LLVMIR/omptarget-debug.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-debug.mlir @@ -10,7 +10,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo %13 = llvm.mlir.constant(1 : i32) : i32 llvm.store %13, %arg0 : i32, !llvm.ptr loc(#loc2) omp.terminator - } + } loc(#loc4) llvm.return } loc(#loc3) } @@ -21,9 +21,13 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo #sp_ty = #llvm.di_subroutine_type #sp = #llvm.di_subprogram, compileUnit = #cu, scope = #file, name = "_QQmain", file = #file, subprogramFlags = "Definition", type = #sp_ty> +#sp1 = #llvm.di_subprogram, compileUnit = #cu, scope = #file, + name = "__omp_offloading_target", file = #file, subprogramFlags = "Definition", + type = #sp_ty> #loc1 = loc("target.f90":1:1) #loc2 = loc("target.f90":46:3) #loc3 = loc(fused<#sp>[#loc1]) +#loc4 = loc(fused<#sp1>[#loc1]) -// CHECK-DAG: ![[SP:.*]] = {{.*}}!DISubprogram(name: "__omp_offloading_{{.*}}"{{.*}}) +// CHECK-DAG: ![[SP:.*]] = {{.*}}!DISubprogram(name: "__omp_offloading_target"{{.*}}) // CHECK-DAG: !DILocation(line: 46, column: 3, scope: ![[SP]]) diff --git a/mlir/test/Target/LLVMIR/omptarget-debug2.mlir b/mlir/test/Target/LLVMIR/omptarget-debug2.mlir index 78dc6e18a40a7..6cf75af38f916 100644 --- a/mlir/test/Target/LLVMIR/omptarget-debug2.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-debug2.mlir @@ -11,7 +11,7 @@ module attributes {omp.is_target_device = false} { %13 = llvm.mlir.constant(1 : i32) : i32 llvm.store %13, %arg0 : i32, !llvm.ptr loc(#loc2) omp.terminator - } + } loc(#loc4) llvm.return } loc(#loc3) } @@ -22,9 +22,13 @@ module attributes {omp.is_target_device = false} { #sp_ty = #llvm.di_subroutine_type #sp = #llvm.di_subprogram, compileUnit = #cu, scope = #file, name = "_QQmain", file = #file, subprogramFlags = "Definition", type = #sp_ty> +#sp1 = #llvm.di_subprogram, compileUnit = #cu, scope = #file, + name = "__omp_offloading_target", file = #file, subprogramFlags = "Definition", + type = #sp_ty> #loc1 = loc("target.f90":1:1) #loc2 = loc("target.f90":46:3) #loc3 = loc(fused<#sp>[#loc1]) +#loc4 = loc(fused<#sp1>[#loc1]) -// CHECK-DAG: ![[SP:.*]] = {{.*}}!DISubprogram(name: "__omp_offloading_{{.*}}"{{.*}}) +// CHECK-DAG: ![[SP:.*]] = {{.*}}!DISubprogram(name: "__omp_offloading_target"{{.*}}) // CHECK-DAG: !DILocation(line: 46, column: 3, scope: ![[SP]]) diff --git a/mlir/test/Target/LLVMIR/omptarget-parallel-llvm-debug.mlir b/mlir/test/Target/LLVMIR/omptarget-parallel-llvm-debug.mlir index 3c45f1f1c76fb..b18338ea35cc3 100644 --- a/mlir/test/Target/LLVMIR/omptarget-parallel-llvm-debug.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-parallel-llvm-debug.mlir @@ -6,8 +6,10 @@ #cu = #llvm.di_compile_unit, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "flang", isOptimized = false, emissionKind = Full> #sp_ty = #llvm.di_subroutine_type #sp = #llvm.di_subprogram +#sp1 = #llvm.di_subprogram #int_ty = #llvm.di_basic_type #var_x = #llvm.di_local_variable +#var_x1 = #llvm.di_local_variable module attributes {dlti.dl_spec = #dlti.dl_spec : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, i64 = dense<64> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, "dlti.endianness" = "little", "dlti.stack_alignment" = 128 : i64, "dlti.mangling_mode" = "e">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", fir.target_cpu = "x86-64", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 21.0.0 (/home/haqadeer/work/src/aomp-llvm-project/flang 793f9220ab32f92fc3b253efec2e332c18090e53)", llvm.target_triple = "x86_64-unknown-linux-gnu", omp.is_gpu = false, omp.is_target_device = false, omp.requires = #omp, omp.target_triples = ["amdgcn-amd-amdhsa"], omp.version = #omp.version} { llvm.func @_QQmain() attributes {fir.bindc_name = "test", frame_pointer = #llvm.framePointerKind, target_cpu = "x86-64"} { %0 = llvm.mlir.constant(1 : i64) : i64 @@ -16,7 +18,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec : vector<2xi64>, %5 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !llvm.ptr {name = "x"} omp.target map_entries(%5 -> %arg0 : !llvm.ptr) { %6 = llvm.mlir.constant(1 : i32) : i32 - llvm.intr.dbg.declare #var_x = %arg0 : !llvm.ptr loc(#loc2) + llvm.intr.dbg.declare #var_x1 = %arg0 : !llvm.ptr loc(#loc3) omp.parallel { %7 = llvm.load %arg0 : !llvm.ptr -> i32 %8 = llvm.add %7, %6 : i32 @@ -24,12 +26,14 @@ module attributes {dlti.dl_spec = #dlti.dl_spec : vector<2xi64>, omp.terminator } omp.terminator - } + } loc(#loc4) llvm.return } loc(#loc10) } #loc1 = loc("target.f90":1:7) #loc2 = loc("target.f90":3:18) +#loc3 = loc("target.f90":6:18) +#loc4 = loc(fused<#sp1>[#loc3]) #loc10 = loc(fused<#sp>[#loc1])