14#include "llvm/Analysis/LoopInfo.h"
15#include "llvm/IR/Dominators.h"
16#include "llvm/IR/Module.h"
25 const std::string Name =
"GOMP_parallel_loop_runtime_start";
27 Function *F =
M->getFunction(Name);
31 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
37 FunctionType *Ty = FunctionType::get(
Builder.getVoidTy(), Params,
false);
38 F = Function::Create(Ty, Linkage, Name,
M);
44 CallInst *Call =
Builder.CreateCall(F, Args);
54 CallInst *Call =
Builder.CreateCall(SubFn, SubFnParam);
61 FunctionType::get(
Builder.getVoidTy(), {Builder.getPtrTy()},
false);
62 Function *SubFn = Function::Create(FT, Function::InternalLinkage,
63 F->getName() +
"_polly_subfn",
M);
65 SubFn->arg_begin()->setName(
"polly.par.userContext");
89std::tuple<Value *, Function *>
91 SetVector<Value *> Data,
95 errs() <<
"warning: Polly's GNU OpenMP backend solely "
96 "supports the scheduling type 'runtime'.\n";
101 errs() <<
"warning: Polly's GNU OpenMP backend solely "
102 "supports the default chunk size.\n";
106 LLVMContext &Context = SubFn->getContext();
109 BasicBlock *HeaderBB = BasicBlock::Create(Context,
"polly.par.setup", SubFn);
111 auto *UI =
new UnreachableInst(Context, HeaderBB);
112 SubFnDT = std::make_unique<DominatorTree>(*SubFn);
114 UI->eraseFromParent();
116 BasicBlock *ExitBB = BasicBlock::Create(Context,
"polly.par.exit", SubFn);
117 BasicBlock *CheckNextBB =
118 BasicBlock::Create(Context,
"polly.par.checkNext", SubFn);
119 BasicBlock *PreHeaderBB =
120 BasicBlock::Create(Context,
"polly.par.loadIVBounds", SubFn);
122 SubFnDT->addNewBlock(ExitBB, HeaderBB);
123 SubFnDT->addNewBlock(CheckNextBB, HeaderBB);
124 SubFnDT->addNewBlock(PreHeaderBB, HeaderBB);
127 Builder.SetInsertPoint(HeaderBB);
130 Value *UserContext = &*SubFn->arg_begin();
137 Builder.SetInsertPoint(CheckNextBB);
140 Next,
Builder.getInt1Ty(),
"polly.par.hasNextScheduleBlock");
141 Builder.CreateCondBr(HasNextSchedule, PreHeaderBB, ExitBB);
144 Builder.SetInsertPoint(PreHeaderBB);
151 "polly.par.UBAdjusted");
158 ICmpInst::ICMP_SLE,
nullptr,
true,
false);
160 BasicBlock::iterator LoopBody =
Builder.GetInsertPoint();
163 Builder.SetInsertPoint(ExitBB);
167 Builder.SetInsertPoint(LoopBody);
173 return std::make_tuple(IV, SubFn);
178 const std::string Name =
"GOMP_loop_runtime_next";
180 Function *F =
M->getFunction(Name);
184 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
186 FunctionType *Ty = FunctionType::get(
Builder.getInt8Ty(), Params,
false);
187 F = Function::Create(Ty, Linkage, Name,
M);
190 Value *Args[] = {LBPtr, UBPtr};
191 CallInst *Call =
Builder.CreateCall(F, Args);
199 const std::string Name =
"GOMP_parallel_end";
201 Function *F =
M->getFunction(Name);
205 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
207 FunctionType *Ty = FunctionType::get(
Builder.getVoidTy(),
false);
208 F = Function::Create(Ty, Linkage, Name,
M);
211 CallInst *Call =
Builder.CreateCall(F, {});
216 const std::string Name =
"GOMP_loop_end_nowait";
218 Function *F =
M->getFunction(Name);
222 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
224 FunctionType *Ty = FunctionType::get(
Builder.getVoidTy(),
false);
225 F = Function::Create(Ty, Linkage, Name,
M);
228 CallInst *Call =
Builder.CreateCall(F, {});
void deployParallelExecution(Function *SubFn, Value *SubFnParam, Value *LB, Value *UB, Value *Stride) override
Create the runtime library calls for spawn and join of the worker threads.
Value * createCallGetWorkItem(Value *LBPtr, Value *UBPtr)
Create a runtime library call to get the next work item.
std::tuple< Value *, Function * > createSubFn(Value *Stride, AllocaInst *Struct, SetVector< Value * > UsedValues, ValueMapT &VMap) override
Create the parallel subfunction.
void createCallSpawnThreads(Value *SubFn, Value *SubFnParam, Value *LB, Value *UB, Value *Stride)
Create a runtime library call to spawn the worker threads.
void createCallJoinThreads()
Create a runtime library call to join the worker threads.
void createCallCleanupThread()
Create a runtime library call to allow cleanup of the thread.
Function * prepareSubFnDefinition(Function *F) const override
Prepare the definition of the parallel subfunction.
PollyIRBuilder & Builder
The IR builder we use to create instructions.
Function * createSubFnDefinition()
Create the definition of the parallel subfunction.
std::unique_ptr< DominatorTree > SubFnDT
The dominance tree for the generated subfunction.
Module * M
The current module.
llvm::DebugLoc DLGenerated
Debug location for generated code without direct link to any specific line.
Type * LongType
The type of a "long" on this hardware used for backend calls.
void extractValuesFromStruct(SetVector< Value * > Values, Type *Ty, Value *Struct, ValueMapT &VMap)
Extract all values from the Struct and construct the mapping.
std::unique_ptr< LoopInfo > SubFnLI
The loop info for the generated subfunction.
OMPGeneralSchedulingType PollyScheduling
@ Value
MemoryKind::Value: Models an llvm::Value.
Value * createLoop(Value *LowerBound, Value *UpperBound, Value *Stride, PollyIRBuilder &Builder, LoopInfo &LI, DominatorTree &DT, BasicBlock *&ExitBlock, ICmpInst::Predicate Predicate, ScopAnnotator *Annotator=nullptr, bool Parallel=false, bool UseGuard=true, bool LoopVectDisabled=false)
Create a scalar do/for-style loop.
llvm::DenseMap< llvm::AssertingVH< llvm::Value >, llvm::AssertingVH< llvm::Value > > ValueMapT
Type to remap values.