Skip to content

Commit 43a8b7b

Browse files
committedJan 16, 2017
[OpenMP] Refactor code that calls codegen for target regions on the device.
This patch refactors code that calls codegen for target regions. Currently the codebase only supports the 'target' directive. The patch pulls out common target processing code into a static function that can be called by codegen for any target directive. Reviewers: ABataev Differential Revision: https://reviews.llvm.org/D28752 llvm-svn: 292134
1 parent c29d5f1 commit 43a8b7b

File tree

3 files changed

+69
-54
lines changed

3 files changed

+69
-54
lines changed
 

‎clang/lib/CodeGen/CGOpenMPRuntime.cpp

+17-15
Original file line numberDiff line numberDiff line change
@@ -6099,17 +6099,18 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
60996099
if (!S)
61006100
return;
61016101

6102-
// If we find a OMP target directive, codegen the outline function and
6103-
// register the result.
6104-
// FIXME: Add other directives with target when they become supported.
6105-
bool isTargetDirective = isa<OMPTargetDirective>(S);
6106-
6107-
if (isTargetDirective) {
6108-
auto *E = cast<OMPExecutableDirective>(S);
6102+
// Codegen OMP target directives that offload compute to the device.
6103+
bool requiresDeviceCodegen =
6104+
isa<OMPExecutableDirective>(S) &&
6105+
isOpenMPTargetExecutionDirective(
6106+
cast<OMPExecutableDirective>(S)->getDirectiveKind());
6107+
6108+
if (requiresDeviceCodegen) {
6109+
auto &E = *cast<OMPExecutableDirective>(S);
61096110
unsigned DeviceID;
61106111
unsigned FileID;
61116112
unsigned Line;
6112-
getTargetEntryUniqueInfo(CGM.getContext(), E->getLocStart(), DeviceID,
6113+
getTargetEntryUniqueInfo(CGM.getContext(), E.getLocStart(), DeviceID,
61136114
FileID, Line);
61146115

61156116
// Is this a target region that should not be emitted as an entry point? If
@@ -6118,13 +6119,14 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
61186119
ParentName, Line))
61196120
return;
61206121

6121-
llvm::Function *Fn;
6122-
llvm::Constant *Addr;
6123-
std::tie(Fn, Addr) =
6124-
CodeGenFunction::EmitOMPTargetDirectiveOutlinedFunction(
6125-
CGM, cast<OMPTargetDirective>(*E), ParentName,
6126-
/*isOffloadEntry=*/true);
6127-
assert(Fn && Addr && "Target region emission failed.");
6122+
switch (S->getStmtClass()) {
6123+
case Stmt::OMPTargetDirectiveClass:
6124+
CodeGenFunction::EmitOMPTargetDeviceFunction(
6125+
CGM, ParentName, cast<OMPTargetDirective>(*S));
6126+
break;
6127+
default:
6128+
llvm_unreachable("Unknown target directive for OpenMP device codegen.");
6129+
}
61286130
return;
61296131
}
61306132

‎clang/lib/CodeGen/CGStmtOpenMP.cpp

+48-32
Original file line numberDiff line numberDiff line change
@@ -3403,32 +3403,15 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
34033403
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen);
34043404
}
34053405

3406-
std::pair<llvm::Function * /*OutlinedFn*/, llvm::Constant * /*OutlinedFnID*/>
3407-
CodeGenFunction::EmitOMPTargetDirectiveOutlinedFunction(
3408-
CodeGenModule &CGM, const OMPTargetDirective &S, StringRef ParentName,
3409-
bool IsOffloadEntry) {
3410-
llvm::Function *OutlinedFn = nullptr;
3411-
llvm::Constant *OutlinedFnID = nullptr;
3412-
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3413-
OMPPrivateScope PrivateScope(CGF);
3414-
(void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
3415-
CGF.EmitOMPPrivateClause(S, PrivateScope);
3416-
(void)PrivateScope.Privatize();
3417-
3418-
Action.Enter(CGF);
3419-
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
3420-
};
3421-
// Emit target region as a standalone region.
3422-
CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
3423-
S, ParentName, OutlinedFn, OutlinedFnID, IsOffloadEntry, CodeGen);
3424-
return std::make_pair(OutlinedFn, OutlinedFnID);
3425-
}
3426-
3427-
void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
3406+
static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
3407+
const OMPExecutableDirective &S,
3408+
const RegionCodeGenTy &CodeGen) {
3409+
assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind()));
3410+
CodeGenModule &CGM = CGF.CGM;
34283411
const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt());
34293412

