diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -76,6 +76,11 @@ LLVM_MARK_AS_BITMASK_ENUM(0x7FFFFFFF) }; +enum class SchedType { +#define OMP_SCHED_TYPE(Enum, Str, Value) Enum = Value, +#include "llvm/Frontend/OpenMP/OMPKinds.def" +}; + #define OMP_IDENT_FLAG(Enum, ...) constexpr auto Enum = omp::IdentFlag::Enum; #include "llvm/Frontend/OpenMP/OMPKinds.def" diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h --- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -21,35 +21,6 @@ namespace llvm { -enum OpenMPSchedType { - /// Lower bound for default (unordered) versions. - OMP_sch_lower = 32, - OMP_sch_static_chunked = 33, - OMP_sch_static = 34, - OMP_sch_dynamic_chunked = 35, - OMP_sch_guided_chunked = 36, - OMP_sch_runtime = 37, - OMP_sch_auto = 38, - /// static with chunk adjustment (e.g., simd) - OMP_sch_static_balanced_chunked = 45, - /// Lower bound for 'ordered' versions. - OMP_ord_lower = 64, - OMP_ord_static_chunked = 65, - OMP_ord_static = 66, - OMP_ord_dynamic_chunked = 67, - OMP_ord_guided_chunked = 68, - OMP_ord_runtime = 69, - OMP_ord_auto = 70, - OMP_sch_default = OMP_sch_static, - /// dist_schedule types - OMP_dist_sch_static_chunked = 91, - OMP_dist_sch_static = 92, - /// Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers. - /// Set if the monotonic schedule modifier was present. - OMP_sch_modifier_monotonic = (1 << 29), - /// Set if the nonmonotonic schedule modifier was present. - OMP_sch_modifier_nonmonotonic = (1 << 30), -}; /// An interface to create LLVM-IR for OpenMP directives. /// /// Each OpenMP directive has a corresponding public generator method. @@ -413,7 +384,7 @@ ArrayRef SectionCBs, PrivatizeCallbackTy PrivCB, FinalizeCallbackTy FiniCB, bool IsCancellable, - bool IsNoWait); + bool IsNowait); /// Generate conditional branch and relevant BasicBlocks through which private /// threads copy the 'copyin' variables from Master copy to threadprivate diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -1012,6 +1012,52 @@ ///} +/// OMP Scheduler Type Kinds +/// +/// See: +/// openmp/runtime/src/kmp.h - enum sched_type +///{ + +#ifndef OMP_SCHED_TYPE +#define OMP_SCHED_TYPE(Enum, Str, Value) +#endif + +#define __OMP_SCHED_TYPE(Name, Value) \ + OMP_SCHED_TYPE(OMP_SCHED_TYPE_##Name, #Name, Value) + +/// Lower bound for default (unordered) versions. +__OMP_SCHED_TYPE(SCH_LOWER, 32) +__OMP_SCHED_TYPE(SCH_STATIC_CHUNKED, 33) +__OMP_SCHED_TYPE(SCH_STATIC, 34) +__OMP_SCHED_TYPE(SCH_DYNAMIC_CHUNKED, 35) +__OMP_SCHED_TYPE(SCH_GUIDED_CHUNKED, 36) +__OMP_SCHED_TYPE(SCH_RUNTIME, 37) +__OMP_SCHED_TYPE(SCH_AUTO, 38) +/// static with chunk adjustment (e.g., simd) +__OMP_SCHED_TYPE(SCH_STATIC_BALANCED_CHUNKED, 45) +/// Lower bound for 'ordered' versions. +__OMP_SCHED_TYPE(ORD_LOWER, 64) +__OMP_SCHED_TYPE(ORD_STATIC_CHUNKED, 65) +__OMP_SCHED_TYPE(ORD_STATIC, 66) +__OMP_SCHED_TYPE(ORD_DYNAMIC_CHUNKED, 67) +__OMP_SCHED_TYPE(ORD_GUIDED_CHUNKED, 68) +__OMP_SCHED_TYPE(ORD_RUNTIME, 69) +__OMP_SCHED_TYPE(ORD_AUTO, 70) +__OMP_SCHED_TYPE(SCH_DEFAULT, 34) // = SCH_STATIC +/// dist_schedule types +__OMP_SCHED_TYPE(DIST_SCH_STATIC_CHUNKED, 91) +__OMP_SCHED_TYPE(DIST_SCH_STATIC, 92) +/// Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers. +/// Set if the monotonic schedule modifier was present. +__OMP_SCHED_TYPE(SCH_MODIFIER_MONOTONIC, 1 << 29) +/// Set if the nonmonotonic schedule modifier was present. +__OMP_SCHED_TYPE(SCH_MODIFIER_NONMONOTONIC, 1 << 30) + +#undef __OMP_SCHED_TYPE +#undef OMP_SCHED_TYPE + +///} + /// KMP cancel kind /// ///{ diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -784,7 +784,7 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::CreateSections( const LocationDescription &Loc, InsertPointTy AllocaIP, ArrayRef SectionCBs, PrivatizeCallbackTy PrivCB, - FinalizeCallbackTy FiniCB, bool IsCancellable, bool IsNoWait) { + FinalizeCallbackTy FiniCB, bool IsCancellable, bool IsNowait) { if (!updateToLocation(Loc)) return Loc.IP; Constant *SrcLocStr = getOrCreateSrcLocStr(Loc); @@ -794,7 +794,7 @@ BasicBlock *InsertBB = Builder.GetInsertBlock(); Function *CurFn = InsertBB->getParent(); - InsertPointTy CurrIP = Builder.saveIP(); + InsertPointTy CurIP = Builder.saveIP(); Builder.restoreIP(AllocaIP); // allocate helper vars for for loop Value *LB = Builder.CreateAlloca(Int32, nullptr, "omp.sections.lb"); @@ -803,7 +803,7 @@ Value *IL = Builder.CreateAlloca(Int32, nullptr, "omp.sections.il"); Value *IV = Builder.CreateAlloca(Int32, nullptr, "omp.sections.iv"); - Builder.restoreIP(CurrIP); + Builder.restoreIP(CurIP); // initialize helper vars for for loop ConstantInt *GlobalUBVal = Builder.getInt32(SectionCBs.size() - 1); Builder.CreateStore(Builder.getInt32(0), LB); @@ -811,99 +811,95 @@ Builder.CreateStore(Builder.getInt32(1), ST); Builder.CreateStore(Builder.getInt32(0), IL); - auto CreateForLoopCB = [&]() { - Instruction *LBRef = Builder.CreateLoad(LB); - Builder.CreateStore(LBRef, IV); - - // create new basic blocks for emitting the for loop - auto *ForBodyBB = BasicBlock::Create(M.getContext(), - "omp.sections.inner.for.body", CurFn); - auto *ForExitBB = BasicBlock::Create(M.getContext(), - "omp.sections.inner.for.exit", CurFn); - auto *ForIncBB = - BasicBlock::Create(M.getContext(), "omp.sections.inner.for.inc", CurFn); - - // split InsertBB to create the basic block for emitting for-loop-condition - auto *UI = new UnreachableInst(Builder.getContext(), InsertBB); - BasicBlock *ForCondBB = - InsertBB->splitBasicBlock(UI, "omp.sections.inner.for.cond"); - UI->eraseFromParent(); - Builder.SetInsertPoint(ForCondBB); - Instruction *IVRef = Builder.CreateLoad(IV); - Instruction *UBRef = Builder.CreateLoad(UB); - Value *cmpRef = Builder.CreateICmpSLE(IVRef, UBRef, "cmp"); - Builder.CreateCondBr(cmpRef, ForBodyBB, ForExitBB); - - // for Body - Builder.SetInsertPoint(ForBodyBB); - // creating switch statement inside for body. - auto *SwitchExitBB = - BasicBlock::Create(M.getContext(), "omp.switch.exit", CurFn); - SwitchInst *SwitchStmt = - Builder.CreateSwitch(Builder.CreateLoad(IV), SwitchExitBB); - // each section in emitted as a switch case - // Iterate through all sections and emit a switch construct: - // switch (IV) { - // case 0: - // ; - // break; - // ... - // case - 1: - // - 1]>; - // break; - // } - // .omp.sections.exit: - unsigned CaseNumber = 0; - for (auto SectionCB : SectionCBs) { - auto *CaseBB = - BasicBlock::Create(M.getContext(), "omp.sections.case", CurFn); - SwitchStmt->addCase(Builder.getInt32(CaseNumber), CaseBB); - Builder.SetInsertPoint(CaseBB); - SectionCB(InsertPointTy(), Builder.saveIP(), *SwitchExitBB); - CaseNumber++; - } - Builder.SetInsertPoint(SwitchExitBB); - // end switch statement inside for body - Builder.CreateBr(ForIncBB); - // end for body - - // for inc - Builder.SetInsertPoint(ForIncBB); - Instruction *IVRef2 = Builder.CreateLoad(IV); - Value *Inc = Builder.CreateNSWAdd(IVRef2, Builder.getInt32(1), "inc"); - Builder.CreateStore(Inc, IV); - Builder.CreateBr(ForCondBB); - Builder.SetInsertPoint(ForExitBB); - }; - // emit kmpc_for // TODO: Change the following to call the IR Builder function to emit kmpc_for // after for loop is lowered. Value *ForEntryArgs[] = { Ident, ThreadID, - Builder.getInt32(OMP_sch_static), // Schedule type - IL, // &isLastIter - LB, // &LB - UB, // &UB - ST, // &Stride - Builder.getInt32(1), // Incr - Builder.getInt32(1) // Chunk + Builder.getInt32(static_cast( + SchedType::OMP_SCHED_TYPE_SCH_STATIC)), // Schedule type + IL, // &isLastIter + LB, // &LB + UB, // &UB + ST, // &Stride + Builder.getInt32(1), // Incr + Builder.getInt32(1) // Chunk }; Function *EntryRTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_for_static_init_4); Builder.CreateCall(EntryRTLFn, ForEntryArgs); - CreateForLoopCB(); + Instruction *LBRef = Builder.CreateLoad(LB); + Builder.CreateStore(LBRef, IV); + + // create new basic blocks for emitting the for loop + auto *ForBodyBB = + BasicBlock::Create(M.getContext(), "omp.sections.inner.for.body", CurFn); + auto *ForExitBB = + BasicBlock::Create(M.getContext(), "omp.sections.inner.for.exit", CurFn); + auto *ForIncBB = + BasicBlock::Create(M.getContext(), "omp.sections.inner.for.inc", CurFn); + + // split InsertBB to create the basic block for emitting for-loop-condition + auto *UI = new UnreachableInst(Builder.getContext(), InsertBB); + BasicBlock *ForCondBB = + InsertBB->splitBasicBlock(UI, "omp.sections.inner.for.cond"); + UI->eraseFromParent(); + Builder.SetInsertPoint(ForCondBB); + Instruction *IVRef = Builder.CreateLoad(IV); + Instruction *UBRef = Builder.CreateLoad(UB); + Value *cmpRef = Builder.CreateICmpSLE(IVRef, UBRef, "cmp"); + Builder.CreateCondBr(cmpRef, ForBodyBB, ForExitBB); + + // for Body + Builder.SetInsertPoint(ForBodyBB); + // creating switch statement inside for body. + auto *SwitchExitBB = + BasicBlock::Create(M.getContext(), "omp.switch.exit", CurFn); + SwitchInst *SwitchStmt = + Builder.CreateSwitch(Builder.CreateLoad(IV), SwitchExitBB); + // each section in emitted as a switch case + // Iterate through all sections and emit a switch construct: + // switch (IV) { + // case 0: + // ; + // break; + // ... + // case - 1: + // - 1]>; + // break; + // } + // .omp.sections.exit: + unsigned CaseNumber = 0; + for (auto SectionCB : SectionCBs) { + auto *CaseBB = + BasicBlock::Create(M.getContext(), "omp.sections.case", CurFn); + SwitchStmt->addCase(Builder.getInt32(CaseNumber), CaseBB); + Builder.SetInsertPoint(CaseBB); + SectionCB(InsertPointTy(), Builder.saveIP(), *SwitchExitBB); + CaseNumber++; + } + Builder.SetInsertPoint(SwitchExitBB); + // end switch statement inside for body + Builder.CreateBr(ForIncBB); + // end for body + + // for inc + Builder.SetInsertPoint(ForIncBB); + Instruction *IVRef2 = Builder.CreateLoad(IV); + Value *Inc = Builder.CreateNSWAdd(IVRef2, Builder.getInt32(1), "inc"); + Builder.CreateStore(Inc, IV); + Builder.CreateBr(ForCondBB); + Builder.SetInsertPoint(ForExitBB); Value *ForExitArgs[] = {Ident, ThreadID}; Function *ExitRTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_for_static_fini); Builder.CreateCall(ExitRTLFn, ForExitArgs); - if (!IsNoWait) { + if (!IsNowait) CreateBarrier(Builder, OMPD_sections, true, IsCancellable); - } // TODO: Handle PrivCB