Polly 20.0.0git
LoopGeneratorsKMP.cpp
Go to the documentation of this file.
1//===------ LoopGeneratorsKMP.cpp - IR helper to create loops -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains functions to create parallel loops as LLVM-IR.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/Analysis/LoopInfo.h"
15#include "llvm/IR/Dominators.h"
16#include "llvm/IR/Module.h"
17
18using namespace llvm;
19using namespace polly;
20
22 Value *SubFnParam,
23 Value *LB, Value *UB,
24 Value *Stride) {
25 const std::string Name = "__kmpc_fork_call";
26 Function *F = M->getFunction(Name);
27 Type *KMPCMicroTy = StructType::getTypeByName(M->getContext(), "kmpc_micro");
28
29 if (!KMPCMicroTy) {
30 // void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid, ...)
31 Type *MicroParams[] = {Builder.getInt32Ty()->getPointerTo(),
32 Builder.getInt32Ty()->getPointerTo()};
33
34 KMPCMicroTy = FunctionType::get(Builder.getVoidTy(), MicroParams, true);
35 }
36
37 // If F is not available, declare it.
38 if (!F) {
39 StructType *IdentTy =
40 StructType::getTypeByName(M->getContext(), "struct.ident_t");
41
42 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
43 Type *Params[] = {IdentTy->getPointerTo(), Builder.getInt32Ty(),
44 KMPCMicroTy->getPointerTo()};
45
46 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, true);
47 F = Function::Create(Ty, Linkage, Name, M);
48 }
49
50 Value *Task = Builder.CreatePointerBitCastOrAddrSpaceCast(
51 SubFn, KMPCMicroTy->getPointerTo());
52
53 Value *Args[] = {SourceLocationInfo,
54 Builder.getInt32(4) /* Number of arguments (w/o Task) */,
55 Task,
56 LB,
57 UB,
58 Stride,
59 SubFnParam};
60
61 CallInst *Call = Builder.CreateCall(F, Args);
62 Call->setDebugLoc(DLGenerated);
63}
64
66 Value *SubFnParam,
67 Value *LB, Value *UB,
68 Value *Stride) {
69 // Inform OpenMP runtime about the number of threads if greater than zero
70 if (PollyNumThreads > 0) {
71 Value *GlobalThreadID = createCallGlobalThreadNum();
72 createCallPushNumThreads(GlobalThreadID, Builder.getInt32(PollyNumThreads));
73 }
74
75 // Tell the runtime we start a parallel loop
76 createCallSpawnThreads(SubFn, SubFnParam, LB, UB, Stride);
77}
78
80 std::vector<Type *> Arguments = {Builder.getInt32Ty()->getPointerTo(),
81 Builder.getInt32Ty()->getPointerTo(),
85 Builder.getPtrTy()};
86
87 FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
88 Function *SubFn = Function::Create(FT, Function::InternalLinkage,
89 F->getName() + "_polly_subfn", M);
90 // Name the function's arguments
91 Function::arg_iterator AI = SubFn->arg_begin();
92 AI->setName("polly.kmpc.global_tid");
93 std::advance(AI, 1);
94 AI->setName("polly.kmpc.bound_tid");
95 std::advance(AI, 1);
96 AI->setName("polly.kmpc.lb");
97 std::advance(AI, 1);
98 AI->setName("polly.kmpc.ub");
99 std::advance(AI, 1);
100 AI->setName("polly.kmpc.inc");
101 std::advance(AI, 1);
102 AI->setName("polly.kmpc.shared");
103
104 return SubFn;
105}
106
107// Create a subfunction of the following (preliminary) structure:
108//
109// PrevBB
110// |
111// v
112// HeaderBB
113// / | _____
114// / v v |
115// / PreHeaderBB |
116// | | |
117// | v |
118// | CheckNextBB |
119// \ | \_____/
120// \ |
121// v v
122// ExitBB
123//
124// HeaderBB will hold allocations, loading of variables and kmp-init calls.
125// CheckNextBB will check for more work (dynamic / static chunked) or will be
126// empty (static non chunked).
127// If there is more work to do: go to PreHeaderBB, otherwise go to ExitBB.
128// PreHeaderBB loads the new boundaries (& will lead to the loop body later on).
129// Just like CheckNextBB: PreHeaderBB is (preliminary) empty in the static non
130// chunked scheduling case. ExitBB marks the end of the parallel execution.
131// The possibly empty BasicBlocks will automatically be removed.
132std::tuple<Value *, Function *>
133ParallelLoopGeneratorKMP::createSubFn(Value *SequentialLoopStride,
134 AllocaInst *StructData,
135 SetVector<Value *> Data, ValueMapT &Map) {
137 LLVMContext &Context = SubFn->getContext();
138
139 // Create basic blocks.
140 BasicBlock *HeaderBB = BasicBlock::Create(Context, "polly.par.setup", SubFn);
141 SubFnDT = std::make_unique<DominatorTree>(*SubFn);
142 SubFnLI = std::make_unique<LoopInfo>(*SubFnDT);
143
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);
149
150 SubFnDT->addNewBlock(ExitBB, HeaderBB);
151 SubFnDT->addNewBlock(CheckNextBB, HeaderBB);
152 SubFnDT->addNewBlock(PreHeaderBB, HeaderBB);
153
154 // Fill up basic block HeaderBB.
155 Builder.SetInsertPoint(HeaderBB);
156 Value *LBPtr = Builder.CreateAlloca(LongType, nullptr, "polly.par.LBPtr");
157 Value *UBPtr = Builder.CreateAlloca(LongType, nullptr, "polly.par.UBPtr");
158 Value *IsLastPtr = Builder.CreateAlloca(Builder.getInt32Ty(), nullptr,
159 "polly.par.lastIterPtr");
160 Value *StridePtr =
161 Builder.CreateAlloca(LongType, nullptr, "polly.par.StridePtr");
162
163 // Get iterator for retrieving the previously defined parameters.
164 Function::arg_iterator AI = SubFn->arg_begin();
165 // First argument holds "global thread ID".
166 Value *IDPtr = &*AI;
167 // Skip "bound thread ID" since it is not used (but had to be defined).
168 std::advance(AI, 2);
169 // Move iterator to: LB, UB, Stride, Shared variable struct.
170 Value *LB = &*AI;
171 std::advance(AI, 1);
172 Value *UB = &*AI;
173 std::advance(AI, 1);
174 Value *Stride = &*AI;
175 std::advance(AI, 1);
176 Value *Shared = &*AI;
177
178 extractValuesFromStruct(Data, StructData->getAllocatedType(), Shared, Map);
179
180 const auto Alignment = llvm::Align(is64BitArch() ? 8 : 4);
181 Value *ID = Builder.CreateAlignedLoad(Builder.getInt32Ty(), IDPtr, Alignment,
182 "polly.par.global_tid");
183
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);
188
189 // Subtract one as the upper bound provided by openmp is a < comparison
190 // whereas the codegenForSequential function creates a <= comparison.
191 Value *AdjustedUB = Builder.CreateAdd(UB, ConstantInt::get(LongType, -1),
192 "polly.indvar.UBAdjusted");
193
194 Value *ChunkSize =
195 ConstantInt::get(LongType, std::max<int>(PollyChunkSize, 1));
196
197 OMPGeneralSchedulingType Scheduling =
199
200 switch (Scheduling) {
204 // "DYNAMIC" scheduling types are handled below (including 'runtime')
205 {
206 UB = AdjustedUB;
207 createCallDispatchInit(ID, LB, UB, Stride, ChunkSize);
208 Value *HasWork =
209 createCallDispatchNext(ID, IsLastPtr, LBPtr, UBPtr, StridePtr);
210 Value *HasIteration =
211 Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_EQ, HasWork,
212 Builder.getInt32(1), "polly.hasIteration");
213 Builder.CreateCondBr(HasIteration, PreHeaderBB, ExitBB);
214
215 Builder.SetInsertPoint(CheckNextBB);
216 HasWork = createCallDispatchNext(ID, IsLastPtr, LBPtr, UBPtr, StridePtr);
217 HasIteration =
218 Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_EQ, HasWork,
219 Builder.getInt32(1), "polly.hasWork");
220 Builder.CreateCondBr(HasIteration, PreHeaderBB, ExitBB);
221
222 Builder.SetInsertPoint(PreHeaderBB);
223 LB = Builder.CreateAlignedLoad(LongType, LBPtr, Alignment,
224 "polly.indvar.LB");
225 UB = Builder.CreateAlignedLoad(LongType, UBPtr, Alignment,
226 "polly.indvar.UB");
227 }
228 break;
231 // "STATIC" scheduling types are handled below
232 {
233 Builder.CreateAlignedStore(AdjustedUB, UBPtr, Alignment);
234 createCallStaticInit(ID, IsLastPtr, LBPtr, UBPtr, StridePtr, ChunkSize);
235
236 Value *ChunkedStride = Builder.CreateAlignedLoad(
237 LongType, StridePtr, Alignment, "polly.kmpc.stride");
238
239 LB = Builder.CreateAlignedLoad(LongType, LBPtr, Alignment,
240 "polly.indvar.LB");
241 UB = Builder.CreateAlignedLoad(LongType, UBPtr, Alignment,
242 "polly.indvar.UB.temp");
243
244 Value *UBInRange =
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);
249
250 Value *HasIteration = Builder.CreateICmp(
251 llvm::CmpInst::Predicate::ICMP_SLE, LB, UB, "polly.hasIteration");
252 Builder.CreateCondBr(HasIteration, PreHeaderBB, ExitBB);
253
254 if (Scheduling == OMPGeneralSchedulingType::StaticChunked) {
255 Builder.SetInsertPoint(PreHeaderBB);
256 LB = Builder.CreateAlignedLoad(LongType, LBPtr, Alignment,
257 "polly.indvar.LB.entry");
258 UB = Builder.CreateAlignedLoad(LongType, UBPtr, Alignment,
259 "polly.indvar.UB.entry");
260 }
261
262 Builder.SetInsertPoint(CheckNextBB);
263
264 if (Scheduling == OMPGeneralSchedulingType::StaticChunked) {
265 Value *NextLB =
266 Builder.CreateAdd(LB, ChunkedStride, "polly.indvar.nextLB");
267 Value *NextUB = Builder.CreateAdd(UB, ChunkedStride);
268
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");
274
275 Builder.CreateAlignedStore(NextLB, LBPtr, Alignment);
276 Builder.CreateAlignedStore(NextUB, UBPtr, Alignment);
277
278 Value *HasWork =
279 Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_SLE, NextLB,
280 AdjustedUB, "polly.hasWork");
281 Builder.CreateCondBr(HasWork, PreHeaderBB, ExitBB);
282 } else {
283 Builder.CreateBr(ExitBB);
284 }
285
286 Builder.SetInsertPoint(PreHeaderBB);
287 }
288 break;
289 }
290
291 Builder.CreateBr(CheckNextBB);
292 Builder.SetInsertPoint(&*--Builder.GetInsertPoint());
293 BasicBlock *AfterBB;
294 Value *IV = createLoop(LB, UB, SequentialLoopStride, Builder, *SubFnLI,
295 *SubFnDT, AfterBB, ICmpInst::ICMP_SLE, nullptr, true,
296 /* UseGuard */ false);
297
298 BasicBlock::iterator LoopBody = Builder.GetInsertPoint();
299
300 // Add code to terminate this subfunction.
301 Builder.SetInsertPoint(ExitBB);
302 // Static (i.e. non-dynamic) scheduling types, are terminated with a fini-call
303 if (Scheduling == OMPGeneralSchedulingType::StaticChunked ||
306 }
307 Builder.CreateRetVoid();
308 Builder.SetInsertPoint(&*LoopBody);
309
310 // FIXME: Call SubFnDT->verify() and SubFnLI->verify() to check that the
311 // DominatorTree/LoopInfo has been created correctly. Alternatively, recreate
312 // from scratch since it is not needed here directly.
313
314 return std::make_tuple(IV, SubFn);
315}
316
318 const std::string Name = "__kmpc_global_thread_num";
319 Function *F = M->getFunction(Name);
320
321 // If F is not available, declare it.
322 if (!F) {
323 StructType *IdentTy =
324 StructType::getTypeByName(M->getContext(), "struct.ident_t");
325
326 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
327 Type *Params[] = {IdentTy->getPointerTo()};
328
329 FunctionType *Ty = FunctionType::get(Builder.getInt32Ty(), Params, false);
330 F = Function::Create(Ty, Linkage, Name, M);
331 }
332
333 CallInst *Call = Builder.CreateCall(F, {SourceLocationInfo});
334 Call->setDebugLoc(DLGenerated);
335 return Call;
336}
337
339 Value *NumThreads) {
340 const std::string Name = "__kmpc_push_num_threads";
341 Function *F = M->getFunction(Name);
342
343 // If F is not available, declare it.
344 if (!F) {
345 StructType *IdentTy =
346 StructType::getTypeByName(M->getContext(), "struct.ident_t");
347
348 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
349 Type *Params[] = {IdentTy->getPointerTo(), Builder.getInt32Ty(),
350 Builder.getInt32Ty()};
351
352 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
353 F = Function::Create(Ty, Linkage, Name, M);
354 }
355
356 Value *Args[] = {SourceLocationInfo, GlobalThreadID, NumThreads};
357
358 CallInst *Call = Builder.CreateCall(F, Args);
359 Call->setDebugLoc(DLGenerated);
360}
361
363 Value *IsLastPtr,
364 Value *LBPtr, Value *UBPtr,
365 Value *StridePtr,
366 Value *ChunkSize) {
367 const std::string Name =
368 is64BitArch() ? "__kmpc_for_static_init_8" : "__kmpc_for_static_init_4";
369 Function *F = M->getFunction(Name);
370 StructType *IdentTy =
371 StructType::getTypeByName(M->getContext(), "struct.ident_t");
372
373 // If F is not available, declare it.
374 if (!F) {
375 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
376
377 Type *Params[] = {IdentTy->getPointerTo(),
378 Builder.getInt32Ty(),
379 Builder.getInt32Ty(),
380 Builder.getInt32Ty()->getPointerTo(),
381 LongType->getPointerTo(),
382 LongType->getPointerTo(),
383 LongType->getPointerTo(),
384 LongType,
385 LongType};
386
387 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
388 F = Function::Create(Ty, Linkage, Name, M);
389 }
390
391 // The parameter 'ChunkSize' will hold strictly positive integer values,
392 // regardless of PollyChunkSize's value
393 Value *Args[] = {
395 GlobalThreadID,
397 IsLastPtr,
398 LBPtr,
399 UBPtr,
400 StridePtr,
401 ConstantInt::get(LongType, 1),
402 ChunkSize};
403
404 CallInst *Call = Builder.CreateCall(F, Args);
405 Call->setDebugLoc(DLGenerated);
406}
407
409 const std::string Name = "__kmpc_for_static_fini";
410 Function *F = M->getFunction(Name);
411 StructType *IdentTy =
412 StructType::getTypeByName(M->getContext(), "struct.ident_t");
413
414 // If F is not available, declare it.
415 if (!F) {
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);
420 }
421
422 Value *Args[] = {SourceLocationInfo, GlobalThreadID};
423
424 CallInst *Call = Builder.CreateCall(F, Args);
425 Call->setDebugLoc(DLGenerated);
426}
427
429 Value *LB, Value *UB,
430 Value *Inc,
431 Value *ChunkSize) {
432 const std::string Name =
433 is64BitArch() ? "__kmpc_dispatch_init_8" : "__kmpc_dispatch_init_4";
434 Function *F = M->getFunction(Name);
435 StructType *IdentTy =
436 StructType::getTypeByName(M->getContext(), "struct.ident_t");
437
438 // If F is not available, declare it.
439 if (!F) {
440 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
441
442 Type *Params[] = {IdentTy->getPointerTo(),
443 Builder.getInt32Ty(),
444 Builder.getInt32Ty(),
445 LongType,
446 LongType,
447 LongType,
448 LongType};
449
450 FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
451 F = Function::Create(Ty, Linkage, Name, M);
452 }
453
454 // The parameter 'ChunkSize' will hold strictly positive integer values,
455 // regardless of PollyChunkSize's value
456 Value *Args[] = {
458 GlobalThreadID,
460 LB,
461 UB,
462 Inc,
463 ChunkSize};
464
465 CallInst *Call = Builder.CreateCall(F, Args);
466 Call->setDebugLoc(DLGenerated);
467}
468
470 Value *IsLastPtr,
471 Value *LBPtr,
472 Value *UBPtr,
473 Value *StridePtr) {
474 const std::string Name =
475 is64BitArch() ? "__kmpc_dispatch_next_8" : "__kmpc_dispatch_next_4";
476 Function *F = M->getFunction(Name);
477 StructType *IdentTy =
478 StructType::getTypeByName(M->getContext(), "struct.ident_t");
479
480 // If F is not available, declare it.
481 if (!F) {
482 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
483
484 Type *Params[] = {IdentTy->getPointerTo(),
485 Builder.getInt32Ty(),
486 Builder.getInt32Ty()->getPointerTo(),
487 LongType->getPointerTo(),
488 LongType->getPointerTo(),
489 LongType->getPointerTo()};
490
491 FunctionType *Ty = FunctionType::get(Builder.getInt32Ty(), Params, false);
492 F = Function::Create(Ty, Linkage, Name, M);
493 }
494
495 Value *Args[] = {SourceLocationInfo, GlobalThreadID, IsLastPtr, LBPtr, UBPtr,
496 StridePtr};
497
498 CallInst *Call = Builder.CreateCall(F, Args);
499 Call->setDebugLoc(DLGenerated);
500 return Call;
501}
502
503// TODO: This function currently creates a source location dummy. It might be
504// necessary to (actually) provide information, in the future.
506 const std::string LocName = ".loc.dummy";
507 GlobalVariable *SourceLocDummy = M->getGlobalVariable(LocName);
508
509 if (SourceLocDummy == nullptr) {
510 const std::string StructName = "struct.ident_t";
511 StructType *IdentTy =
512 StructType::getTypeByName(M->getContext(), StructName);
513
514 // If the ident_t StructType is not available, declare it.
515 // in LLVM-IR: ident_t = type { i32, i32, i32, i32, i8* }
516 if (!IdentTy) {
517 Type *LocMembers[] = {Builder.getInt32Ty(), Builder.getInt32Ty(),
518 Builder.getInt32Ty(), Builder.getInt32Ty(),
519 Builder.getPtrTy()};
520
521 IdentTy =
522 StructType::create(M->getContext(), LocMembers, StructName, false);
523 }
524
525 const auto ArrayType =
526 llvm::ArrayType::get(Builder.getInt8Ty(), /* Length */ 23);
527
528 // Global Variable Definitions
529 GlobalVariable *StrVar =
530 new GlobalVariable(*M, ArrayType, true, GlobalValue::PrivateLinkage,
531 nullptr, ".str.ident");
532 StrVar->setAlignment(llvm::Align(1));
533
534 SourceLocDummy = new GlobalVariable(
535 *M, IdentTy, true, GlobalValue::PrivateLinkage, nullptr, LocName);
536 SourceLocDummy->setAlignment(llvm::Align(8));
537
538 // Constant Definitions
539 Constant *InitStr = ConstantDataArray::getString(
540 M->getContext(), "Source location dummy.", true);
541
542 Constant *StrPtr = static_cast<Constant *>(Builder.CreateInBoundsGEP(
543 ArrayType, StrVar, {Builder.getInt32(0), Builder.getInt32(0)}));
544
545 Constant *LocInitStruct = ConstantStruct::get(
546 IdentTy, {Builder.getInt32(0), Builder.getInt32(0), Builder.getInt32(0),
547 Builder.getInt32(0), StrPtr});
548
549 // Initialize variables
550 StrVar->setInitializer(InitStr);
551 SourceLocDummy->setInitializer(LocInitStruct);
552 }
553
554 return SourceLocDummy;
555}
556
558 return (LongType->getIntegerBitWidth() == 64);
559}
560
562 int ChunkSize, OMPGeneralSchedulingType Scheduling) const {
563 if (ChunkSize == 0 && Scheduling == OMPGeneralSchedulingType::StaticChunked)
565
566 return Scheduling;
567}
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
int PollyNumThreads
@ Value
MemoryKind::Value: Models an llvm::Value.
int PollyChunkSize
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.
Definition: ScopHelper.h:106