[OPENMP]Improve debug locations in OpenMP regions.

Emit more precise debug locations for the OpenMP outlined regions.
This commit is contained in:
Alexey Bataev 2020-01-17 14:05:40 -05:00
parent fe085be125
commit c33ba8c158
4 changed files with 44 additions and 36 deletions

View File

@ -1517,7 +1517,7 @@ static llvm::Function *emitParallelOrTeamsOutlinedFunction(
CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind, CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
HasCancel, OutlinedHelperName); HasCancel, OutlinedHelperName);
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo); CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
return CGF.GenerateOpenMPCapturedStmtFunction(*CS); return CGF.GenerateOpenMPCapturedStmtFunction(*CS, D.getBeginLoc());
} }
llvm::Function *CGOpenMPRuntime::emitParallelOutlinedFunction( llvm::Function *CGOpenMPRuntime::emitParallelOutlinedFunction(
@ -3772,6 +3772,7 @@ void CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF,
llvm::Value *ThreadId = getThreadID(CGF, Loc); llvm::Value *ThreadId = getThreadID(CGF, Loc);
llvm::FunctionCallee StaticInitFunction = llvm::FunctionCallee StaticInitFunction =
createForStaticInitFunction(Values.IVSize, Values.IVSigned); createForStaticInitFunction(Values.IVSize, Values.IVSigned);
auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction, emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, Values); ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, Values);
} }
@ -3806,6 +3807,7 @@ void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF,
? OMP_IDENT_WORK_LOOP ? OMP_IDENT_WORK_LOOP
: OMP_IDENT_WORK_SECTIONS), : OMP_IDENT_WORK_SECTIONS),
getThreadID(CGF, Loc)}; getThreadID(CGF, Loc)};
auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini), CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini),
Args); Args);
} }
@ -6484,7 +6486,7 @@ void CGOpenMPRuntime::emitTargetOutlinedFunctionHelper(
CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName); CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo); CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
OutlinedFn = CGF.GenerateOpenMPCapturedStmtFunction(CS); OutlinedFn = CGF.GenerateOpenMPCapturedStmtFunction(CS, D.getBeginLoc());
// If this target outline function is not an offload entry, we don't need to // If this target outline function is not an offload entry, we don't need to
// register it. // register it.

View File

