annotate polly/lib/CodeGen/LoopGeneratorsKMP.cpp @ 214:0cf2d4ade63d

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