Skip to content

Commit 8de9edd

Browse files
committed
[flang][OMPIRBuilder] Improve debug info for AMDGPU target.
This PR builds on PR#118314 and PR#125692 which enable the debugging of variables in the OpenMP target region. This PR adds the following changes so that usable debug info comes out of amdgpu backend. 1. Add DIOp based expressions. 2. Use alloca as location of the variable in debug record. Regarding 2nd point, OMPIRBuilder creates a function to implement target construct. The variable that are mapped are passed as argument to it. The argument handling code adds alloca+store+load for the arguments which are mapped by reference. It was observed that if the argument* is used as location of variable in debug record (directly or when it is result of LoadInst), the debug information is dropped for that variable. Thing work ok if the location of the alloca is used instead.
1 parent 9cc1545 commit 8de9edd

File tree

3 files changed

+94
-9
lines changed

3 files changed

+94
-9
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
! RUN: %flang_fc1 -triple amdgcn-amd-amdhsa -emit-llvm -fopenmp -fopenmp-is-target-device -debug-info-kind=standalone %s -o - | FileCheck %s
2+
3+
subroutine fff(x, y)
4+
implicit none
5+
integer :: y(:)
6+
integer :: x
7+
8+
!$omp target map(tofrom: x) map(tofrom: y)
9+
x = 5
10+
y = 10
11+
!$omp end target
12+
13+
end subroutine fff
14+
15+
!CHECK: define{{.*}}amdgpu_kernel void @[[FN:[0-9a-zA_Z_]+]]({{.*}}){{.*}}!dbg ![[SP:[0-9]+]]
16+
!CHECK: #dbg_declare({{.*}}, ![[X:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr), DIOpDeref(ptr)), {{.*}})
17+
!CHECK: #dbg_declare({{.*}}, ![[Y:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr), DIOpDeref(ptr)), {{.*}})
18+
!CHECK: }
19+
20+
! CHECK-DAG: ![[SP]] = {{.*}}!DISubprogram(name: "[[FN]]"{{.*}})
21+
! CHECK-DAG: ![[X]] = !DILocalVariable(name: "x", arg: 2, scope: ![[SP]]{{.*}}type: ![[INT:[0-9]+]])
22+
! CHECK-DAG: ![[INT]] = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed)
23+
! CHECK-DAG: ![[Y]] = !DILocalVariable(name: "y", arg: 3, scope: ![[SP]]{{.*}}type: ![[ARR:[0-9]+]])
24+
! CHECK-DAG: ![[ARR]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[INT]]{{.*}})

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6994,7 +6994,6 @@ static void FixupDebugInfoForOutlinedFunction(
69946994
SmallDenseMap<DILocalVariable *, DILocalVariable *> RemappedVariables;
69956995

69966996
auto GetUpdatedDIVariable = [&](DILocalVariable *OldVar, unsigned arg) {
6997-
auto NewSP = Func->getSubprogram();
69986997
DILocalVariable *&NewVar = RemappedVariables[OldVar];
69996998
// Only use cached variable if the arg number matches. This is important
70006999
// so that DIVariable created for privatized variables are not discarded.
@@ -7006,8 +7005,8 @@ static void FixupDebugInfoForOutlinedFunction(
70067005
NewVar = llvm::DILocalVariable::get(
70077006
Builder.getContext(), NewScope, OldVar->getName(), OldVar->getFile(),
70087007
OldVar->getLine(), OldVar->getType(), arg, OldVar->getFlags(),
7009-
llvm::dwarf::DW_MSPACE_LLVM_none,
7010-
OldVar->getAlignInBits(), OldVar->getAnnotations());
7008+
OldVar->getDWARFMemorySpace(), OldVar->getAlignInBits(),
7009+
OldVar->getAnnotations());
70117010
return NewVar;
70127011
};
70137012

@@ -7021,6 +7020,53 @@ static void FixupDebugInfoForOutlinedFunction(
70217020
ArgNo = std::get<1>(Iter->second) + 1;
70227021
}
70237022
}
7023+
7024+
Module *M = Func->getParent();
7025+
if ((Triple(M->getTargetTriple())).isAMDGPU()) {
7026+
// For target side, the ArgAccessorFuncCB/createDeviceArgumentAccessor
7027+
// adds following for the kenel arguments.
7028+
// %3 = alloca ptr, align 8, addrspace(5), !dbg !26
7029+
// %4 = addrspacecast ptr addrspace(5) %3 to ptr, !dbg !26
7030+
// store ptr %1, ptr %4, align 8, !dbg !26
7031+
7032+
// For arguments that are passed by ref, there is an extra load like the
7033+
// following.
7034+
// %8 = load ptr, ptr %4, align 8
7035+
//
7036+
// The debug record at this moment may be pointing to %8 (in above
7037+
// snippet) as location of variable. The AMDGPU backend drops the debug
7038+
// info for variable in such cases. So we change the location to alloca
7039+
// instead.
7040+
bool passByRef = false;
7041+
llvm::Type *locType = nullptr;
7042+
for (auto Loc : DR->location_ops()) {
7043+
locType = Loc->getType();
7044+
if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(Loc)) {
7045+
DR->replaceVariableLocationOp(Loc, Load->getPointerOperand());
7046+
passByRef = true;
7047+
}
7048+
}
7049+
// Add DIOps based expression. Note that we generate an extra indirection
7050+
// if an argument is mapped by reference. The first reads the pointer
7051+
// from alloca and 2nd read the value of the variable from that pointer.
7052+
llvm::DIExprBuilder ExprBuilder(Builder.getContext());
7053+
unsigned int allocaAS = M->getDataLayout().getAllocaAddrSpace();
7054+
unsigned int defaultAS = M->getDataLayout().getProgramAddressSpace();
7055+
ExprBuilder.append<llvm::DIOp::Arg>(0u, Builder.getPtrTy(allocaAS));
7056+
// We have 2 options for the variables that are mapped byRef.
7057+
// 1. Use a single indirection but change the type to the reference to the
7058+
// original type. It will show up in the debugger as
7059+
// "x=@0x7ffeec820000: 5"
7060+
// This is similar to what clang does.
7061+
// 2. Use double indirection and keep the original type. It will show up
7062+
// in debugger as "x=5". This approached is used here as it is
7063+
// consisten with the normal fortran parameters display.
7064+
if (passByRef)
7065+
ExprBuilder.append<llvm::DIOp::Deref>(Builder.getPtrTy(defaultAS));
7066+
ExprBuilder.append<llvm::DIOp::Deref>(locType);
7067+
DR->setExpression(ExprBuilder.intoExpression());
7068+
}
7069+
70247070
DR->setVariable(GetUpdatedDIVariable(OldVar, ArgNo));
70257071
};
70267072