@ -365,26 +365,28 @@ static QualType getCanonicalParamType(ASTContext &C, QualType T) {
} }
namespace { namespace {
/// Contains required data for proper outlined function codegen. /// Contains required data for proper outlined function codegen.
struct FunctionOptions { struct FunctionOptions {
/// Captured statement for which the function is generated. /// Captured statement for which the function is generated.
const CapturedStmt *S = nullptr; const CapturedStmt *S = nullptr;
/// true if cast to/from UIntPtr is required for variables captured by /// true if cast to/from UIntPtr is required for variables captured by
/// value. /// value.
const bool UIntPtrCastRequired = true; const bool UIntPtrCastRequired = true;
/// true if only casted arguments must be registered as local args or VLA /// true if only casted arguments must be registered as local args or VLA
/// sizes. /// sizes.
const bool RegisterCastedArgsOnly = false; const bool RegisterCastedArgsOnly = false;
/// Name of the generated function. /// Name of the generated function.
const StringRef FunctionName; const StringRef FunctionName;
explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired, /// Location of the non-debug version of the outlined function.
bool RegisterCastedArgsOnly, SourceLocation Loc;
StringRef FunctionName) explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired,
: S(S), UIntPtrCastRequired(UIntPtrCastRequired), bool RegisterCastedArgsOnly, StringRef FunctionName,
RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly), SourceLocation Loc)
FunctionName(FunctionName) {} : S(S), UIntPtrCastRequired(UIntPtrCastRequired),
}; RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
} FunctionName(FunctionName), Loc(Loc) {}
};
} // namespace
static llvm::Function *emitOutlinedFunctionPrologue( static llvm::Function *emitOutlinedFunctionPrologue(
CodeGenFunction &CGF, FunctionArgList &Args, CodeGenFunction &CGF, FunctionArgList &Args,
@ -485,7 +487,9 @@ static llvm::Function *emitOutlinedFunctionPrologue(
// Generate the function. // Generate the function.
CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs, CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs,
FO.S->getBeginLoc(), CD->getBody()->getBeginLoc()); FO.UIntPtrCastRequired ? FO.Loc : FO.S->getBeginLoc(),
FO.UIntPtrCastRequired ? FO.Loc
: CD->getBody()->getBeginLoc());
unsigned Cnt = CD->getContextParamPosition(); unsigned Cnt = CD->getContextParamPosition();
I = FO.S->captures().begin(); I = FO.S->captures().begin();
for (const FieldDecl *FD : RD->fields()) { for (const FieldDecl *FD : RD->fields()) {
@ -560,7 +564,8 @@ static llvm::Function *emitOutlinedFunctionPrologue(
} }
llvm::Function * llvm::Function *
CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) { CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
SourceLocation Loc) {
assert( assert(
CapturedStmtInfo && CapturedStmtInfo &&
"CapturedStmtInfo should be set when generating the captured function"); "CapturedStmtInfo should be set when generating the captured function");
@ -577,7 +582,7 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
if (NeedWrapperFunction) if (NeedWrapperFunction)
Out << "_debug__"; Out << "_debug__";
FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false, FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false,
Out.str()); Out.str(), Loc);
llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs, llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs,
VLASizes, CXXThisValue, FO); VLASizes, CXXThisValue, FO);
CodeGenFunction::OMPPrivateScope LocalScope(*this); CodeGenFunction::OMPPrivateScope LocalScope(*this);
@ -600,7 +605,7 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true, FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true,
/*RegisterCastedArgsOnly=*/true, /*RegisterCastedArgsOnly=*/true,
CapturedStmtInfo->getHelperName()); CapturedStmtInfo->getHelperName(), Loc);
CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true); CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true);
WrapperCGF.CapturedStmtInfo = CapturedStmtInfo; WrapperCGF.CapturedStmtInfo = CapturedStmtInfo;
Args.clear(); Args.clear();
@ -632,8 +637,7 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
} }
CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType())); CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType()));
} }
CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, S.getBeginLoc(), CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, Loc, F, CallArgs);
F, CallArgs);
WrapperCGF.FinishFunction(); WrapperCGF.FinishFunction();
return WrapperF; return WrapperF;
} }
@ -3790,7 +3794,7 @@ void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
}); });
EmitBlock(LoopExit.getBlock()); EmitBlock(LoopExit.getBlock());
// Tell the runtime we are done. // Tell the runtime we are done.
RT.emitForStaticFinish(*this, S.getBeginLoc(), S.getDirectiveKind()); RT.emitForStaticFinish(*this, S.getEndLoc(), S.getDirectiveKind());
} else { } else {
// Emit the outer loop, which requests its work chunk [LB..UB] from // Emit the outer loop, which requests its work chunk [LB..UB] from
// runtime and runs the inner loop to process it. // runtime and runs the inner loop to process it.
@ -3843,11 +3847,12 @@ void CodeGenFunction::EmitOMPDistributeDirective(
} }
static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM, static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
const CapturedStmt *S) { const CapturedStmt *S,
SourceLocation Loc) {
CodeGenFunction CGF(CGM, /*suppressNewContext=*/true); CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
CodeGenFunction::CGCapturedStmtInfo CapStmtInfo; CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
CGF.CapturedStmtInfo = &CapStmtInfo; CGF.CapturedStmtInfo = &CapStmtInfo;
llvm::Function *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S); llvm::Function *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S, Loc);
Fn->setDoesNotRecurse(); Fn->setDoesNotRecurse();
return Fn; return Fn;
} }
@ -3867,7 +3872,8 @@ void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
if (C) { if (C) {
llvm::SmallVector<llvm::Value *, 16> CapturedVars; llvm::SmallVector<llvm::Value *, 16> CapturedVars;
CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
llvm::Function *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS); llvm::Function *OutlinedFn =
emitOutlinedOrderedFunction(CGM, CS, S.getBeginLoc());
CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(), CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(),
OutlinedFn, CapturedVars); OutlinedFn, CapturedVars);
} else { } else {

View File

@ -2983,7 +2983,8 @@ public:
llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K); llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S);
Address GenerateCapturedStmtArgument(const CapturedStmt &S); Address GenerateCapturedStmtArgument(const CapturedStmt &S);
llvm::Function *GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S); llvm::Function *GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
SourceLocation Loc);
void GenerateOpenMPCapturedVars(const CapturedStmt &S, void GenerateOpenMPCapturedVars(const CapturedStmt &S,
SmallVectorImpl<llvm::Value *> &CapturedVars); SmallVectorImpl<llvm::Value *> &CapturedVars);
void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy, void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy,

View File

@ -374,7 +374,7 @@ void parallel_for(float *a, const int n) {
// TERM_DEBUG: invoke i32 {{.*}}foo{{.*}}() // TERM_DEBUG: invoke i32 {{.*}}foo{{.*}}()
// TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]],
// TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG-NOT: __kmpc_global_thread_num
// TERM_DEBUG: call void @__kmpc_for_static_fini({{.+}}), !dbg [[DBG_LOC_END:![0-9]+]] // TERM_DEBUG: call void @__kmpc_for_static_fini({{.+}}), !dbg [[DBG_LOC_START]]
// TERM_DEBUG: [[TERM_LPAD]] // TERM_DEBUG: [[TERM_LPAD]]
// TERM_DEBUG: call void @__clang_call_terminate // TERM_DEBUG: call void @__clang_call_terminate
// TERM_DEBUG: unreachable // TERM_DEBUG: unreachable
@ -385,8 +385,7 @@ void parallel_for(float *a, const int n) {
a[i] += foo() + arr[i] + n; a[i] += foo() + arr[i] + n;
} }
// Check source line corresponds to "#pragma omp parallel for schedule(static, 5)" above: // Check source line corresponds to "#pragma omp parallel for schedule(static, 5)" above:
// TERM_DEBUG-DAG: [[DBG_LOC_START]] = !DILocation(line: [[@LINE-4]], // TERM_DEBUG-DAG: [[DBG_LOC_START]] = !DILocation(line: [[@LINE-17]],
// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !DILocation(line: [[@LINE-18]],
#else // OMP5 #else // OMP5
// OMP5-LABEL: increment // OMP5-LABEL: increment