diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 34 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 93 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.h | 111 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 119 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 146 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 9 |
10 files changed, 144 insertions, 401 deletions
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 0d039939bc0..af19af4943a 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -1198,31 +1198,19 @@ OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C, return new (Mem) OMPPrivateClause(N); } -void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) { - assert(VL.size() == varlist_size() && - "Number of private copies is not the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), varlist_end()); -} - -void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) { - assert(VL.size() == varlist_size() && - "Number of inits is not the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), getPrivateCopies().end()); -} - -OMPFirstprivateClause * -OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL, - ArrayRef<Expr *> InitVL) { +OMPFirstprivateClause *OMPFirstprivateClause::Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef<Expr *> VL) { void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause), llvm::alignOf<Expr *>()) + - 3 * sizeof(Expr *) * VL.size()); - OMPFirstprivateClause *Clause = - new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size()); + sizeof(Expr *) * VL.size()); + OMPFirstprivateClause *Clause = new (Mem) OMPFirstprivateClause(StartLoc, + LParenLoc, + EndLoc, + VL.size()); Clause->setVarRefs(VL); - Clause->setPrivateCopies(PrivateVL); - Clause->setInits(InitVL); return Clause; } @@ -1230,7 +1218,7 @@ OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C, unsigned N) { void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause), llvm::alignOf<Expr *>()) + - 3 * sizeof(Expr *) * N); + sizeof(Expr *) * N); return new (Mem) OMPFirstprivateClause(N); } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 157e21d069b..9bcb5929ed0 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -329,15 +329,9 @@ void OMPClauseProfiler::VisitOMPClauseList(T *Node) { void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) { VisitOMPClauseList(C); } -void -OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) { +void OMPClauseProfiler::VisitOMPFirstprivateClause( + const OMPFirstprivateClause *C) { VisitOMPClauseList(C); - for (auto *E : C->private_copies()) { - Profiler->VisitStmt(E); - } - for (auto *E : C->inits()) { - Profiler->VisitStmt(E); - } } void OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) { diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 24575ce6d41..d4a546dc112 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1073,7 +1073,7 @@ static bool isCapturedBy(const VarDecl &var, const Expr *e) { /// \brief Determine whether the given initializer is trivial in the sense /// that it requires no code to be generated. -bool CodeGenFunction::isTrivialInitializer(const Expr *Init) { +static bool isTrivialInitializer(const Expr *Init) { if (!Init) return true; diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index c439833cfe7..9dfcd0753b2 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -24,29 +24,6 @@ using namespace clang; using namespace CodeGen; -void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, Stmt *S) { - CodeGenFunction::OuterDeclMapTy OuterDeclMap; - CGF.EmitOMPFirstprivateClause(Directive, OuterDeclMap); - if (!OuterDeclMap.empty()) { - // Emit implicit barrier to synchronize threads and avoid data races. - auto Flags = static_cast<CGOpenMPRuntime::OpenMPLocationFlags>( - CGOpenMPRuntime::OMP_IDENT_KMPC | - CGOpenMPRuntime::OMP_IDENT_BARRIER_IMPL); - CGF.CGM.getOpenMPRuntime().EmitOMPBarrierCall(CGF, Directive.getLocStart(), - Flags); - // Remap captured variables to use their private copies in the outlined - // function. - for (auto I : OuterDeclMap) { - CGF.LocalDeclMap[I.first] = I.second; - } - } - CGCapturedStmtInfo::EmitBody(CGF, S); - // Clear mappings of captured private variables. - for (auto I : OuterDeclMap) { - CGF.LocalDeclMap.erase(I.first); - } -} - CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM) : CGM(CGM), DefaultOpenMPPSource(nullptr) { IdentTy = llvm::StructType::create( @@ -74,10 +51,11 @@ CGOpenMPRuntime::GetOrCreateDefaultOpenMPLocation(OpenMPLocationFlags Flags) { DefaultOpenMPPSource = llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy); } - auto DefaultOpenMPLocation = new llvm::GlobalVariable( - CGM.getModule(), IdentTy, /*isConstant*/ true, - llvm::GlobalValue::PrivateLinkage, /*Initializer*/ nullptr); + llvm::GlobalVariable *DefaultOpenMPLocation = cast<llvm::GlobalVariable>( + CGM.CreateRuntimeVariable(IdentTy, ".kmpc_default_loc.addr")); DefaultOpenMPLocation->setUnnamedAddr(true); + DefaultOpenMPLocation->setConstant(true); + DefaultOpenMPLocation->setLinkage(llvm::GlobalValue::PrivateLinkage); llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true); llvm::Constant *Values[] = {Zero, @@ -85,7 +63,6 @@ CGOpenMPRuntime::GetOrCreateDefaultOpenMPLocation(OpenMPLocationFlags Flags) { Zero, Zero, DefaultOpenMPPSource}; llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values); DefaultOpenMPLocation->setInitializer(Init); - OpenMPDefaultLocMap[Flags] = DefaultOpenMPLocation; return DefaultOpenMPLocation; } return Entry; @@ -143,14 +120,14 @@ llvm::Value *CGOpenMPRuntime::EmitOpenMPUpdateLocation( return LocValue; } -llvm::Value *CGOpenMPRuntime::GetOpenMPThreadID(CodeGenFunction &CGF, - SourceLocation Loc) { +llvm::Value *CGOpenMPRuntime::GetOpenMPGlobalThreadNum(CodeGenFunction &CGF, + SourceLocation Loc) { assert(CGF.CurFn && "No function in current CodeGenFunction."); - llvm::Value *ThreadID = nullptr; - OpenMPThreadIDMapTy::iterator I = OpenMPThreadIDMap.find(CGF.CurFn); - if (I != OpenMPThreadIDMap.end()) { - ThreadID = I->second; + llvm::Value *GTid = nullptr; + OpenMPGtidMapTy::iterator I = OpenMPGtidMap.find(CGF.CurFn); + if (I != OpenMPGtidMap.end()) { + GTid = I->second; } else { // Check if current function is a function which has first parameter // with type int32 and name ".global_tid.". @@ -168,24 +145,24 @@ llvm::Value *CGOpenMPRuntime::GetOpenMPThreadID(CodeGenFunction &CGF, CGF.CurFn->arg_begin()->getName() == ".global_tid.") { CGBuilderTy::InsertPointGuard IPG(CGF.Builder); CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt); - ThreadID = CGF.Builder.CreateLoad(CGF.CurFn->arg_begin()); + GTid = CGF.Builder.CreateLoad(CGF.CurFn->arg_begin()); } else { // Generate "int32 .kmpc_global_thread_num.addr;" CGBuilderTy::InsertPointGuard IPG(CGF.Builder); CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt); llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc)}; - ThreadID = CGF.EmitRuntimeCall( + GTid = CGF.EmitRuntimeCall( CreateRuntimeFunction(OMPRTL__kmpc_global_thread_num), Args); } - OpenMPThreadIDMap[CGF.CurFn] = ThreadID; + OpenMPGtidMap[CGF.CurFn] = GTid; } - return ThreadID; + return GTid; } void CGOpenMPRuntime::FunctionFinished(CodeGenFunction &CGF) { assert(CGF.CurFn && "No function in current CodeGenFunction."); - if (OpenMPThreadIDMap.count(CGF.CurFn)) - OpenMPThreadIDMap.erase(CGF.CurFn); + if (OpenMPGtidMap.count(CGF.CurFn)) + OpenMPGtidMap.erase(CGF.CurFn); if (OpenMPLocMap.count(CGF.CurFn)) OpenMPLocMap.erase(CGF.CurFn); } @@ -242,33 +219,10 @@ CGOpenMPRuntime::CreateRuntimeFunction(OpenMPRTLFunction Function) { RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical"); break; } - case OMPRTL__kmpc_barrier: { - // Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid); - llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty}; - llvm::FunctionType *FnTy = - llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); - RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier"); - break; - } } return RTLFn; } -void CGOpenMPRuntime::EmitOMPParallelCall(CodeGenFunction &CGF, - SourceLocation Loc, - llvm::Value *OutlinedFn, - llvm::Value *CapturedStruct) { - // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/) - llvm::Value *Args[] = { - EmitOpenMPUpdateLocation(CGF, Loc), - CGF.Builder.getInt32(1), // Number of arguments after 'microtask' argument - // (there is only one additional argument - 'context') - CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy()), - CGF.EmitCastToVoidPtr(CapturedStruct)}; - auto RTLFn = CreateRuntimeFunction(CGOpenMPRuntime::OMPRTL__kmpc_fork_call); - CGF.EmitRuntimeCall(RTLFn, Args); -} - llvm::Value *CGOpenMPRuntime::GetCriticalRegionLock(StringRef CriticalName) { SmallString<256> Buffer; llvm::raw_svector_ostream Out(Buffer); @@ -291,7 +245,7 @@ void CGOpenMPRuntime::EmitOMPCriticalRegionStart(CodeGenFunction &CGF, SourceLocation Loc) { // Prepare other arguments and build a call to __kmpc_critical llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc), - GetOpenMPThreadID(CGF, Loc), RegionLock}; + GetOpenMPGlobalThreadNum(CGF, Loc), RegionLock}; auto RTLFn = CreateRuntimeFunction(CGOpenMPRuntime::OMPRTL__kmpc_critical); CGF.EmitRuntimeCall(RTLFn, Args); } @@ -301,19 +255,8 @@ void CGOpenMPRuntime::EmitOMPCriticalRegionEnd(CodeGenFunction &CGF, SourceLocation Loc) { // Prepare other arguments and build a call to __kmpc_end_critical llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc), - GetOpenMPThreadID(CGF, Loc), RegionLock}; + GetOpenMPGlobalThreadNum(CGF, Loc), RegionLock}; auto RTLFn = CreateRuntimeFunction(CGOpenMPRuntime::OMPRTL__kmpc_end_critical); CGF.EmitRuntimeCall(RTLFn, Args); } - -void CGOpenMPRuntime::EmitOMPBarrierCall(CodeGenFunction &CGF, - SourceLocation Loc, - OpenMPLocationFlags Flags) { - // Build call __kmpc_barrier(loc, thread_id) - llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc, Flags), - GetOpenMPThreadID(CGF, Loc)}; - auto RTLFn = CreateRuntimeFunction(CGOpenMPRuntime::OMPRTL__kmpc_barrier); - CGF.EmitRuntimeCall(RTLFn, Args); -} - diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h index ec6115fb094..bba2c8c4d78 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -14,49 +14,33 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H #define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H -#include "CodeGenFunction.h" -#include "clang/AST/StmtOpenMP.h" #include "clang/AST/Type.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" +namespace llvm { +class AllocaInst; +class CallInst; +class GlobalVariable; +class Constant; +class Function; +class Module; +class StructLayout; +class ArrayType; +class FunctionType; +class StructType; +class Type; +class Value; +} // namespace llvm + namespace clang { namespace CodeGen { -/// \brief API for captured statement code generation in OpenMP constructs. -class CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo { -public: - CGOpenMPRegionInfo(const OMPExecutableDirective &D, const CapturedStmt &S, - const VarDecl *ThreadIDVar) - : CGCapturedStmtInfo(S, CR_OpenMP), ThreadIDVar(ThreadIDVar), - Directive(D) {} - - virtual ~CGOpenMPRegionInfo() override{}; - - /// \brief Gets a variable or parameter for storing global thread id - /// inside OpenMP construct. - const VarDecl *getThreadIDVariable() const { return ThreadIDVar; } - - static bool classof(const CGCapturedStmtInfo *Info) { - return Info->getKind() == CR_OpenMP; - } - - /// \brief Emit the captured statement body. - virtual void EmitBody(CodeGenFunction &CGF, Stmt *S) override; - - /// \brief Get the name of the capture helper. - virtual StringRef getHelperName() const override { return ".omp_outlined."; } - -private: - /// \brief A variable or parameter storing global thread id for OpenMP - /// constructs. - const VarDecl *ThreadIDVar; - /// \brief OpenMP executable directive associated with the region. - const OMPExecutableDirective &Directive; -}; +class CodeGenFunction; +class CodeGenModule; class CGOpenMPRuntime { public: @@ -92,9 +76,7 @@ public: OMPRTL__kmpc_critical, // Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid, // kmp_critical_name *crit); - OMPRTL__kmpc_end_critical, - // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid); - OMPRTL__kmpc_barrier + OMPRTL__kmpc_end_critical }; private: @@ -157,15 +139,24 @@ private: /// \brief Map of local debug location and functions. typedef llvm::DenseMap<llvm::Function *, llvm::Value *> OpenMPLocMapTy; OpenMPLocMapTy OpenMPLocMap; - /// \brief Map of local ThreadID and functions. - typedef llvm::DenseMap<llvm::Function *, llvm::Value *> OpenMPThreadIDMapTy; - OpenMPThreadIDMapTy OpenMPThreadIDMap; + /// \brief Map of local gtid and functions. + typedef llvm::DenseMap<llvm::Function *, llvm::Value *> OpenMPGtidMapTy; + OpenMPGtidMapTy OpenMPGtidMap; /// \brief Type kmp_critical_name, originally defined as typedef kmp_int32 /// kmp_critical_name[8]; llvm::ArrayType *KmpCriticalNameTy; /// \brief Map of critical regions names and the corresponding lock objects. llvm::StringMap<llvm::Value *, llvm::BumpPtrAllocator> CriticalRegionVarNames; +public: + explicit CGOpenMPRuntime(CodeGenModule &CGM); + virtual ~CGOpenMPRuntime() {} + + /// \brief Cleans up references to the objects in finished function. + /// \param CGF Reference to finished CodeGenFunction. + /// + void FunctionFinished(CodeGenFunction &CGF); + /// \brief Emits object of ident_t type with info for source location. /// \param CGF Reference to current CodeGenFunction. /// \param Loc Clang source location. @@ -175,6 +166,13 @@ private: EmitOpenMPUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc, OpenMPLocationFlags Flags = OMP_IDENT_KMPC); + /// \brief Generates global thread number value. + /// \param CGF Reference to current CodeGenFunction. + /// \param Loc Clang source location. + /// + llvm::Value *GetOpenMPGlobalThreadNum(CodeGenFunction &CGF, + SourceLocation Loc); + /// \brief Returns pointer to ident_t type; llvm::Type *getIdentTyPointerTy(); @@ -186,33 +184,6 @@ private: /// \return Specified function. llvm::Constant *CreateRuntimeFunction(OpenMPRTLFunction Function); - /// \brief Gets thread id value for the current thread. - /// \param CGF Reference to current CodeGenFunction. - /// \param Loc Clang source location. - /// - llvm::Value *GetOpenMPThreadID(CodeGenFunction &CGF, SourceLocation Loc); - -public: - explicit CGOpenMPRuntime(CodeGenModule &CGM); - virtual ~CGOpenMPRuntime() {} - - /// \brief Cleans up references to the objects in finished function. - /// \param CGF Reference to finished CodeGenFunction. - /// - void FunctionFinished(CodeGenFunction &CGF); - - /// \brief Emits code for parallel call of the \a OutlinedFn with variables - /// captured in a record which address is stored in \a CapturedStruct. - /// \param CGF Reference to current CodeGenFunction. - /// \param Loc Clang source location. - /// \param OutlinedFn Outlined function to be run in parallel threads. - /// \param CapturedStruct A pointer to the record with the references to - /// variables used in \a OutlinedFn function. - /// - virtual void EmitOMPParallelCall(CodeGenFunction &CGF, SourceLocation Loc, - llvm::Value *OutlinedFn, - llvm::Value *CapturedStruct); - /// \brief Returns corresponding lock object for the specified critical region /// name. If the lock object does not exist it is created, otherwise the /// reference to the existing copy is returned. @@ -237,14 +208,6 @@ public: virtual void EmitOMPCriticalRegionEnd(CodeGenFunction &CGF, llvm::Value *RegionLock, SourceLocation Loc); - - /// \brief Emits a barrier for OpenMP threads. - /// \param CGF Reference to current CodeGenFunction. - /// \param Loc Clang source location. - /// \param Flags Flags for the barrier. - /// - virtual void EmitOMPBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, - OpenMPLocationFlags Flags); }; } // namespace CodeGen } // namespace clang diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 5efff2ccbde..985cc0e62ae 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -24,110 +24,6 @@ using namespace CodeGen; // OpenMP Directive Emission //===----------------------------------------------------------------------===// -void CodeGenFunction::EmitOMPAggregateAssign(LValue OriginalAddr, - llvm::Value *PrivateAddr, - const Expr *AssignExpr, - QualType OriginalType, - const VarDecl *VDInit) { - EmitBlock(createBasicBlock(".omp.assign.begin.")); - if (!isa<CXXConstructExpr>(AssignExpr) || isTrivialInitializer(AssignExpr)) { - // Perform simple memcpy. - EmitAggregateAssign(PrivateAddr, OriginalAddr.getAddress(), - AssignExpr->getType()); - } else { - // Perform element-by-element initialization. - QualType ElementTy; - auto SrcBegin = OriginalAddr.getAddress(); - auto DestBegin = PrivateAddr; - auto ArrayTy = OriginalType->getAsArrayTypeUnsafe(); - auto SrcNumElements = emitArrayLength(ArrayTy, ElementTy, SrcBegin); - auto DestNumElements = emitArrayLength(ArrayTy, ElementTy, DestBegin); - auto SrcEnd = Builder.CreateGEP(SrcBegin, SrcNumElements); - auto DestEnd = Builder.CreateGEP(DestBegin, DestNumElements); - // The basic structure here is a do-while loop, because we don't - // need to check for the zero-element case. - auto BodyBB = createBasicBlock("omp.arraycpy.body"); - auto DoneBB = createBasicBlock("omp.arraycpy.done"); - auto IsEmpty = - Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty"); - Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); - - // Enter the loop body, making that address the current address. - auto EntryBB = Builder.GetInsertBlock(); - EmitBlock(BodyBB); - auto SrcElementPast = Builder.CreatePHI(SrcBegin->getType(), 2, - "omp.arraycpy.srcElementPast"); - SrcElementPast->addIncoming(SrcEnd, EntryBB); - auto DestElementPast = Builder.CreatePHI(DestBegin->getType(), 2, - "omp.arraycpy.destElementPast"); - DestElementPast->addIncoming(DestEnd, EntryBB); - - // Shift the address back by one element. - auto NegativeOne = llvm::ConstantInt::get(SizeTy, -1, true); - auto DestElement = Builder.CreateGEP(DestElementPast, NegativeOne, - "omp.arraycpy.dest.element"); - auto SrcElement = Builder.CreateGEP(SrcElementPast, NegativeOne, - "omp.arraycpy.src.element"); - { - // Create RunCleanScope to cleanup possible temps. - CodeGenFunction::RunCleanupsScope Init(*this); - // Emit initialization for single element. - LocalDeclMap[VDInit] = SrcElement; - EmitAnyExprToMem(AssignExpr, DestElement, - AssignExpr->getType().getQualifiers(), - /*IsInitializer*/ false); - LocalDeclMap.erase(VDInit); - } - - // Check whether we've reached the end. - auto Done = - Builder.CreateICmpEQ(DestElement, DestBegin, "omp.arraycpy.done"); - Builder.CreateCondBr(Done, DoneBB, BodyBB); - DestElementPast->addIncoming(DestElement, Builder.GetInsertBlock()); - SrcElementPast->addIncoming(SrcElement, Builder.GetInsertBlock()); - - // Done. - EmitBlock(DoneBB, true); - } - EmitBlock(createBasicBlock(".omp.assign.end.")); -} - -void CodeGenFunction::EmitOMPFirstprivateClause( - const OMPExecutableDirective &D, - CodeGenFunction::OuterDeclMapTy &OuterDeclMap) { - auto PrivateFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_firstprivate; - }; - for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)> - I(D.clauses(), PrivateFilter); I; ++I) { - auto *C = cast<OMPFirstprivateClause>(*I); - auto IRef = C->varlist_begin(); - auto InitsRef = C->inits().begin(); - for (auto IInit : C->private_copies()) { - auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); - if (*InitsRef != nullptr) { - // Emit VarDecl with copy init for arrays. - auto *FD = CapturedStmtInfo->lookup( - cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl())); - LValue Base = MakeNaturalAlignAddrLValue( - CapturedStmtInfo->getContextValue(), - getContext().getTagDeclType(FD->getParent())); - auto OriginalAddr = EmitLValueForField(Base, FD); - auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl()); - auto Emission = EmitAutoVarAlloca(*VD); - // Emit initialization of aggregate firstprivate vars. - EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(), - VD->getInit(), (*IRef)->getType(), VDInit); - EmitAutoVarCleanups(Emission); - } else - // Emit VarDecl with copy init. - EmitDecl(*VD); - OuterDeclMap[cast<DeclRefExpr>(*IRef)->getDecl()] = GetAddrOfLocalVar(VD); - ++IRef, ++InitsRef; - } - } -} - void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt()); llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS); @@ -135,13 +31,22 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { llvm::Value *OutlinedFn; { CodeGenFunction CGF(CGM, true); - CGOpenMPRegionInfo CGInfo(S, *CS, *CS->getCapturedDecl()->param_begin()); + CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind()); CGF.CapturedStmtInfo = &CGInfo; OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS); } - CGM.getOpenMPRuntime().EmitOMPParallelCall(*this, S.getLocStart(), OutlinedFn, - CapturedStruct); + // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/) + llvm::Value *Args[] = { + CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()), + Builder.getInt32(1), // Number of arguments after 'microtask' argument + // (there is only one additional argument - 'context') + Builder.CreateBitCast(OutlinedFn, + CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()), + EmitCastToVoidPtr(CapturedStruct)}; + llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction( + CGOpenMPRuntime::OMPRTL__kmpc_fork_call); + EmitRuntimeCall(RTLFn, Args); } void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index e471f157381..a4b231ddf4b 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -113,7 +113,6 @@ class CodeGenFunction : public CodeGenTypeCache { void operator=(const CodeGenFunction &) LLVM_DELETED_FUNCTION; friend class CGCXXABI; - friend class CGOpenMPRegionInfo; public: /// A jump destination is an abstract label, branching to which may /// require a jump out through normal cleanups. @@ -1827,10 +1826,6 @@ public: typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D, llvm::Value *Address); - /// \brief Determine whether the given initializer is trivial in the sense - /// that it requires no code to be generated. - bool isTrivialInitializer(const Expr *Init); - /// EmitAutoVarDecl - Emit an auto variable declaration. /// /// This function can be called with a null (unreachable) insert point. @@ -1996,16 +1991,8 @@ public: ArrayRef<const Attr *> Attrs = None); llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K); - void GenerateCapturedStmtFunctionProlog(const CapturedStmt &S); - llvm::Function *GenerateCapturedStmtFunctionEpilog(const CapturedStmt &S); llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); llvm::Value *GenerateCapturedStmtArgument(const CapturedStmt &S); - typedef llvm::DenseMap<const Decl *, llvm::Value *> OuterDeclMapTy; - void EmitOMPAggregateAssign(LValue OriginalAddr, llvm::Value *PrivateAddr, - const Expr *AssignExpr, QualType Type, - const VarDecl *VDInit); - void EmitOMPFirstprivateClause(const OMPExecutableDirective &D, - OuterDeclMapTy &OuterDeclMap); void EmitOMPParallelDirective(const OMPParallelDirective &S); void EmitOMPSimdDirective(const OMPSimdDirective &S); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 159f1bb08ed..ff2b2826092 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3902,36 +3902,11 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); } -namespace { -class DiagsUninitializedSeveretyRAII { -private: - DiagnosticsEngine &Diags; - SourceLocation SavedLoc; - bool IsIgnored; - -public: - DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, - bool IsIgnored) - : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { - if (!IsIgnored) { - Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, - /*Map*/ diag::Severity::Ignored, Loc); - } - } - ~DiagsUninitializedSeveretyRAII() { - if (!IsIgnored) - Diags.popMappings(SavedLoc); - } -}; -} - OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { SmallVector<Expr *, 8> Vars; - SmallVector<Expr *, 8> PrivateCopies; - SmallVector<Expr *, 8> Inits; bool IsImplicitClause = StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); auto ImplicitClauseLoc = DSAStack->getConstructLoc(); @@ -3941,13 +3916,11 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, if (isa<DependentScopeDeclRefExpr>(RefExpr)) { // It will be analyzed later. Vars.push_back(RefExpr); - PrivateCopies.push_back(nullptr); - Inits.push_back(nullptr); continue; } - SourceLocation ELoc = - IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc(); + SourceLocation ELoc = IsImplicitClause ? ImplicitClauseLoc + : RefExpr->getExprLoc(); // OpenMP [2.1, C/C++] // A list item is a variable name. // OpenMP [2.9.3.3, Restrictions, p.1] @@ -3965,8 +3938,6 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, if (Type->isDependentType() || Type->isInstantiationDependentType()) { // It will be analyzed later. Vars.push_back(DE); - PrivateCopies.push_back(nullptr); - Inits.push_back(nullptr); continue; } @@ -4000,6 +3971,65 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, // clause requires an accessible, unambiguous copy constructor for the // class type. Type = Context.getBaseElementType(Type); + CXXRecordDecl *RD = getLangOpts().CPlusPlus + ? Type.getNonReferenceType()->getAsCXXRecordDecl() + : nullptr; + // FIXME This code must be replaced by actual constructing/destructing of + // the firstprivate variable. + if (RD) { + CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0); + PartialDiagnostic PD = + PartialDiagnostic(PartialDiagnostic::NullDiagnostic()); + if (!CD || + CheckConstructorAccess(ELoc, CD, + InitializedEntity::InitializeTemporary(Type), + CD->getAccess(), PD) == AR_inaccessible || + CD->isDeleted()) { + if (IsImplicitClause) { + Diag(ImplicitClauseLoc, + diag::err_omp_task_predetermined_firstprivate_required_method) + << 0; + Diag(RefExpr->getExprLoc(), diag::note_used_here); + } else { + Diag(ELoc, diag::err_omp_required_method) + << getOpenMPClauseName(OMPC_firstprivate) << 1; + } + bool IsDecl = VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + Diag(VD->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) + << VD; + Diag(RD->getLocation(), diag::note_previous_decl) << RD; + continue; + } + MarkFunctionReferenced(ELoc, CD); + DiagnoseUseOfDecl(CD, ELoc); + + CXXDestructorDecl *DD = RD->getDestructor(); + if (DD) { + if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible || + DD->isDeleted()) { + if (IsImplicitClause) { + Diag(ImplicitClauseLoc, + diag::err_omp_task_predetermined_firstprivate_required_method) + << 1; + Diag(RefExpr->getExprLoc(), diag::note_used_here); + } else { + Diag(ELoc, diag::err_omp_required_method) + << getOpenMPClauseName(OMPC_firstprivate) << 4; + } + bool IsDecl = VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + Diag(VD->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) + << VD; + Diag(RD->getLocation(), diag::note_previous_decl) << RD; + continue; + } + MarkFunctionReferenced(ELoc, DD); + DiagnoseUseOfDecl(DD, ELoc); + } + } // If an implicit firstprivate variable found it was checked already. if (!IsImplicitClause) { @@ -4089,67 +4119,15 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, } } - Type = Type.getUnqualifiedType(); - auto VDPrivate = VarDecl::Create(Context, CurContext, DE->getLocStart(), - ELoc, VD->getIdentifier(), VD->getType(), - VD->getTypeSourceInfo(), /*S*/ SC_Auto); - // Generate helper private variable and initialize it with the value of the - // original variable. The address of the original variable is replaced by - // the address of the new private variable in the CodeGen. This new variable - // is not added to IdResolver, so the code in the OpenMP region uses - // original variable for proper diagnostics and variable capturing. - Expr *VDInitRefExpr = nullptr; - // For arrays generate initializer for single element and replace it by the - // original array element in CodeGen. - if (DE->getType()->isArrayType()) { - auto VDInit = VarDecl::Create(Context, CurContext, DE->getLocStart(), - ELoc, VD->getIdentifier(), Type, - VD->getTypeSourceInfo(), /*S*/ SC_Auto); - CurContext->addHiddenDecl(VDInit); - VDInitRefExpr = DeclRefExpr::Create( - Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), - /*TemplateKWLoc*/ SourceLocation(), VDInit, - /*isEnclosingLocal*/ false, ELoc, Type, - /*VK*/ VK_LValue); - VDInit->setIsUsed(); - auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); - InitializedEntity Entity = InitializedEntity::InitializeVariable(VDInit); - InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); - - InitializationSequence InitSeq(*this, Entity, Kind, Init); - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); - if (Result.isInvalid()) - VDPrivate->setInvalidDecl(); - else - VDPrivate->setInit(Result.getAs<Expr>()); - } else { - AddInitializerToDecl(VDPrivate, DefaultLvalueConversion(DE).get(), - /*DirectInit*/ false, /*TypeMayContainAuto*/ false); - } - if (VDPrivate->isInvalidDecl()) { - if (IsImplicitClause) { - Diag(DE->getExprLoc(), - diag::note_omp_task_predetermined_firstprivate_here); - } - continue; - } - CurContext->addDecl(VDPrivate); - auto VDPrivateRefExpr = DeclRefExpr::Create( - Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), - /*TemplateKWLoc*/ SourceLocation(), VDPrivate, - /*isEnclosingLocal*/ false, DE->getLocStart(), DE->getType(), - /*VK*/ VK_LValue); DSAStack->addDSA(VD, DE, OMPC_firstprivate); Vars.push_back(DE); - PrivateCopies.push_back(VDPrivateRefExpr); - Inits.push_back(VDInitRefExpr); } if (Vars.empty()) return nullptr; return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, - Vars, PrivateCopies, Inits); + Vars); } OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 0b8efb51401..c8343373ad6 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1854,14 +1854,6 @@ void OMPClauseReader::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) { for (unsigned i = 0; i != NumVars; ++i) Vars.push_back(Reader->Reader.ReadSubExpr()); C->setVarRefs(Vars); - Vars.clear(); - for (unsigned i = 0; i != NumVars; ++i) - Vars.push_back(Reader->Reader.ReadSubExpr()); - C->setPrivateCopies(Vars); - Vars.clear(); - for (unsigned i = 0; i != NumVars; ++i) - Vars.push_back(Reader->Reader.ReadSubExpr()); - C->setInits(Vars); } void OMPClauseReader::VisitOMPLastprivateClause(OMPLastprivateClause *C) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index a963d6b875a..80d42b8ae5f 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1761,15 +1761,8 @@ void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) { Record.push_back(C->varlist_size()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); - for (auto *VE : C->varlists()) { - Writer->Writer.AddStmt(VE); - } - for (auto *VE : C->private_copies()) { - Writer->Writer.AddStmt(VE); - } - for (auto *VE : C->inits()) { + for (auto *VE : C->varlists()) Writer->Writer.AddStmt(VE); - } } void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) { |