mlir/test/Target/LLVMIR/omptarget-debug-var-1.mlir

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#var_x = #llvm.di_local_variable<scope = #sp,
2727
name = "x", file = #file, line = 12, type = #real_ty>
2828

29-
module attributes {llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_target_device = true} {
29+
module attributes {llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_target_device = true, dlti.dl_spec = #dlti.dl_spec<"dlti.alloca_memory_space" = 5 : ui64>} {
3030
llvm.func @test() {
3131
%0 = llvm.mlir.constant(1 : i64) : i64
3232
%1 = llvm.alloca %0 x f32 : (i64) -> !llvm.ptr
@@ -56,8 +56,23 @@ module attributes {llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_target_devic
5656
#loc3 = loc(fused<#sp>[#loc2])
5757
#loc4 = loc(fused<#g_var>[#loc1])
5858

59-
// CHECK: ![[SP:[0-9]+]] = distinct !DISubprogram(name: "__omp_offloading{{.*}}test{{.*}})
60-
// CHECK: !DILocalVariable(name: "dyn_ptr", arg: 1, scope: ![[SP]]{{.*}}flags: DIFlagArtificial)
61-
// CHECK: !DILocalVariable(name: "x", arg: 2, scope: ![[SP]]{{.*}})
62-
// CHECK: !DILocalVariable(name: "arr", arg: 3, scope: ![[SP]]{{.*}})
63-
// CHECK: !DILocalVariable(name: "i", arg: 4, scope: ![[SP]]{{.*}})
59+
// CHECK: define{{.*}}@__omp_offloading{{.*}}test{{.*}}(ptr %0, ptr %[[ARG1:[0-9]+]], ptr %[[ARG2:[0-9]+]], ptr %[[ARG3:[0-9]+]])
60+
// CHECK-DAG: store ptr %[[ARG1]], ptr %[[CAST1:[0-9]+]]{{.*}}
61+
// CHECK-DAG: %[[CAST1]] = addrspacecast ptr addrspace(5) %[[AL1:[0-9]+]]
62+
// CHECK-DAG: %[[AL1]] = alloca{{.*}}
63+
// CHECK-DAG: store ptr %[[ARG2]], ptr %[[CAST2:[0-9]+]]{{.*}}
64+
// CHECK-DAG: %[[CAST2]] = addrspacecast ptr addrspace(5) %[[AL2:[0-9]+]]
65+
// CHECK-DAG: %[[AL2]] = alloca{{.*}}
66+
// CHECK-DAG: store ptr %[[ARG3]], ptr %[[CAST3:[0-9]+]]{{.*}}
67+
// CHECK-DAG: %[[CAST3]] = addrspacecast ptr addrspace(5) %[[AL3:[0-9]+]]
68+
// CHECK-DAG: %[[AL3]] = alloca{{.*}}
69+
70+
// CHECK-DAG: #dbg_declare(ptr %[[CAST1]], ![[X:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr), DIOpDeref(ptr)), {{.*}})
71+
// CHECK-DAG: #dbg_declare(ptr %[[CAST2]], ![[ARR:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr), DIOpDeref(ptr)), {{.*}})
72+
// CHECK-DAG: #dbg_declare(ptr %[[CAST3]], ![[I:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr)), {{.*}})
73+
74+
// CHECK-DAG: ![[SP:[0-9]+]] = distinct !DISubprogram(name: "__omp_offloading{{.*}}test{{.*}})
75+
// CHECK-DAG: !DILocalVariable(name: "dyn_ptr", arg: 1, scope: ![[SP]]{{.*}}flags: DIFlagArtificial)
76+
// CHECK-DAG: ![[X:[0-9]+]] = !DILocalVariable(name: "x", arg: 2, scope: ![[SP]]{{.*}})
77+
// CHECK-DAG: ![[ARR:[0-9]+]] = !DILocalVariable(name: "arr", arg: 3, scope: ![[SP]]{{.*}})
78+
// CHECK-DAG: ![[I:[0-9]+]] = !DILocalVariable(name: "i", arg: 4, scope: ![[SP]]{{.*}})

0 commit comments

Comments
 (0)