summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGStmtOpenMP.cpp
diff options
context:
space:
mode:
authorSamuel Antao <sfantao@us.ibm.com>2015-10-02 16:14:20 +0000
committerSamuel Antao <sfantao@us.ibm.com>2015-10-02 16:14:20 +0000
commitbed3c466326cffd992bf7570246ea71259b46871 (patch)
treee6f4a3332bad4e94a89e94f7af7722cc5a2f031b /clang/lib/CodeGen/CGStmtOpenMP.cpp
parent77f62652c1f0f755c335efd9ce578891c3a552e7 (diff)
downloadbcm5719-llvm-bed3c466326cffd992bf7570246ea71259b46871.tar.gz
bcm5719-llvm-bed3c466326cffd992bf7570246ea71259b46871.zip
[OpenMP] Target directive host codegen.
This patch implements the outlining for offloading functions for code annotated with the OpenMP target directive. It uses a temporary naming of the outlined functions that will have to be updated later on once target side codegen and registration of offloading libraries is implemented - the naming needs to be made unique in the produced library. llvm-svn: 249148
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp57
1 files changed, 52 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 45fa610b314..cf54d0ee453 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -21,7 +21,8 @@ using namespace clang;
using namespace CodeGen;
void CodeGenFunction::GenerateOpenMPCapturedVars(
- const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {
+ const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars,
+ bool UseOnlyReferences) {
const RecordDecl *RD = S.getCapturedRecordDecl();
auto CurField = RD->field_begin();
auto CurCap = S.captures().begin();
@@ -30,7 +31,17 @@ void CodeGenFunction::GenerateOpenMPCapturedVars(
I != E; ++I, ++CurField, ++CurCap) {
if (CurField->hasCapturedVLAType()) {
auto VAT = CurField->getCapturedVLAType();
- CapturedVars.push_back(VLASizeMap[VAT->getSizeExpr()]);
+ auto *Val = VLASizeMap[VAT->getSizeExpr()];
+ // If we need to use only references, create a temporary location for the
+ // size of the VAT.
+ if (UseOnlyReferences) {
+ LValue LV =
+ MakeAddrLValue(CreateMemTemp(CurField->getType(), "__vla_size_ref"),
+ CurField->getType());
+ EmitStoreThroughLValue(RValue::get(Val), LV);
+ Val = LV.getAddress().getPointer();
+ }
+ CapturedVars.push_back(Val);
} else if (CurCap->capturesThis())
CapturedVars.push_back(CXXThisValue);
else
@@ -39,7 +50,8 @@ void CodeGenFunction::GenerateOpenMPCapturedVars(
}
llvm::Function *
-CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
+CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
+ bool UseOnlyReferences) {
assert(
CapturedStmtInfo &&
"CapturedStmtInfo should be set when generating the captured function");
@@ -65,6 +77,9 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
else {
assert(I->capturesVariableArrayType());
II = &getContext().Idents.get("vla");
+ if (UseOnlyReferences)
+ ArgType = getContext().getLValueReferenceType(
+ ArgType, /*SpelledAsLValue=*/false);
}
if (ArgType->isVariablyModifiedType())
ArgType = getContext().getVariableArrayDecayedType(ArgType);
@@ -100,6 +115,9 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
MakeAddrLValue(GetAddrOfLocalVar(Args[Cnt]), Args[Cnt]->getType(),
AlignmentSource::Decl);
if (FD->hasCapturedVLAType()) {
+ if (UseOnlyReferences)
+ ArgLVal = EmitLoadOfReferenceLValue(
+ ArgLVal.getAddress(), ArgLVal.getType()->castAs<ReferenceType>());
auto *ExprArg =
EmitLoadOfLValue(ArgLVal, SourceLocation()).getScalarVal();
auto VAT = FD->getCapturedVLAType();
@@ -2269,8 +2287,37 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen);
}
-void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) {
- llvm_unreachable("CodeGen for 'omp target' is not supported yet.");
+void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
+ LexicalScope Scope(*this, S.getSourceRange());
+ const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt());
+
+ llvm::SmallVector<llvm::Value *, 16> CapturedVars;
+ GenerateOpenMPCapturedVars(CS, CapturedVars, /*UseOnlyReferences=*/true);
+
+ // Emit target region as a standalone region.
+ auto &&CodeGen = [&CS](CodeGenFunction &CGF) {
+ CGF.EmitStmt(CS.getCapturedStmt());
+ };
+
+ // Obtain the target region outlined function.
+ llvm::Value *Fn =
+ CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, CodeGen);
+
+ // Check if we have any if clause associated with the directive.
+ const Expr *IfCond = nullptr;
+
+ if (auto *C = S.getSingleClause<OMPIfClause>()) {
+ IfCond = C->getCondition();
+ }
+
+ // Check if we have any device clause associated with the directive.
+ const Expr *Device = nullptr;
+ if (auto *C = S.getSingleClause<OMPDeviceClause>()) {
+ Device = C->getDevice();
+ }
+
+ CGM.getOpenMPRuntime().emitTargetCall(*this, S, Fn, IfCond, Device,
+ CapturedVars);
}
void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {
OpenPOWER on IntegriCloud