14#include "llvm/Analysis/LoopInfo.h"
15#include "llvm/IR/Dominators.h"
16#include "llvm/IR/Module.h"
25 const std::string Name =
"__kmpc_fork_call";
27 Type *KMPCMicroTy = StructType::getTypeByName(
M->getContext(),
"kmpc_micro");
31 Type *MicroParams[] = {
Builder.getInt32Ty()->getPointerTo(),
32 Builder.getInt32Ty()->getPointerTo()};
34 KMPCMicroTy = FunctionType::get(
Builder.getVoidTy(), MicroParams,
true);
40 StructType::getTypeByName(
M->getContext(),
"struct.ident_t");
42 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
43 Type *Params[] = {IdentTy->getPointerTo(),
Builder.getInt32Ty(),
44 KMPCMicroTy->getPointerTo()};
46 FunctionType *Ty = FunctionType::get(
Builder.getVoidTy(), Params,
true);
47 F = Function::Create(Ty, Linkage, Name,
M);
50 Value *Task =
Builder.CreatePointerBitCastOrAddrSpaceCast(
51 SubFn, KMPCMicroTy->getPointerTo());
61 CallInst *Call =
Builder.CreateCall(F, Args);
80 std::vector<Type *> Arguments = {
Builder.getInt32Ty()->getPointerTo(),
81 Builder.getInt32Ty()->getPointerTo(),
87 FunctionType *FT = FunctionType::get(
Builder.getVoidTy(), Arguments,
false);
88 Function *SubFn = Function::Create(FT, Function::InternalLinkage,
89 F->getName() +
"_polly_subfn",
M);
91 Function::arg_iterator AI = SubFn->arg_begin();
92 AI->setName(
"polly.kmpc.global_tid");
94 AI->setName(
"polly.kmpc.bound_tid");
96 AI->setName(
"polly.kmpc.lb");
98 AI->setName(
"polly.kmpc.ub");
100 AI->setName(
"polly.kmpc.inc");
102 AI->setName(
"polly.kmpc.shared");
132std::tuple<Value *, Function *>
134 AllocaInst *StructData,
135 SetVector<Value *> Data,
ValueMapT &Map) {
137 LLVMContext &Context = SubFn->getContext();
140 BasicBlock *HeaderBB = BasicBlock::Create(Context,
"polly.par.setup", SubFn);
141 SubFnDT = std::make_unique<DominatorTree>(*SubFn);
144 BasicBlock *ExitBB = BasicBlock::Create(Context,
"polly.par.exit", SubFn);
145 BasicBlock *CheckNextBB =
146 BasicBlock::Create(Context,
"polly.par.checkNext", SubFn);
147 BasicBlock *PreHeaderBB =
148 BasicBlock::Create(Context,
"polly.par.loadIVBounds", SubFn);
150 SubFnDT->addNewBlock(ExitBB, HeaderBB);
151 SubFnDT->addNewBlock(CheckNextBB, HeaderBB);
152 SubFnDT->addNewBlock(PreHeaderBB, HeaderBB);
155 Builder.SetInsertPoint(HeaderBB);
159 "polly.par.lastIterPtr");
164 Function::arg_iterator AI = SubFn->arg_begin();
174 Value *Stride = &*AI;
176 Value *Shared = &*AI;
180 const auto Alignment = llvm::Align(
is64BitArch() ? 8 : 4);
182 "polly.par.global_tid");
184 Builder.CreateAlignedStore(LB, LBPtr, Alignment);
185 Builder.CreateAlignedStore(UB, UBPtr, Alignment);
186 Builder.CreateAlignedStore(
Builder.getInt32(0), IsLastPtr, Alignment);
187 Builder.CreateAlignedStore(Stride, StridePtr, Alignment);
192 "polly.indvar.UBAdjusted");
200 switch (Scheduling) {
210 Value *HasIteration =
211 Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_EQ, HasWork,
212 Builder.getInt32(1),
"polly.hasIteration");
213 Builder.CreateCondBr(HasIteration, PreHeaderBB, ExitBB);
215 Builder.SetInsertPoint(CheckNextBB);
218 Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_EQ, HasWork,
219 Builder.getInt32(1),
"polly.hasWork");
220 Builder.CreateCondBr(HasIteration, PreHeaderBB, ExitBB);
222 Builder.SetInsertPoint(PreHeaderBB);
233 Builder.CreateAlignedStore(AdjustedUB, UBPtr, Alignment);
237 LongType, StridePtr, Alignment,
"polly.kmpc.stride");
242 "polly.indvar.UB.temp");
245 Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_SLE, UB, AdjustedUB,
246 "polly.indvar.UB.inRange");
247 UB =
Builder.CreateSelect(UBInRange, UB, AdjustedUB,
"polly.indvar.UB");
248 Builder.CreateAlignedStore(UB, UBPtr, Alignment);
251 llvm::CmpInst::Predicate::ICMP_SLE, LB, UB,
"polly.hasIteration");
252 Builder.CreateCondBr(HasIteration, PreHeaderBB, ExitBB);
255 Builder.SetInsertPoint(PreHeaderBB);
257 "polly.indvar.LB.entry");
259 "polly.indvar.UB.entry");
262 Builder.SetInsertPoint(CheckNextBB);
266 Builder.CreateAdd(LB, ChunkedStride,
"polly.indvar.nextLB");
269 Value *NextUBOutOfBounds =
270 Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_SGT, NextUB,
271 AdjustedUB,
"polly.indvar.nextUB.outOfBounds");
272 NextUB =
Builder.CreateSelect(NextUBOutOfBounds, AdjustedUB, NextUB,
273 "polly.indvar.nextUB");
275 Builder.CreateAlignedStore(NextLB, LBPtr, Alignment);
276 Builder.CreateAlignedStore(NextUB, UBPtr, Alignment);
279 Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_SLE, NextLB,
280 AdjustedUB,
"polly.hasWork");
281 Builder.CreateCondBr(HasWork, PreHeaderBB, ExitBB);
286 Builder.SetInsertPoint(PreHeaderBB);
295 *
SubFnDT, AfterBB, ICmpInst::ICMP_SLE,
nullptr,
true,
298 BasicBlock::iterator LoopBody =
Builder.GetInsertPoint();
301 Builder.SetInsertPoint(ExitBB);
308 Builder.SetInsertPoint(&*LoopBody);
314 return std::make_tuple(IV, SubFn);
318 const std::string Name =
"__kmpc_global_thread_num";
323 StructType *IdentTy =
324 StructType::getTypeByName(
M->getContext(),
"struct.ident_t");
326 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
327 Type *Params[] = {IdentTy->getPointerTo()};
329 FunctionType *Ty = FunctionType::get(
Builder.getInt32Ty(), Params,
false);
330 F = Function::Create(Ty, Linkage, Name,
M);
340 const std::string Name =
"__kmpc_push_num_threads";
345 StructType *IdentTy =
346 StructType::getTypeByName(
M->getContext(),
"struct.ident_t");
348 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
349 Type *Params[] = {IdentTy->getPointerTo(),
Builder.getInt32Ty(),
352 FunctionType *Ty = FunctionType::get(
Builder.getVoidTy(), Params,
false);
353 F = Function::Create(Ty, Linkage, Name,
M);
358 CallInst *Call =
Builder.CreateCall(F, Args);
364 Value *LBPtr, Value *UBPtr,
367 const std::string Name =
368 is64BitArch() ?
"__kmpc_for_static_init_8" :
"__kmpc_for_static_init_4";
370 StructType *IdentTy =
371 StructType::getTypeByName(
M->getContext(),
"struct.ident_t");
375 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
377 Type *Params[] = {IdentTy->getPointerTo(),
380 Builder.getInt32Ty()->getPointerTo(),
387 FunctionType *Ty = FunctionType::get(
Builder.getVoidTy(), Params,
false);
388 F = Function::Create(Ty, Linkage, Name,
M);
404 CallInst *Call =
Builder.CreateCall(F, Args);
409 const std::string Name =
"__kmpc_for_static_fini";
411 StructType *IdentTy =
412 StructType::getTypeByName(
M->getContext(),
"struct.ident_t");
416 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
417 Type *Params[] = {IdentTy->getPointerTo(),
Builder.getInt32Ty()};
418 FunctionType *Ty = FunctionType::get(
Builder.getVoidTy(), Params,
false);
419 F = Function::Create(Ty, Linkage, Name,
M);
424 CallInst *Call =
Builder.CreateCall(F, Args);
429 Value *LB, Value *UB,
432 const std::string Name =
433 is64BitArch() ?
"__kmpc_dispatch_init_8" :
"__kmpc_dispatch_init_4";
435 StructType *IdentTy =
436 StructType::getTypeByName(
M->getContext(),
"struct.ident_t");
440 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
442 Type *Params[] = {IdentTy->getPointerTo(),
450 FunctionType *Ty = FunctionType::get(
Builder.getVoidTy(), Params,
false);
451 F = Function::Create(Ty, Linkage, Name,
M);
465 CallInst *Call =
Builder.CreateCall(F, Args);
474 const std::string Name =
475 is64BitArch() ?
"__kmpc_dispatch_next_8" :
"__kmpc_dispatch_next_4";
477 StructType *IdentTy =
478 StructType::getTypeByName(
M->getContext(),
"struct.ident_t");
482 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
484 Type *Params[] = {IdentTy->getPointerTo(),
486 Builder.getInt32Ty()->getPointerTo(),
491 FunctionType *Ty = FunctionType::get(
Builder.getInt32Ty(), Params,
false);
492 F = Function::Create(Ty, Linkage, Name,
M);
498 CallInst *Call =
Builder.CreateCall(F, Args);
506 const std::string LocName =
".loc.dummy";
507 GlobalVariable *SourceLocDummy =
M->getGlobalVariable(LocName);
509 if (SourceLocDummy ==
nullptr) {
510 const std::string StructName =
"struct.ident_t";
511 StructType *IdentTy =
512 StructType::getTypeByName(
M->getContext(), StructName);
522 StructType::create(
M->getContext(), LocMembers, StructName,
false);
525 const auto ArrayType =
526 llvm::ArrayType::get(
Builder.getInt8Ty(), 23);
529 GlobalVariable *StrVar =
530 new GlobalVariable(*
M, ArrayType,
true, GlobalValue::PrivateLinkage,
531 nullptr,
".str.ident");
532 StrVar->setAlignment(llvm::Align(1));
534 SourceLocDummy =
new GlobalVariable(
535 *
M, IdentTy,
true, GlobalValue::PrivateLinkage,
nullptr, LocName);
536 SourceLocDummy->setAlignment(llvm::Align(8));
539 Constant *InitStr = ConstantDataArray::getString(
540 M->getContext(),
"Source location dummy.",
true);
542 Constant *StrPtr =
static_cast<Constant *
>(
Builder.CreateInBoundsGEP(
545 Constant *LocInitStruct = ConstantStruct::get(
550 StrVar->setInitializer(InitStr);
551 SourceLocDummy->setInitializer(LocInitStruct);
554 return SourceLocDummy;
558 return (
LongType->getIntegerBitWidth() == 64);
polly dump Polly Dump Function
void createCallStaticFini(Value *GlobalThreadID)
Create a runtime library call to mark the end of a statically scheduled loop.
Function * prepareSubFnDefinition(Function *F) const override
Prepare the definition of 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 createCallDispatchInit(Value *GlobalThreadID, Value *LB, Value *UB, Value *Inc, Value *ChunkSize)
Create a runtime library call to prepare the OpenMP runtime.
std::tuple< Value *, Function * > createSubFn(Value *Stride, AllocaInst *Struct, SetVector< Value * > UsedValues, ValueMapT &VMap) override
Create the parallel subfunction.
void createCallStaticInit(Value *GlobalThreadID, Value *IsLastPtr, Value *LBPtr, Value *UBPtr, Value *StridePtr, Value *ChunkSize)
Create a runtime library call to prepare the OpenMP runtime.
GlobalVariable * createSourceLocation()
Create the current source location.
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.
void createCallPushNumThreads(Value *GlobalThreadID, Value *NumThreads)
Create a runtime library call to request a number of threads.
OMPGeneralSchedulingType getSchedType(int ChunkSize, OMPGeneralSchedulingType Scheduling) const
Convert the combination of given chunk size and scheduling type (which might have been set via the co...
Value * createCallDispatchNext(Value *GlobalThreadID, Value *IsLastPtr, Value *LBPtr, Value *UBPtr, Value *StridePtr)
Create a runtime library call to retrieve the next (dynamically) allocated chunk of work for this thr...
bool is64BitArch()
Returns True if 'LongType' is 64bit wide, otherwise: False.
GlobalValue * SourceLocationInfo
The source location struct of this loop.
Value * createCallGlobalThreadNum()
Create a runtime library call to get the current global thread number.
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.
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
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.
OMPGeneralSchedulingType
General scheduling types of parallel OpenMP for loops.
llvm::DenseMap< llvm::AssertingVH< llvm::Value >, llvm::AssertingVH< llvm::Value > > ValueMapT
Type to remap values.