diff options
author | Samuel Antao <sfantao@us.ibm.com> | 2015-10-02 16:14:20 +0000 |
---|---|---|
committer | Samuel Antao <sfantao@us.ibm.com> | 2015-10-02 16:14:20 +0000 |
commit | bed3c466326cffd992bf7570246ea71259b46871 (patch) | |
tree | e6f4a3332bad4e94a89e94f7af7722cc5a2f031b /clang/lib/CodeGen/CGStmtOpenMP.cpp | |
parent | 77f62652c1f0f755c335efd9ce578891c3a552e7 (diff) | |
download | bcm5719-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.cpp | 57 |
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 &) { |