summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2018-03-15 15:47:20 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2018-03-15 15:47:20 +0000
commit4f4bf7c3482598c02bea7fbe9bbcca56ac720313 (patch)
tree9d22d71fca84678cbb814b489d172fb2d714b35d /clang/lib/CodeGen
parent1110c4d33675f4351c080e621dbf8ee298ef13ae (diff)
downloadbcm5719-llvm-4f4bf7c3482598c02bea7fbe9bbcca56ac720313.tar.gz
bcm5719-llvm-4f4bf7c3482598c02bea7fbe9bbcca56ac720313.zip
[OPENMP] Codegen for `omp declare target` construct.
Added initial codegen for device side of declarations inside `omp declare target` construct + codegen for implicit `declare target` functions, which are used in the target regions. llvm-svn: 327636
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp5
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp54
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.h20
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp10
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp12
5 files changed, 95 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index d499d3a4798..790db1a7bf0 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -285,8 +285,11 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
// never defer them.
assert(isa<ObjCMethodDecl>(DC) && "unexpected parent code decl");
}
- if (GD.getDecl())
+ if (GD.getDecl()) {
+ // Disable emission of the parent function for the OpenMP device codegen.
+ CGOpenMPRuntime::DisableAutoDeclareTargetRAII NoDeclTarget(*this);
(void)GetAddrOfGlobal(GD);
+ }
return Addr;
}
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 8c25d206f49..6bbe639f908 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -7405,9 +7405,14 @@ bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
// Try to detect target regions in the function.
scanForTargetRegionsFunctions(FD.getBody(), CGM.getMangledName(GD));
- // We should not emit any function other that the ones created during the
- // scanning. Therefore, we signal that this function is completely dealt
- // with.
+ // Do not to emit function if it is not marked as declare target.
+ if (!GD.getDecl()->hasAttrs())
+ return true;
+
+ for (const auto *D = FD.getMostRecentDecl(); D; D = D->getPreviousDecl())
+ if (D->hasAttr<OMPDeclareTargetDeclAttr>())
+ return false;
+
return true;
}
@@ -7433,8 +7438,15 @@ bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
}
}
- // If we are in target mode, we do not emit any global (declare target is not
- // implemented yet). Therefore we signal that GD was processed in this case.
+ // Do not to emit variable if it is not marked as declare target.
+ if (!GD.getDecl()->hasAttrs())
+ return true;
+
+ for (const Decl *D = GD.getDecl()->getMostRecentDecl(); D;
+ D = D->getPreviousDecl())
+ if (D->hasAttr<OMPDeclareTargetDeclAttr>())
+ return false;
+
return true;
}
@@ -7446,6 +7458,38 @@ bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {
return emitTargetGlobalVariable(GD);
}
+CGOpenMPRuntime::DisableAutoDeclareTargetRAII::DisableAutoDeclareTargetRAII(
+ CodeGenModule &CGM)
+ : CGM(CGM) {
+ if (CGM.getLangOpts().OpenMPIsDevice) {
+ SavedShouldMarkAsGlobal = CGM.getOpenMPRuntime().ShouldMarkAsGlobal;
+ CGM.getOpenMPRuntime().ShouldMarkAsGlobal = false;
+ }
+}
+
+CGOpenMPRuntime::DisableAutoDeclareTargetRAII::~DisableAutoDeclareTargetRAII() {
+ if (CGM.getLangOpts().OpenMPIsDevice)
+ CGM.getOpenMPRuntime().ShouldMarkAsGlobal = SavedShouldMarkAsGlobal;
+}
+
+bool CGOpenMPRuntime::markAsGlobalTarget(const FunctionDecl *D) {
+ if (!CGM.getLangOpts().OpenMPIsDevice || !ShouldMarkAsGlobal)
+ return true;
+ // Do not to emit function if it is marked as declare target as it was already
+ // emitted.
+ for (const auto *FD = D->getMostRecentDecl(); FD; FD = FD->getPreviousDecl())
+ if (FD->hasAttr<OMPDeclareTargetDeclAttr>())
+ return true;
+
+ const FunctionDecl *FD = D->getCanonicalDecl();
+ // Do not mark member functions except for static.
+ if (const auto *Method = dyn_cast<CXXMethodDecl>(FD))
+ if (!Method->isStatic())
+ return true;
+
+ return !AlreadyEmittedTargetFunctions.insert(FD).second;
+}
+
llvm::Function *CGOpenMPRuntime::emitRegistrationFunction() {
// If we have offloading in the current module, we need to emit the entries
// now and register the offloading descriptor.
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index 0f18d13296f..410241b6189 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -199,6 +199,18 @@ public:
};
class CGOpenMPRuntime {
+public:
+ /// Allows to disable automatic handling of functions used in target regions
+ /// as those marked as `omp declare target`.
+ class DisableAutoDeclareTargetRAII {
+ CodeGenModule &CGM;
+ bool SavedShouldMarkAsGlobal;
+
+ public:
+ DisableAutoDeclareTargetRAII(CodeGenModule &CGM);
+ ~DisableAutoDeclareTargetRAII();
+ };
+
protected:
CodeGenModule &CGM;
@@ -488,6 +500,9 @@ private:
};
OffloadEntriesInfoManagerTy OffloadEntriesInfoManager;
+ bool ShouldMarkAsGlobal = true;
+ llvm::SmallDenseSet<const FunctionDecl *> AlreadyEmittedTargetFunctions;
+
/// \brief Creates and registers offloading binary descriptor for the current
/// compilation unit. The function that does the registration is returned.
llvm::Function *createOffloadingBinaryDescriptorRegistration();
@@ -1370,6 +1385,11 @@ public:
/// Gets the OpenMP-specific address of the local variable.
virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF,
const VarDecl *VD);
+
+ /// Marks the declaration as alread emitted for the device code and returns
+ /// true, if it was marked already, and false, otherwise.
+ bool markAsGlobalTarget(const FunctionDecl *D);
+
};
/// Class supports emissionof SIMD-only code.
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 7d2093bdf60..9d077a2be16 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -3914,6 +3914,16 @@ static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind()));
CodeGenModule &CGM = CGF.CGM;
+ // On device emit this construct as inlined code.
+ if (CGM.getLangOpts().OpenMPIsDevice) {
+ OMPLexicalScope Scope(CGF, S, OMPD_target);
+ CGM.getOpenMPRuntime().emitInlinedDirective(
+ CGF, OMPD_target, [&S](CodeGenFunction &CGF, PrePostActionTy &) {
+ CGF.EmitStmt(S.getCapturedStmt(OMPD_target)->getCapturedStmt());
+ });
+ return;
+ }
+
llvm::Function *Fn = nullptr;
llvm::Constant *FnID = nullptr;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index e75780a0a93..3c503eb66fa 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2383,6 +2383,12 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
// Any attempts to use a MultiVersion function should result in retrieving
// the iFunc instead. Name Mangling will handle the rest of the changes.
if (const FunctionDecl *FD = cast_or_null<FunctionDecl>(D)) {
+ // For the device mark the function as one that should be emitted.
+ if (getLangOpts().OpenMPIsDevice && OpenMPRuntime &&
+ !OpenMPRuntime->markAsGlobalTarget(FD) && FD->isDefined() &&
+ !DontDefer && !IsForDefinition)
+ addDeferredDeclToEmit(GD);
+
if (FD->isMultiVersion() && FD->getAttr<TargetAttr>()->isDefaultVersion()) {
UpdateMultiVersionNames(GD, FD);
if (!IsForDefinition)
@@ -3072,6 +3078,12 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
if (getLangOpts().OpenCL && ASTTy->isSamplerT())
return;
+ // If this is OpenMP device, check if it is legal to emit this global
+ // normally.
+ if (LangOpts.OpenMPIsDevice && OpenMPRuntime &&
+ OpenMPRuntime->emitTargetGlobalVariable(D))
+ return;
+
llvm::Constant *Init = nullptr;
CXXRecordDecl *RD = ASTTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
bool NeedsGlobalCtor = false;
OpenPOWER on IntegriCloud