34303413
llvm::SmallVector<llvm::Value *, 16> CapturedVars;
3431-
GenerateOpenMPCapturedVars(CS, CapturedVars);
3414+
CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
34323415

34333416
llvm::Function *Fn = nullptr;
34343417
llvm::Constant *FnID = nullptr;
@@ -3452,31 +3435,64 @@ void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
34523435
bool IsOffloadEntry = true;
34533436
if (IfCond) {
34543437
bool Val;
3455-
if (ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
3438+
if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
34563439
IsOffloadEntry = false;
34573440
}
34583441
if (CGM.getLangOpts().OMPTargetTriples.empty())
34593442
IsOffloadEntry = false;
34603443

3461-
assert(CurFuncDecl && "No parent declaration for target region!");
3444+
assert(CGF.CurFuncDecl && "No parent declaration for target region!");
34623445
StringRef ParentName;
34633446
// In case we have Ctors/Dtors we use the complete type variant to produce
34643447
// the mangling of the device outlined kernel.
3465-
if (auto *D = dyn_cast<CXXConstructorDecl>(CurFuncDecl))
3448+
if (auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl))
34663449
ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete));
3467-
else if (auto *D = dyn_cast<CXXDestructorDecl>(CurFuncDecl))
3450+
else if (auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl))
34683451
ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete));
34693452
else
34703453
ParentName =
3471-
CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CurFuncDecl)));
3454+
CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl)));
34723455

3473-
std::tie(Fn, FnID) = EmitOMPTargetDirectiveOutlinedFunction(
3474-
CGM, S, ParentName, IsOffloadEntry);
3475-
OMPLexicalScope Scope(*this, S);
3476-
CGM.getOpenMPRuntime().emitTargetCall(*this, S, Fn, FnID, IfCond, Device,
3456+
// Emit target region as a standalone region.
3457+
CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
3458+
IsOffloadEntry, CodeGen);
3459+
OMPLexicalScope Scope(CGF, S);
3460+
CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device,
34773461
CapturedVars);
34783462
}
34793463

3464+
static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S,
3465+
PrePostActionTy &Action) {
3466+
CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
3467+
(void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
3468+
CGF.EmitOMPPrivateClause(S, PrivateScope);
3469+
(void)PrivateScope.Privatize();
3470+
3471+
Action.Enter(CGF);
3472+
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
3473+
}
3474+
3475+
void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
3476+
StringRef ParentName,
3477+
const OMPTargetDirective &S) {
3478+
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3479+
emitTargetRegion(CGF, S, Action);
3480+
};
3481+
llvm::Function *Fn;
3482+
llvm::Constant *Addr;
3483+
// Emit target region as a standalone region.
3484+
CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
3485+
S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
3486+
assert(Fn && Addr && "Target device function emission failed.");
3487+
}
3488+
3489+
void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
3490+
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
3491+
emitTargetRegion(CGF, S, Action);
3492+
};
3493+
emitCommonOMPTargetDirective(*this, S, CodeGen);
3494+
}
3495+
34803496
static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
34813497
const OMPExecutableDirective &S,
34823498
OpenMPDirectiveKind InnermostKind,

‎clang/lib/CodeGen/CodeGenFunction.h

+4-7
Original file line numberDiff line numberDiff line change
@@ -2704,13 +2704,10 @@ class CodeGenFunction : public CodeGenTypeCache {
27042704
void EmitOMPTargetTeamsDistributeSimdDirective(
27052705
const OMPTargetTeamsDistributeSimdDirective &S);
27062706

2707-
/// Emit outlined function for the target directive.
2708-
static std::pair<llvm::Function * /*OutlinedFn*/,
2709-
llvm::Constant * /*OutlinedFnID*/>
2710-
EmitOMPTargetDirectiveOutlinedFunction(CodeGenModule &CGM,
2711-
const OMPTargetDirective &S,
2712-
StringRef ParentName,
2713-
bool IsOffloadEntry);
2707+
/// Emit device code for the target directive.
2708+
static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
2709+
StringRef ParentName,
2710+
const OMPTargetDirective &S);
27142711
/// \brief Emit inner loop of the worksharing/simd construct.
27152712
///
27162713
/// \param S Directive, for which the inner loop must be emitted.

0 commit comments

Comments
 (0)
Please sign in to comment.