Polly 23.0.0git
IslNodeBuilder.cpp
Go to the documentation of this file.
1//===- IslNodeBuilder.cpp - Translate an isl AST into a LLVM-IR AST -------===//
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 the IslNodeBuilder, a class to translate an isl AST into
10// a LLVM-IR AST.
11//
12//===----------------------------------------------------------------------===//
13
22#include "polly/Options.h"
23#include "polly/ScopInfo.h"
28#include "llvm/ADT/APInt.h"
29#include "llvm/ADT/PostOrderIterator.h"
30#include "llvm/ADT/SetVector.h"
31#include "llvm/ADT/SmallPtrSet.h"
32#include "llvm/ADT/Statistic.h"
33#include "llvm/Analysis/AssumptionCache.h"
34#include "llvm/Analysis/LoopInfo.h"
35#include "llvm/Analysis/RegionInfo.h"
36#include "llvm/Analysis/ScalarEvolution.h"
37#include "llvm/Analysis/ScalarEvolutionExpressions.h"
38#include "llvm/Analysis/TargetLibraryInfo.h"
39#include "llvm/IR/BasicBlock.h"
40#include "llvm/IR/Constant.h"
41#include "llvm/IR/Constants.h"
42#include "llvm/IR/DataLayout.h"
43#include "llvm/IR/DerivedTypes.h"
44#include "llvm/IR/Dominators.h"
45#include "llvm/IR/Function.h"
46#include "llvm/IR/InstrTypes.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/Instructions.h"
49#include "llvm/IR/Module.h"
50#include "llvm/IR/Type.h"
51#include "llvm/IR/Value.h"
52#include "llvm/Support/Casting.h"
53#include "llvm/Support/CommandLine.h"
54#include "llvm/Support/ErrorHandling.h"
55#include "llvm/TargetParser/Triple.h"
56#include "llvm/Transforms/Utils/BasicBlockUtils.h"
57#include "isl/aff.h"
58#include "isl/aff_type.h"
59#include "isl/ast.h"
60#include "isl/ast_build.h"
62#include "isl/map.h"
63#include "isl/set.h"
64#include "isl/union_map.h"
65#include "isl/union_set.h"
66#include "isl/val.h"
67#include <algorithm>
68#include <cassert>
69#include <cstdint>
70#include <cstring>
71#include <string>
72#include <utility>
73#include <vector>
74
75using namespace llvm;
76using namespace polly;
77
78#define DEBUG_TYPE "polly-codegen"
79
80STATISTIC(VersionedScops, "Number of SCoPs that required versioning.");
81
82STATISTIC(SequentialLoops, "Number of generated sequential for-loops");
83STATISTIC(ParallelLoops, "Number of generated parallel for-loops");
84STATISTIC(IfConditions, "Number of generated if-conditions");
85
86/// OpenMP backend options
87enum class OpenMPBackend { GNU, LLVM };
88
89static cl::opt<bool> PollyGenerateRTCPrint(
90 "polly-codegen-emit-rtc-print",
91 cl::desc("Emit code that prints the runtime check result dynamically."),
92 cl::Hidden, cl::cat(PollyCategory));
93
94// If this option is set we always use the isl AST generator to regenerate
95// memory accesses. Without this option set we regenerate expressions using the
96// original SCEV expressions and only generate new expressions in case the
97// access relation has been changed and consequently must be regenerated.
98static cl::opt<bool> PollyGenerateExpressions(
99 "polly-codegen-generate-expressions",
100 cl::desc("Generate AST expressions for unmodified and modified accesses"),
101 cl::Hidden, cl::cat(PollyCategory));
102
104 "polly-target-first-level-cache-line-size",
105 cl::desc("The size of the first level cache line size specified in bytes."),
106 cl::Hidden, cl::init(64), cl::cat(PollyCategory));
107
108static cl::opt<OpenMPBackend> PollyOmpBackend(
109 "polly-omp-backend", cl::desc("Choose the OpenMP library to use:"),
110 cl::values(clEnumValN(OpenMPBackend::GNU, "GNU", "GNU OpenMP"),
111 clEnumValN(OpenMPBackend::LLVM, "LLVM", "LLVM OpenMP")),
112 cl::Hidden, cl::init(OpenMPBackend::GNU), cl::cat(PollyCategory));
113
115 ICmpInst::Predicate &Predicate) {
116 isl::ast_expr Cond = For.cond();
117 isl::ast_expr Iterator = For.iterator();
119 "conditional expression is not an atomic upper bound");
120
122
123 switch (OpType) {
124 case isl_ast_op_le:
125 Predicate = ICmpInst::ICMP_SLE;
126 break;
127 case isl_ast_op_lt:
128 Predicate = ICmpInst::ICMP_SLT;
129 break;
130 default:
131 llvm_unreachable("Unexpected comparison type in loop condition");
132 }
133
134 isl::ast_expr Arg0 = Cond.get_op_arg(0);
135
137 "conditional expression is not an atomic upper bound");
138
139 isl::id UBID = Arg0.get_id();
140
142 "Could not get the iterator");
143
144 isl::id IteratorID = Iterator.get_id();
145
146 assert(UBID.get() == IteratorID.get() &&
147 "conditional expression is not an atomic upper bound");
148
149 return Cond.get_op_arg(1);
150}
151
154 isl::ast_node Body = For.body();
155
156 // First, check if we can actually handle this code.
157 switch (isl_ast_node_get_type(Body.get())) {
159 break;
160 case isl_ast_node_block: {
161 isl::ast_node_block BodyBlock = Body.as<isl::ast_node_block>();
162 isl::ast_node_list List = BodyBlock.children();
163 for (isl::ast_node Node : List) {
164 isl_ast_node_type NodeType = isl_ast_node_get_type(Node.get());
165 if (NodeType != isl_ast_node_user)
166 return -1;
167 }
168 break;
169 }
170 default:
171 return -1;
172 }
173
174 isl::ast_expr Init = For.init();
175 if (!Init.isa<isl::ast_expr_int>() || !Init.val().is_zero())
176 return -1;
177 isl::ast_expr Inc = For.inc();
178 if (!Inc.isa<isl::ast_expr_int>() || !Inc.val().is_one())
179 return -1;
180 CmpInst::Predicate Predicate;
181 isl::ast_expr UB = getUpperBound(For, Predicate);
182 if (!UB.isa<isl::ast_expr_int>())
183 return -1;
184 isl::val UpVal = UB.get_val();
185 int NumberIterations = UpVal.get_num_si();
186 if (NumberIterations < 0)
187 return -1;
188 if (Predicate == CmpInst::ICMP_SLT)
189 return NumberIterations;
190 else
191 return NumberIterations + 1;
192}
193
194static void findReferencesByUse(Value *SrcVal, ScopStmt *UserStmt,
195 Loop *UserScope, const ValueMapT &GlobalMap,
196 SetVector<Value *> &Values,
197 SetVector<const SCEV *> &SCEVs) {
198 VirtualUse VUse = VirtualUse::create(UserStmt, UserScope, SrcVal, true);
199 switch (VUse.getKind()) {
201 // When accelerator-offloading, GlobalValue is a host address whose content
202 // must still be transferred to the GPU.
203 if (isa<GlobalValue>(SrcVal))
204 Values.insert(SrcVal);
205 break;
206
208 SCEVs.insert(VUse.getScevExpr());
209 return;
210
216 break;
217 }
218
219 if (Value *NewVal = GlobalMap.lookup(SrcVal))
220 Values.insert(NewVal);
221}
222
223static void findReferencesInInst(Instruction *Inst, ScopStmt *UserStmt,
224 Loop *UserScope, const ValueMapT &GlobalMap,
225 SetVector<Value *> &Values,
226 SetVector<const SCEV *> &SCEVs) {
227 for (Use &U : Inst->operands())
228 findReferencesByUse(U.get(), UserStmt, UserScope, GlobalMap, Values, SCEVs);
229}
230
231static void findReferencesInStmt(ScopStmt *Stmt, SetVector<Value *> &Values,
232 ValueMapT &GlobalMap,
233 SetVector<const SCEV *> &SCEVs) {
234 LoopInfo *LI = Stmt->getParent()->getLI();
235
236 BasicBlock *BB = Stmt->getBasicBlock();
237 // TODO: Should BB ever be null?
238 Loop *Scope = BB ? LI->getLoopFor(BB) : nullptr;
239 for (Instruction *Inst : Stmt->getInstructions())
240 findReferencesInInst(Inst, Stmt, Scope, GlobalMap, Values, SCEVs);
241
242 if (Stmt->isRegionStmt()) {
243 for (BasicBlock *BB : Stmt->getRegion()->blocks()) {
244 Loop *Scope = LI->getLoopFor(BB);
245 for (Instruction &Inst : *BB)
246 findReferencesInInst(&Inst, Stmt, Scope, GlobalMap, Values, SCEVs);
247 }
248 }
249}
250
251void polly::addReferencesFromStmt(ScopStmt *Stmt, void *UserPtr,
252 bool CreateScalarRefs) {
253 auto &References = *static_cast<SubtreeReferences *>(UserPtr);
254
255 findReferencesInStmt(Stmt, References.Values, References.GlobalMap,
256 References.SCEVs);
257
258 for (auto &Access : *Stmt) {
259 if (References.ParamSpace) {
260 isl::space ParamSpace = Access->getLatestAccessRelation().get_space();
261 (*References.ParamSpace) =
262 References.ParamSpace->align_params(ParamSpace);
263 }
264
265 if (Access->isLatestArrayKind()) {
266 auto *BasePtr = Access->getLatestScopArrayInfo()->getBasePtr();
267 if (Instruction *OpInst = dyn_cast<Instruction>(BasePtr))
268 if (Stmt->getParent()->contains(OpInst))
269 continue;
270
271 References.Values.insert(BasePtr);
272 continue;
273 }
274
275 if (CreateScalarRefs)
276 References.Values.insert(References.BlockGen.getOrCreateAlloca(*Access));
277 }
278}
279
280/// Extract the out-of-scop values and SCEVs referenced from a set describing
281/// a ScopStmt.
282///
283/// This includes the SCEVUnknowns referenced by the SCEVs used in the
284/// statement and the base pointers of the memory accesses. For scalar
285/// statements we force the generation of alloca memory locations and list
286/// these locations in the set of out-of-scop values as well.
287///
288/// @param Set A set which references the ScopStmt we are interested in.
289/// @param UserPtr A void pointer that can be casted to a SubtreeReferences
290/// structure.
292 isl::id Id = Set.get_tuple_id();
293 auto *Stmt = static_cast<ScopStmt *>(Id.get_user());
294 addReferencesFromStmt(Stmt, UserPtr);
295}
296
297/// Extract the out-of-scop values and SCEVs referenced from a union set
298/// referencing multiple ScopStmts.
299///
300/// This includes the SCEVUnknowns referenced by the SCEVs used in the
301/// statement and the base pointers of the memory accesses. For scalar
302/// statements we force the generation of alloca memory locations and list
303/// these locations in the set of out-of-scop values as well.
304///
305/// @param USet A union set referencing the ScopStmts we are interested
306/// in.
307/// @param References The SubtreeReferences data structure through which
308/// results are returned and further information is
309/// provided.
311 SubtreeReferences &References) {
312
313 for (isl::set Set : USet.get_set_list())
314 addReferencesFromStmtSet(Set, &References);
315}
316
317isl::union_map
321
323 SetVector<Value *> &Values,
324 SetVector<const Loop *> &Loops) {
325 SetVector<const SCEV *> SCEVs;
326 SubtreeReferences References = {
327 LI, SE, S, ValueMap, Values, SCEVs, getBlockGenerator(), nullptr};
328
329 Values.insert_range(llvm::make_second_range(IDToValue));
330
331 // NOTE: this is populated in IslNodeBuilder::addParameters
332 for (const auto &I : OutsideLoopIterations)
333 Values.insert(cast<SCEVUnknown>(I.second)->getValue());
334
336 addReferencesFromStmtUnionSet(Schedule, References);
337
338 for (const SCEV *Expr : SCEVs) {
339 findValues(Expr, SE, Values);
340 findLoops(Expr, Loops);
341 }
342
343 Values.remove_if([](const Value *V) { return isa<GlobalValue>(V); });
344
345 /// Note: Code generation of induction variables of loops outside Scops
346 ///
347 /// Remove loops that contain the scop or that are part of the scop, as they
348 /// are considered local. This leaves only loops that are before the scop, but
349 /// do not contain the scop itself.
350 /// We ignore loops perfectly contained in the Scop because these are already
351 /// generated at `IslNodeBuilder::addParameters`. These `Loops` are loops
352 /// whose induction variables are referred to by the Scop, but the Scop is not
353 /// fully contained in these Loops. Since there can be many of these,
354 /// we choose to codegen these on-demand.
355 /// @see IslNodeBuilder::materializeNonScopLoopInductionVariable.
356 Loops.remove_if([this](const Loop *L) {
357 return S.contains(L) || L->contains(S.getEntry());
358 });
359
360 // Contains Values that may need to be replaced with other values
361 // due to replacements from the ValueMap. We should make sure
362 // that we return correctly remapped values.
363 // NOTE: this code path is tested by:
364 // 1. test/Isl/CodeGen/OpenMP/single_loop_with_loop_invariant_baseptr.ll
365 // 2. test/Isl/CodeGen/OpenMP/loop-body-references-outer-values-3.ll
366 SetVector<Value *> ReplacedValues;
367 for (Value *V : Values) {
368 ReplacedValues.insert(getLatestValue(V));
369 }
370 Values = ReplacedValues;
371}
372
374 auto It = ValueMap.find(Original);
375 if (It == ValueMap.end())
376 return Original;
377 return It->second;
378}
379
381 auto *Id = isl_ast_node_mark_get_id(Node);
382 auto Child = isl_ast_node_mark_get_node(Node);
383 isl_ast_node_free(Node);
384 // If a child node of a 'SIMD mark' is a loop that has a single iteration,
385 // it will be optimized away and we should skip it.
386 if (strcmp(isl_id_get_name(Id), "SIMD") == 0 &&
388 createForSequential(isl::manage(Child).as<isl::ast_node_for>(), true);
389 isl_id_free(Id);
390 return;
391 }
392
393 BandAttr *ChildLoopAttr = getLoopAttr(isl::manage_copy(Id));
394 BandAttr *AncestorLoopAttr;
395 if (ChildLoopAttr) {
396 // Save current LoopAttr environment to restore again when leaving this
397 // subtree. This means there was no loop between the ancestor LoopAttr and
398 // this mark, i.e. the ancestor LoopAttr did not directly mark a loop. This
399 // can happen e.g. if the AST build peeled or unrolled the loop.
400 AncestorLoopAttr = Annotator.getStagingAttrEnv();
401
402 Annotator.getStagingAttrEnv() = ChildLoopAttr;
403 }
404
405 create(Child);
406
407 if (ChildLoopAttr) {
408 assert(Annotator.getStagingAttrEnv() == ChildLoopAttr &&
409 "Nest must not overwrite loop attr environment");
410 Annotator.getStagingAttrEnv() = AncestorLoopAttr;
411 }
412
413 isl_id_free(Id);
414}
415
416/// Restore the initial ordering of dimensions of the band node
417///
418/// In case the band node represents all the dimensions of the iteration
419/// domain, recreate the band node to restore the initial ordering of the
420/// dimensions.
421///
422/// @param Node The band node to be modified.
423/// @return The modified schedule node.
426 isl::ast_node Body = Node.body();
428 return false;
429
430 isl::ast_node_mark BodyMark = Body.as<isl::ast_node_mark>();
431 auto Id = BodyMark.id();
432 if (strcmp(Id.get_name().c_str(), "Loop Vectorizer Disabled") == 0)
433 return true;
434 return false;
435}
436
438 bool MarkParallel) {
439 Value *ValueLB, *ValueUB, *ValueInc;
440 Type *MaxType;
441 BasicBlock *ExitBlock;
442 Value *IV;
443 CmpInst::Predicate Predicate;
444
445 bool LoopVectorizerDisabled = IsLoopVectorizerDisabled(For);
446
447 isl::ast_node Body = For.body();
448
449 // isl_ast_node_for_is_degenerate(For)
450 //
451 // TODO: For degenerated loops we could generate a plain assignment.
452 // However, for now we just reuse the logic for normal loops, which will
453 // create a loop with a single iteration.
454
455 isl::ast_expr Init = For.init();
456 isl::ast_expr Inc = For.inc();
457 isl::ast_expr Iterator = For.iterator();
458 isl::id IteratorID = Iterator.get_id();
459 isl::ast_expr UB = getUpperBound(For, Predicate);
460
461 ValueLB = ExprBuilder.create(Init.release());
462 ValueUB = ExprBuilder.create(UB.release());
463 ValueInc = ExprBuilder.create(Inc.release());
464
465 MaxType = ExprBuilder.getType(Iterator.get());
466 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
467 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
468 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
469
470 if (MaxType != ValueLB->getType())
471 ValueLB = Builder.CreateSExt(ValueLB, MaxType);
472 if (MaxType != ValueUB->getType())
473 ValueUB = Builder.CreateSExt(ValueUB, MaxType);
474 if (MaxType != ValueInc->getType())
475 ValueInc = Builder.CreateSExt(ValueInc, MaxType);
476
477 // If we can show that LB <Predicate> UB holds at least once, we can
478 // omit the GuardBB in front of the loop.
479 bool UseGuardBB = !GenSE->isKnownPredicate(Predicate, GenSE->getSCEV(ValueLB),
480 GenSE->getSCEV(ValueUB));
481 IV = createLoop(ValueLB, ValueUB, ValueInc, Builder, *GenLI, *GenDT,
482 ExitBlock, Predicate, &Annotator, MarkParallel, UseGuardBB,
483 LoopVectorizerDisabled);
484 IDToValue[IteratorID.get()] = IV;
485
486 create(Body.release());
487
488 Annotator.popLoop(MarkParallel);
489
490 IDToValue.erase(IDToValue.find(IteratorID.get()));
491
492 Builder.SetInsertPoint(ExitBlock, ExitBlock->begin());
493
494 SequentialLoops++;
495}
496
498 isl_ast_node *Body;
499 isl_ast_expr *Init, *Inc, *Iterator, *UB;
500 isl_id *IteratorID;
501 Value *ValueLB, *ValueUB, *ValueInc;
502 Type *MaxType;
503 Value *IV;
504 CmpInst::Predicate Predicate;
505
506 // The preamble of parallel code interacts different than normal code with
507 // e.g., scalar initialization. Therefore, we ensure the parallel code is
508 // separated from the last basic block.
509 BasicBlock *ParBB =
510 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), &DT, &LI);
511 ParBB->setName("polly.parallel.for");
512 Builder.SetInsertPoint(ParBB, ParBB->begin());
513
514 Body = isl_ast_node_for_get_body(For);
515 Init = isl_ast_node_for_get_init(For);
516 Inc = isl_ast_node_for_get_inc(For);
517 Iterator = isl_ast_node_for_get_iterator(For);
518 IteratorID = isl_ast_expr_get_id(Iterator);
519 UB = getUpperBound(isl::manage_copy(For).as<isl::ast_node_for>(), Predicate)
520 .release();
521
522 ValueLB = ExprBuilder.create(Init);
523 ValueUB = ExprBuilder.create(UB);
524 ValueInc = ExprBuilder.create(Inc);
525
526 // OpenMP always uses SLE. In case the isl generated AST uses a SLT
527 // expression, we need to adjust the loop bound by one.
528 if (Predicate == CmpInst::ICMP_SLT)
529 ValueUB = Builder.CreateAdd(
530 ValueUB, Builder.CreateSExt(Builder.getTrue(), ValueUB->getType()));
531
532 MaxType = ExprBuilder.getType(Iterator);
533 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
534 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
535 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
536
537 if (MaxType != ValueLB->getType())
538 ValueLB = Builder.CreateSExt(ValueLB, MaxType);
539 if (MaxType != ValueUB->getType())
540 ValueUB = Builder.CreateSExt(ValueUB, MaxType);
541 if (MaxType != ValueInc->getType())
542 ValueInc = Builder.CreateSExt(ValueInc, MaxType);
543
544 BasicBlock::iterator LoopBody;
545
546 SetVector<Value *> SubtreeValues;
547 SetVector<const Loop *> Loops;
548
549 getReferencesInSubtree(isl::manage_copy(For), SubtreeValues, Loops);
550
551 // Create for all loops we depend on values that contain the current loop
552 // iteration. These values are necessary to generate code for SCEVs that
553 // depend on such loops. As a result we need to pass them to the subfunction.
554 // See [Code generation of induction variables of loops outside Scops]
555 for (const Loop *L : Loops) {
556 Value *LoopInductionVar = materializeNonScopLoopInductionVariable(L);
557 SubtreeValues.insert(LoopInductionVar);
558 }
559
560 ValueMapT NewValues;
561
562 std::unique_ptr<ParallelLoopGenerator> ParallelLoopGenPtr;
563
564 switch (PollyOmpBackend) {
566 ParallelLoopGenPtr.reset(new ParallelLoopGeneratorGOMP(Builder, DL));
567 break;
569 ParallelLoopGenPtr.reset(new ParallelLoopGeneratorKMP(Builder, DL));
570 break;
571 }
572
573 IV = ParallelLoopGenPtr->createParallelLoop(
574 ValueLB, ValueUB, ValueInc, SubtreeValues, NewValues, &LoopBody);
575 BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
576
577 // Remember the parallel subfunction
578 Function *SubFn = LoopBody->getFunction();
579 ParallelSubfunctions.push_back(SubFn);
580
581 // We start working on the outlined function. Since DominatorTree/LoopInfo are
582 // not an inter-procedural passes, we temporarily switch them out. Save the
583 // old ones first.
584 Function *CallerFn = Builder.GetInsertBlock()->getParent();
585 DominatorTree *CallerDT = GenDT;
586 LoopInfo *CallerLI = GenLI;
587 ScalarEvolution *CallerSE = GenSE;
588 ValueMapT CallerGlobals = ValueMap;
590
591 // Get the analyses for the subfunction. ParallelLoopGenerator already create
592 // DominatorTree and LoopInfo for us.
593 DominatorTree *SubDT = ParallelLoopGenPtr->getCalleeDominatorTree();
594 LoopInfo *SubLI = ParallelLoopGenPtr->getCalleeLoopInfo();
595
596 // Create TargetLibraryInfo, AssumptionCachem and ScalarEvolution ourselves.
597 // TODO: Ideally, we would use the pass manager's TargetLibraryInfoPass and
598 // AssumptionAnalysis instead of our own. They contain more target-specific
599 // information than we have available here: TargetLibraryInfoImpl can be a
600 // derived class determined by TargetMachine, AssumptionCache can be
601 // configured using a TargetTransformInfo object also derived from
602 // TargetMachine.
603 TargetLibraryInfoImpl BaselineInfoImpl(SubFn->getParent()->getTargetTriple());
604 TargetLibraryInfo CalleeTLI(BaselineInfoImpl, SubFn);
605 AssumptionCache CalleeAC(*SubFn);
606 std::unique_ptr<ScalarEvolution> SubSE = std::make_unique<ScalarEvolution>(
607 *SubFn, CalleeTLI, CalleeAC, *SubDT, *SubLI);
608
609 // Switch to the subfunction
610 GenDT = SubDT;
611 GenLI = SubLI;
612 GenSE = SubSE.get();
613 BlockGen.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
614 RegionGen.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
615 ExprBuilder.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
616 Builder.SetInsertPoint(LoopBody);
617
618 // Update the ValueMap to use instructions in the subfunction. Note that
619 // "GlobalMap" used in BlockGenerator/IslExprBuilder is a reference to this
620 // ValueMap.
621 for (auto &[OldVal, NewVal] : ValueMap) {
622 NewVal = NewValues.lookup(NewVal);
623
624 // Clean-up any value that getReferencesInSubtree thinks we do not need.
625 // DenseMap::erase only writes a tombstone (and destroys OldVal/NewVal), so
626 // does not invalidate our iterator.
627 if (!NewVal)
628 ValueMap.erase(OldVal);
629 }
630
631 // This is for NewVals that do not appear in ValueMap (such as SCoP-invariant
632 // values whose original value can be reused as long as we are in the same
633 // function). No need to map the others.
634 for (auto &[NewVal, NewNewVal] : NewValues) {
635 if (Instruction *NewValInst = dyn_cast<Instruction>((Value *)NewVal)) {
636 if (S.contains(NewValInst))
637 continue;
638 assert(NewValInst->getFunction() == &S.getFunction());
639 }
640 assert(!ValueMap.contains(NewVal));
641 ValueMap[NewVal] = NewNewVal;
642 }
643
644 // Also update the IDToValue map to use instructions from the subfunction.
645 for (auto &[OldVal, NewVal] : IDToValue) {
646 NewVal = NewValues.lookup(NewVal);
647 assert(NewVal);
648 }
649 IDToValue[IteratorID] = IV;
650
651#ifndef NDEBUG
652 // Check whether the maps now exclusively refer to SubFn values.
653 for (auto &[OldVal, SubVal] : ValueMap) {
654 Instruction *SubInst = dyn_cast<Instruction>((Value *)SubVal);
655 assert(SubInst->getFunction() == SubFn &&
656 "Instructions from outside the subfn cannot be accessed within the "
657 "subfn");
658 }
659 for (auto &[Id, SubVal] : IDToValue) {
660 Instruction *SubInst = dyn_cast<Instruction>((Value *)SubVal);
661 assert(SubInst->getFunction() == SubFn &&
662 "Instructions from outside the subfn cannot be accessed within the "
663 "subfn");
664 }
665#endif
666
667 ValueMapT NewValuesReverse;
668 for (auto P : NewValues)
669 NewValuesReverse[P.second] = P.first;
670
671 Annotator.addAlternativeAliasBases(NewValuesReverse);
672
673 create(Body);
674
675 Annotator.resetAlternativeAliasBases();
676
677 // Resume working on the caller function.
678 GenDT = CallerDT;
679 GenLI = CallerLI;
680 GenSE = CallerSE;
681 IDToValue = std::move(IDToValueCopy);
682 ValueMap = std::move(CallerGlobals);
683 ExprBuilder.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
684 RegionGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
685 BlockGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
686 Builder.SetInsertPoint(AfterLoop);
687
688 for (const Loop *L : Loops)
689 OutsideLoopIterations.erase(L);
690
692 isl_ast_expr_free(Iterator);
693 isl_id_free(IteratorID);
694
695 ParallelLoops++;
696}
697
701 return;
702 }
703 bool Parallel = (IslAstInfo::isParallel(isl::manage_copy(For)) &&
705 createForSequential(isl::manage(For).as<isl::ast_node_for>(), Parallel);
706}
707
710
711 Function *F = Builder.GetInsertBlock()->getParent();
712 LLVMContext &Context = F->getContext();
713
714 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
715 Builder.GetInsertPoint(), GenDT, GenLI);
716 CondBB->setName("polly.cond");
717 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), GenDT, GenLI);
718 MergeBB->setName("polly.merge");
719 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
720 BasicBlock *ElseBB = BasicBlock::Create(Context, "polly.else", F);
721
722 GenDT->addNewBlock(ThenBB, CondBB);
723 GenDT->addNewBlock(ElseBB, CondBB);
724 GenDT->changeImmediateDominator(MergeBB, CondBB);
725
726 Loop *L = GenLI->getLoopFor(CondBB);
727 if (L) {
728 L->addBasicBlockToLoop(ThenBB, *GenLI);
729 L->addBasicBlockToLoop(ElseBB, *GenLI);
730 }
731
732 CondBB->getTerminator()->eraseFromParent();
733
734 Builder.SetInsertPoint(CondBB);
735 Value *Predicate = ExprBuilder.create(Cond);
736 Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
737 Builder.SetInsertPoint(ThenBB);
738 Builder.CreateBr(MergeBB);
739 Builder.SetInsertPoint(ElseBB);
740 Builder.CreateBr(MergeBB);
741 Builder.SetInsertPoint(ThenBB, ThenBB->begin());
742
744
745 Builder.SetInsertPoint(ElseBB, ElseBB->begin());
746
749
750 Builder.SetInsertPoint(MergeBB, MergeBB->begin());
751
753
754 IfConditions++;
755}
756
757__isl_give isl_id_to_ast_expr *
759 __isl_keep isl_ast_node *Node) {
760 isl::id_to_ast_expr NewAccesses =
762
764 assert(!Build.is_null() && "Could not obtain isl_ast_build from user node");
765 Stmt->setAstBuild(Build);
766
767 for (auto *MA : *Stmt) {
768 if (!MA->hasNewAccessRelation()) {
770 if (!MA->isAffine())
771 continue;
772 if (MA->getLatestScopArrayInfo()->getBasePtrOriginSAI())
773 continue;
774
775 auto *BasePtr =
776 dyn_cast<Instruction>(MA->getLatestScopArrayInfo()->getBasePtr());
777 if (BasePtr && Stmt->getParent()->getRegion().contains(BasePtr))
778 continue;
779 } else {
780 continue;
781 }
782 }
783 assert(MA->isAffine() &&
784 "Only affine memory accesses can be code generated");
785
786 isl::union_map Schedule = Build.get_schedule();
787
788#ifndef NDEBUG
789 if (MA->isRead()) {
790 auto Dom = Stmt->getDomain().release();
791 auto SchedDom = isl_set_from_union_set(Schedule.domain().release());
792 auto AccDom = isl_map_domain(MA->getAccessRelation().release());
793 Dom = isl_set_intersect_params(Dom,
794 Stmt->getParent()->getContext().release());
795 SchedDom = isl_set_intersect_params(
796 SchedDom, Stmt->getParent()->getContext().release());
797 assert(isl_set_is_subset(SchedDom, AccDom) &&
798 "Access relation not defined on full schedule domain");
799 assert(isl_set_is_subset(Dom, AccDom) &&
800 "Access relation not defined on full domain");
801 isl_set_free(AccDom);
802 isl_set_free(SchedDom);
803 isl_set_free(Dom);
804 }
805#endif
806
807 isl::pw_multi_aff PWAccRel = MA->applyScheduleToAccessRelation(Schedule);
808
809 // isl cannot generate an index expression for access-nothing accesses.
810 isl::set AccDomain = PWAccRel.domain();
811 if (AccDomain.is_empty())
812 continue;
813
814 isl::ast_expr AccessExpr = Build.access_from(PWAccRel);
815 NewAccesses = NewAccesses.set(MA->getId(), AccessExpr);
816 }
817
818 return NewAccesses.release();
819}
820
822 ScopStmt *Stmt, LoopToScevMapT &LTS) {
824 "Expression of type 'op' expected");
826 "Operation of type 'call' expected");
827 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr) - 1; ++i) {
828 isl_ast_expr *SubExpr;
829 Value *V;
830
831 SubExpr = isl_ast_expr_get_op_arg(Expr, i + 1);
832 V = ExprBuilder.create(SubExpr);
833 ScalarEvolution *SE = Stmt->getParent()->getSE();
834 LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V);
835 }
836
837 isl_ast_expr_free(Expr);
838}
839
841 __isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
842 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
843 __isl_take isl_id *IteratorID) {
844 int i = 0;
845
846 Value *OldValue = IDToValue[IteratorID];
847 for (Value *IV : IVS) {
848 IDToValue[IteratorID] = IV;
849 createSubstitutions(isl_ast_expr_copy(Expr), Stmt, VLTS[i]);
850 i++;
851 }
852
853 IDToValue[IteratorID] = OldValue;
854 isl_id_free(IteratorID);
855 isl_ast_expr_free(Expr);
856}
857
859 ScopStmt *Stmt, __isl_keep isl_id_to_ast_expr *NewAccesses) {
860 assert(Stmt->size() == 2);
861 auto ReadAccess = Stmt->begin();
862 auto WriteAccess = ReadAccess++;
863 assert((*ReadAccess)->isRead() && (*WriteAccess)->isMustWrite());
864 assert((*ReadAccess)->getElementType() == (*WriteAccess)->getElementType() &&
865 "Accesses use the same data type");
866 assert((*ReadAccess)->isArrayKind() && (*WriteAccess)->isArrayKind());
867 auto *AccessExpr =
868 isl_id_to_ast_expr_get(NewAccesses, (*ReadAccess)->getId().release());
869 auto *LoadValue = ExprBuilder.create(AccessExpr);
870 AccessExpr =
871 isl_id_to_ast_expr_get(NewAccesses, (*WriteAccess)->getId().release());
872 auto *StoreAddr = ExprBuilder.createAccessAddress(AccessExpr).first;
873 Builder.CreateStore(LoadValue, StoreAddr);
874}
875
877 assert(!OutsideLoopIterations.contains(L) &&
878 "trying to materialize loop induction variable twice");
879 const SCEV *OuterLIV = SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)),
880 SE.getUnknown(Builder.getInt64(1)), L,
881 SCEV::FlagAnyWrap);
882 Value *V = generateSCEV(OuterLIV);
883 OutsideLoopIterations[L] = SE.getUnknown(V);
884 return V;
885}
886
888 LoopToScevMapT LTS;
889 isl_id *Id;
890 ScopStmt *Stmt;
891
893 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
894 Id = isl_ast_expr_get_id(StmtExpr);
895 isl_ast_expr_free(StmtExpr);
896
897 LTS.insert_range(OutsideLoopIterations);
898
899 Stmt = (ScopStmt *)isl_id_get_user(Id);
900 auto *NewAccesses = createNewAccesses(Stmt, User);
901 if (Stmt->isCopyStmt()) {
902 generateCopyStmt(Stmt, NewAccesses);
903 isl_ast_expr_free(Expr);
904 } else {
905 createSubstitutions(Expr, Stmt, LTS);
906
907 if (Stmt->isBlockStmt())
908 BlockGen.copyStmt(*Stmt, LTS, NewAccesses);
909 else
910 RegionGen.copyStmt(*Stmt, LTS, NewAccesses);
911 }
912
913 isl_id_to_ast_expr_free(NewAccesses);
914 isl_ast_node_free(User);
915 isl_id_free(Id);
916}
917
919 isl_ast_node_list *List = isl_ast_node_block_get_children(Block);
920
921 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
922 create(isl_ast_node_list_get_ast_node(List, i));
923
924 isl_ast_node_free(Block);
925 isl_ast_node_list_free(List);
926}
927
929 if (!TraceStmts)
930 return;
931
932 // Sequence of strings to print.
933 SmallVector<llvm::Value *, 8> Values;
934 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "Scop: "));
935
936 auto Params = S.getParamSpace();
937 for (int i : rangeIslSize(0, Params.dim(isl::dim::param))) {
938 if (i != 0)
939 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, " "));
940
941 isl::id PId = Params.get_dim_id(isl::dim::param, i);
942 Values.push_back(
944 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "="));
945 Values.push_back(IDToValue.lookup(PId.get()));
946 }
947
948 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "\n"));
949 RuntimeDebugBuilder::createCPUPrinter(Builder, ArrayRef<Value *>(Values));
950}
951
953 switch (isl_ast_node_get_type(Node)) {
955 llvm_unreachable("code generation error");
957 createMark(Node);
958 return;
959 case isl_ast_node_for:
960 createFor(Node);
961 return;
962 case isl_ast_node_if:
963 createIf(Node);
964 return;
966 createUser(Node);
967 return;
969 createBlock(Node);
970 return;
971 }
972
973 llvm_unreachable("Unknown isl_ast_node type");
974}
975
977 // If the Id is already mapped, skip it.
978 if (!IDToValue.count(Id)) {
979 auto *ParamSCEV = (const SCEV *)isl_id_get_user(Id);
980 Value *V = nullptr;
981
982 // Parameters could refer to invariant loads that need to be
983 // preloaded before we can generate code for the parameter. Thus,
984 // check if any value referred to in ParamSCEV is an invariant load
985 // and if so make sure its equivalence class is preloaded.
986 SetVector<Value *> Values;
987 findValues(ParamSCEV, SE, Values);
988 for (auto *Val : Values) {
989 // Check if the value is an instruction in a dead block within the SCoP
990 // and if so do not code generate it.
991 if (auto *Inst = dyn_cast<Instruction>(Val)) {
992 if (S.contains(Inst)) {
993 bool IsDead = true;
994
995 // Check for "undef" loads first, then if there is a statement for
996 // the parent of Inst and lastly if the parent of Inst has an empty
997 // domain. In the first and last case the instruction is dead but if
998 // there is a statement or the domain is not empty Inst is not dead.
999 auto MemInst = MemAccInst::dyn_cast(Inst);
1000 auto Address = MemInst ? MemInst.getPointerOperand() : nullptr;
1001 if (Address && SE.getUnknown(UndefValue::get(Address->getType())) ==
1002 SE.getPointerBase(SE.getSCEV(Address))) {
1003 } else if (S.getStmtFor(Inst)) {
1004 IsDead = false;
1005 } else {
1006 auto *Domain = S.getDomainConditions(Inst->getParent()).release();
1007 IsDead = isl_set_is_empty(Domain);
1009 }
1010
1011 if (IsDead) {
1012 V = UndefValue::get(ParamSCEV->getType());
1013 break;
1014 }
1015 }
1016 }
1017
1018 if (auto *IAClass = S.lookupInvariantEquivClass(Val)) {
1019 // Check if this invariant access class is empty, hence if we never
1020 // actually added a loads instruction to it. In that case it has no
1021 // (meaningful) users and we should not try to code generate it.
1022 if (IAClass->InvariantAccesses.empty())
1023 V = UndefValue::get(ParamSCEV->getType());
1024
1025 if (!preloadInvariantEquivClass(*IAClass)) {
1026 isl_id_free(Id);
1027 return false;
1028 }
1029 }
1030 }
1031
1032 V = V ? V : generateSCEV(ParamSCEV);
1033 IDToValue[Id] = V;
1034 }
1035
1036 isl_id_free(Id);
1037 return true;
1038}
1039
1041 for (unsigned i = 0, e = isl_set_dim(Set, isl_dim_param); i < e; ++i) {
1042 if (!isl_set_involves_dims(Set, isl_dim_param, i, 1))
1043 continue;
1045 if (!materializeValue(Id))
1046 return false;
1047 }
1048 return true;
1049}
1050
1052 for (const SCEV *Param : S.parameters()) {
1053 isl_id *Id = S.getIdForParam(Param).release();
1054 if (!materializeValue(Id))
1055 return false;
1056 }
1057 return true;
1058}
1059
1061 isl_ast_build *Build,
1062 Instruction *AccInst) {
1063 isl_pw_multi_aff *PWAccRel = isl_pw_multi_aff_from_set(AccessRange);
1064 isl_ast_expr *Access =
1066 auto *Address = isl_ast_expr_address_of(Access);
1067 auto *AddressValue = ExprBuilder.create(Address);
1068 Value *PreloadVal;
1069
1070 // Correct the type as the SAI might have a different type than the user
1071 // expects, especially if the base pointer is a struct.
1072 Type *Ty = AccInst->getType();
1073
1074 auto *Ptr = AddressValue;
1075 auto Name = Ptr->getName();
1076 PreloadVal = Builder.CreateLoad(Ty, Ptr, Name + ".load");
1077 if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal))
1078 PreloadInst->setAlignment(cast<LoadInst>(AccInst)->getAlign());
1079
1080 // TODO: This is only a hot fix for SCoP sequences that use the same load
1081 // instruction contained and hoisted by one of the SCoPs.
1082 if (SE.isSCEVable(Ty))
1083 SE.forgetValue(AccInst);
1084
1085 return PreloadVal;
1086}
1087
1090 isl_set *AccessRange = isl_map_range(MA.getAddressFunction().release());
1091 AccessRange = isl_set_gist_params(AccessRange, S.getContext().release());
1092
1093 if (!materializeParameters(AccessRange)) {
1094 isl_set_free(AccessRange);
1096 return nullptr;
1097 }
1098
1099 auto *Build =
1100 isl_ast_build_from_context(isl_set_universe(S.getParamSpace().release()));
1102 bool AlwaysExecuted = isl_set_is_equal(Domain, Universe);
1103 isl_set_free(Universe);
1104
1105 Instruction *AccInst = MA.getAccessInstruction();
1106 Type *AccInstTy = AccInst->getType();
1107
1108 Value *PreloadVal = nullptr;
1109 if (AlwaysExecuted) {
1110 PreloadVal = preloadUnconditionally(AccessRange, Build, AccInst);
1111 isl_ast_build_free(Build);
1113 return PreloadVal;
1114 }
1115
1117 isl_ast_build_free(Build);
1118 isl_set_free(AccessRange);
1120 return nullptr;
1121 }
1122
1123 isl_ast_expr *DomainCond = isl_ast_build_expr_from_set(Build, Domain);
1124 Domain = nullptr;
1125
1126 ExprBuilder.setTrackOverflow(true);
1127 Value *Cond = ExprBuilder.createBool(DomainCond);
1128 Value *OverflowHappened = Builder.CreateNot(ExprBuilder.getOverflowState(),
1129 "polly.preload.cond.overflown");
1130 Cond = Builder.CreateAnd(Cond, OverflowHappened, "polly.preload.cond.result");
1131 ExprBuilder.setTrackOverflow(false);
1132
1133 if (!Cond->getType()->isIntegerTy(1))
1134 Cond = Builder.CreateIsNotNull(Cond);
1135
1136 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1137 Builder.GetInsertPoint(), GenDT, GenLI);
1138 CondBB->setName("polly.preload.cond");
1139
1140 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), GenDT, GenLI);
1141 MergeBB->setName("polly.preload.merge");
1142
1143 Function *F = Builder.GetInsertBlock()->getParent();
1144 LLVMContext &Context = F->getContext();
1145 BasicBlock *ExecBB = BasicBlock::Create(Context, "polly.preload.exec", F);
1146
1147 GenDT->addNewBlock(ExecBB, CondBB);
1148 if (Loop *L = GenLI->getLoopFor(CondBB))
1149 L->addBasicBlockToLoop(ExecBB, *GenLI);
1150
1151 auto *CondBBTerminator = CondBB->getTerminator();
1152 Builder.SetInsertPoint(CondBB, CondBBTerminator->getIterator());
1153 Builder.CreateCondBr(Cond, ExecBB, MergeBB);
1154 CondBBTerminator->eraseFromParent();
1155
1156 Builder.SetInsertPoint(ExecBB);
1157 Builder.CreateBr(MergeBB);
1158
1159 Builder.SetInsertPoint(ExecBB, ExecBB->getTerminator()->getIterator());
1160 Value *PreAccInst = preloadUnconditionally(AccessRange, Build, AccInst);
1161 Builder.SetInsertPoint(MergeBB, MergeBB->getTerminator()->getIterator());
1162 auto *MergePHI = Builder.CreatePHI(
1163 AccInstTy, 2, "polly.preload." + AccInst->getName() + ".merge");
1164 PreloadVal = MergePHI;
1165
1166 if (!PreAccInst) {
1167 PreloadVal = nullptr;
1168 PreAccInst = UndefValue::get(AccInstTy);
1169 }
1170
1171 MergePHI->addIncoming(PreAccInst, ExecBB);
1172 MergePHI->addIncoming(Constant::getNullValue(AccInstTy), CondBB);
1173
1174 isl_ast_build_free(Build);
1175 return PreloadVal;
1176}
1177
1179 InvariantEquivClassTy &IAClass) {
1180 // For an equivalence class of invariant loads we pre-load the representing
1181 // element with the unified execution context. However, we have to map all
1182 // elements of the class to the one preloaded load as they are referenced
1183 // during the code generation and therefore need to be mapped.
1184 const MemoryAccessList &MAs = IAClass.InvariantAccesses;
1185 if (MAs.empty())
1186 return true;
1187
1188 MemoryAccess *MA = MAs.front();
1189 assert(MA->isArrayKind() && MA->isRead());
1190
1191 // If the access function was already mapped, the preload of this equivalence
1192 // class was triggered earlier already and doesn't need to be done again.
1193 if (ValueMap.count(MA->getAccessInstruction()))
1194 return true;
1195
1196 // Check for recursion which can be caused by additional constraints, e.g.,
1197 // non-finite loop constraints. In such a case we have to bail out and insert
1198 // a "false" runtime check that will cause the original code to be executed.
1199 auto PtrId = std::make_pair(IAClass.IdentifyingPointer, IAClass.AccessType);
1200 if (!PreloadedPtrs.insert(PtrId).second)
1201 return false;
1202
1203 // The execution context of the IAClass.
1204 isl::set &ExecutionCtx = IAClass.ExecutionContext;
1205
1206 // If the base pointer of this class is dependent on another one we have to
1207 // make sure it was preloaded already.
1208 auto *SAI = MA->getScopArrayInfo();
1209 if (auto *BaseIAClass = S.lookupInvariantEquivClass(SAI->getBasePtr())) {
1210 if (!preloadInvariantEquivClass(*BaseIAClass))
1211 return false;
1212
1213 // After we preloaded the BaseIAClass we adjusted the BaseExecutionCtx and
1214 // we need to refine the ExecutionCtx.
1215 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1216 ExecutionCtx = ExecutionCtx.intersect(BaseExecutionCtx);
1217 }
1218
1219 // If the size of a dimension is dependent on another class, make sure it is
1220 // preloaded.
1221 for (unsigned i = 1, e = SAI->getNumberOfDimensions(); i < e; ++i) {
1222 const SCEV *Dim = SAI->getDimensionSize(i);
1223 SetVector<Value *> Values;
1224 findValues(Dim, SE, Values);
1225 for (auto *Val : Values) {
1226 if (auto *BaseIAClass = S.lookupInvariantEquivClass(Val)) {
1227 if (!preloadInvariantEquivClass(*BaseIAClass))
1228 return false;
1229
1230 // After we preloaded the BaseIAClass we adjusted the BaseExecutionCtx
1231 // and we need to refine the ExecutionCtx.
1232 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1233 ExecutionCtx = ExecutionCtx.intersect(BaseExecutionCtx);
1234 }
1235 }
1236 }
1237
1238 Instruction *AccInst = MA->getAccessInstruction();
1239 Type *AccInstTy = AccInst->getType();
1240
1241 Value *PreloadVal = preloadInvariantLoad(*MA, ExecutionCtx.copy());
1242 if (!PreloadVal)
1243 return false;
1244
1245 for (const MemoryAccess *MA : MAs) {
1246 Instruction *MAAccInst = MA->getAccessInstruction();
1247 assert(PreloadVal->getType() == MAAccInst->getType());
1248 ValueMap[MAAccInst] = PreloadVal;
1249 }
1250
1251 if (SE.isSCEVable(AccInstTy)) {
1252 isl_id *ParamId = S.getIdForParam(SE.getSCEV(AccInst)).release();
1253 if (ParamId)
1254 IDToValue[ParamId] = PreloadVal;
1255 isl_id_free(ParamId);
1256 }
1257
1258 BasicBlock *EntryBB = &Builder.GetInsertBlock()->getParent()->getEntryBlock();
1259 auto *Alloca = new AllocaInst(AccInstTy, DL.getAllocaAddrSpace(),
1260 AccInst->getName() + ".preload.s2a",
1261 EntryBB->getFirstInsertionPt());
1262 Builder.CreateStore(PreloadVal, Alloca);
1263 ValueMapT PreloadedPointer;
1264 PreloadedPointer[PreloadVal] = AccInst;
1265 Annotator.addAlternativeAliasBases(PreloadedPointer);
1266
1267 for (auto *DerivedSAI : SAI->getDerivedSAIs()) {
1268 Value *BasePtr = DerivedSAI->getBasePtr();
1269
1270 for (const MemoryAccess *MA : MAs) {
1271 // As the derived SAI information is quite coarse, any load from the
1272 // current SAI could be the base pointer of the derived SAI, however we
1273 // should only change the base pointer of the derived SAI if we actually
1274 // preloaded it.
1275 if (BasePtr == MA->getOriginalBaseAddr()) {
1276 assert(BasePtr->getType() == PreloadVal->getType());
1277 DerivedSAI->setBasePtr(PreloadVal);
1278 }
1279
1280 // For scalar derived SAIs we remap the alloca used for the derived value.
1281 if (BasePtr == MA->getAccessInstruction())
1282 ScalarMap[DerivedSAI] = Alloca;
1283 }
1284 }
1285
1286 for (const MemoryAccess *MA : MAs) {
1287 Instruction *MAAccInst = MA->getAccessInstruction();
1288 // Use the escape system to get the correct value to users outside the SCoP.
1290 for (auto *U : MAAccInst->users())
1291 if (Instruction *UI = dyn_cast<Instruction>(U))
1292 if (!S.contains(UI))
1293 EscapeUsers.push_back(UI);
1294
1295 if (EscapeUsers.empty())
1296 continue;
1297
1299 std::make_pair(Alloca, std::move(EscapeUsers));
1300 }
1301
1302 return true;
1303}
1304
1306 for (auto &SAI : S.arrays()) {
1307 if (SAI->getBasePtr())
1308 continue;
1309
1310 assert(SAI->getNumberOfDimensions() > 0 && SAI->getDimensionSize(0) &&
1311 "The size of the outermost dimension is used to declare newly "
1312 "created arrays that require memory allocation.");
1313
1314 Type *NewArrayType = nullptr;
1315
1316 // Get the size of the array = size(dim_1)*...*size(dim_n)
1317 uint64_t ArraySizeInt = 1;
1318 for (int i = SAI->getNumberOfDimensions() - 1; i >= 0; i--) {
1319 auto *DimSize = SAI->getDimensionSize(i);
1320 unsigned UnsignedDimSize = static_cast<const SCEVConstant *>(DimSize)
1321 ->getAPInt()
1322 .getLimitedValue();
1323
1324 if (!NewArrayType)
1325 NewArrayType = SAI->getElementType();
1326
1327 NewArrayType = ArrayType::get(NewArrayType, UnsignedDimSize);
1328 ArraySizeInt *= UnsignedDimSize;
1329 }
1330
1331 if (SAI->isOnHeap()) {
1332 LLVMContext &Ctx = NewArrayType->getContext();
1333
1334 // Get the IntPtrTy from the Datalayout
1335 auto IntPtrTy = DL.getIntPtrType(Ctx);
1336
1337 // Get the size of the element type in bits
1338 unsigned Size = SAI->getElemSizeInBytes();
1339
1340 // Insert the malloc call at polly.start
1341 BasicBlock *StartBlock = std::get<0>(StartExitBlocks);
1342 Builder.SetInsertPoint(StartBlock,
1343 StartBlock->getTerminator()->getIterator());
1344 auto *CreatedArray = Builder.CreateMalloc(
1345 IntPtrTy, SAI->getElementType(),
1346 ConstantInt::get(Type::getInt64Ty(Ctx), Size),
1347 ConstantInt::get(Type::getInt64Ty(Ctx), ArraySizeInt), nullptr,
1348 SAI->getName());
1349
1350 SAI->setBasePtr(CreatedArray);
1351
1352 // Insert the free call at polly.exiting
1353 BasicBlock *ExitingBlock = std::get<1>(StartExitBlocks);
1354 Builder.SetInsertPoint(ExitingBlock,
1355 ExitingBlock->getTerminator()->getIterator());
1356 Builder.CreateFree(CreatedArray);
1357 } else {
1358 auto InstIt = Builder.GetInsertBlock()
1359 ->getParent()
1360 ->getEntryBlock()
1361 .getTerminator()
1362 ->getIterator();
1363
1364 auto *CreatedArray = new AllocaInst(NewArrayType, DL.getAllocaAddrSpace(),
1365 SAI->getName(), InstIt);
1367 CreatedArray->setAlignment(Align(PollyTargetFirstLevelCacheLineSize));
1368 SAI->setBasePtr(CreatedArray);
1369 }
1370 }
1371}
1372
1374 auto &InvariantEquivClasses = S.getInvariantAccesses();
1375 if (InvariantEquivClasses.empty())
1376 return true;
1377
1378 BasicBlock *PreLoadBB = SplitBlock(Builder.GetInsertBlock(),
1379 Builder.GetInsertPoint(), GenDT, GenLI);
1380 PreLoadBB->setName("polly.preload.begin");
1381 Builder.SetInsertPoint(PreLoadBB, PreLoadBB->begin());
1382
1383 for (auto &IAClass : InvariantEquivClasses)
1384 if (!preloadInvariantEquivClass(IAClass))
1385 return false;
1386
1387 return true;
1388}
1389
1391 // Materialize values for the parameters of the SCoP.
1393
1394 // Generate values for the current loop iteration for all surrounding loops.
1395 //
1396 // We may also reference loops outside of the scop which do not contain the
1397 // scop itself, but as the number of such scops may be arbitrarily large we do
1398 // not generate code for them here, but only at the point of code generation
1399 // where these values are needed.
1400 Loop *L = LI.getLoopFor(S.getEntry());
1401
1402 while (L != nullptr && S.contains(L))
1403 L = L->getParentLoop();
1404
1405 while (L != nullptr) {
1407 L = L->getParentLoop();
1408 }
1409
1410 isl_set_free(Context);
1411}
1412
1414 /// We pass the insert location of our Builder, as Polly ensures during IR
1415 /// generation that there is always a valid CFG into which instructions are
1416 /// inserted. As a result, the insertpoint is known to be always followed by a
1417 /// terminator instruction. This means the insert point may be specified by a
1418 /// terminator instruction, but it can never point to an ->end() iterator
1419 /// which does not have a corresponding instruction. Hence, dereferencing
1420 /// the insertpoint to obtain an instruction is known to be save.
1421 ///
1422 /// We also do not need to update the Builder here, as new instructions are
1423 /// always inserted _before_ the given InsertLocation. As a result, the
1424 /// insert location remains valid.
1425 assert(Builder.GetInsertBlock()->end() != Builder.GetInsertPoint() &&
1426 "Insert location points after last valid instruction");
1427 BasicBlock::iterator InsertLocation = Builder.GetInsertPoint();
1428
1429 return expandCodeFor(S, SE, Builder.GetInsertBlock()->getParent(), *GenSE, DL,
1430 "polly", Expr, Expr->getType(), InsertLocation,
1431 &ValueMap, /*LoopToScevMap*/ nullptr,
1432 StartBlock->getSinglePredecessor());
1433}
1434
1435/// The AST expression we generate to perform the run-time check assumes
1436/// computations on integer types of infinite size. As we only use 64-bit
1437/// arithmetic we check for overflows, in case of which we set the result
1438/// of this run-time check to false to be conservatively correct,
1440 auto ExprBuilder = getExprBuilder();
1441
1442 // In case the AST expression has integers larger than 64 bit, bail out. The
1443 // resulting LLVM-IR will contain operations on types that use more than 64
1444 // bits. These are -- in case wrapping intrinsics are used -- translated to
1445 // runtime library calls that are not available on all systems (e.g., Android)
1446 // and consequently will result in linker errors.
1447 if (ExprBuilder.hasLargeInts(isl::manage_copy(Condition))) {
1448 isl_ast_expr_free(Condition);
1449 return Builder.getFalse();
1450 }
1451
1452 ExprBuilder.setTrackOverflow(true);
1453 Value *RTC = ExprBuilder.create(Condition);
1454 if (!RTC->getType()->isIntegerTy(1))
1455 RTC = Builder.CreateIsNotNull(RTC);
1456 Value *OverflowHappened =
1457 Builder.CreateNot(ExprBuilder.getOverflowState(), "polly.rtc.overflown");
1458
1460 auto *F = Builder.GetInsertBlock()->getParent();
1462 Builder,
1463 "F: " + F->getName().str() + " R: " + S.getRegion().getNameStr() +
1464 "RTC: ",
1465 RTC, " Overflow: ", OverflowHappened,
1466 "\n"
1467 " (0 failed, -1 succeeded)\n"
1468 " (if one or both are 0 falling back to original code, if both are -1 "
1469 "executing Polly code)\n");
1470 }
1471
1472 RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result");
1473 ExprBuilder.setTrackOverflow(false);
1474
1475 if (!isa<ConstantInt>(RTC))
1476 VersionedScops++;
1477
1478 return RTC;
1479}
static void findReferencesInInst(Instruction *Inst, ScopStmt *UserStmt, Loop *UserScope, const ValueMapT &GlobalMap, SetVector< Value * > &Values, SetVector< const SCEV * > &SCEVs)
static void findReferencesByUse(Value *SrcVal, ScopStmt *UserStmt, Loop *UserScope, const ValueMapT &GlobalMap, SetVector< Value * > &Values, SetVector< const SCEV * > &SCEVs)
static void addReferencesFromStmtSet(isl::set Set, SubtreeReferences *UserPtr)
Extract the out-of-scop values and SCEVs referenced from a set describing a ScopStmt.
static cl::opt< bool > PollyGenerateRTCPrint("polly-codegen-emit-rtc-print", cl::desc("Emit code that prints the runtime check result dynamically."), cl::Hidden, cl::cat(PollyCategory))
static void addReferencesFromStmtUnionSet(isl::union_set USet, SubtreeReferences &References)
Extract the out-of-scop values and SCEVs referenced from a union set referencing multiple ScopStmts.
static cl::opt< bool > PollyGenerateExpressions("polly-codegen-generate-expressions", cl::desc("Generate AST expressions for unmodified and modified accesses"), cl::Hidden, cl::cat(PollyCategory))
STATISTIC(VersionedScops, "Number of SCoPs that required versioning.")
static bool IsLoopVectorizerDisabled(isl::ast_node_for Node)
Restore the initial ordering of dimensions of the band node.
static void findReferencesInStmt(ScopStmt *Stmt, SetVector< Value * > &Values, ValueMapT &GlobalMap, SetVector< const SCEV * > &SCEVs)
static cl::opt< OpenMPBackend > PollyOmpBackend("polly-omp-backend", cl::desc("Choose the OpenMP library to use:"), cl::values(clEnumValN(OpenMPBackend::GNU, "GNU", "GNU OpenMP"), clEnumValN(OpenMPBackend::LLVM, "LLVM", "LLVM OpenMP")), cl::Hidden, cl::init(OpenMPBackend::GNU), cl::cat(PollyCategory))
static cl::opt< int > PollyTargetFirstLevelCacheLineSize("polly-target-first-level-cache-line-size", cl::desc("The size of the first level cache line size specified in bytes."), cl::Hidden, cl::init(64), cl::cat(PollyCategory))
OpenMPBackend
OpenMP backend options.
llvm::cl::OptionCategory PollyCategory
bool TraceStmts
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_from_set(__isl_take isl_set *set)
Definition isl_aff.c:5657
__isl_export __isl_give isl_ast_expr * isl_ast_node_for_get_init(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1383
__isl_export __isl_give isl_ast_node_list * isl_ast_node_block_get_children(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1576
__isl_null isl_ast_expr * isl_ast_expr_free(__isl_take isl_ast_expr *expr)
Definition isl_ast.c:243
__isl_give isl_ast_expr * isl_ast_expr_address_of(__isl_take isl_ast_expr *expr)
Definition isl_ast.c:649
isl_size isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
Definition isl_ast.c:359
enum isl_ast_expr_op_type isl_ast_expr_get_op_type(__isl_keep isl_ast_expr *expr)
Definition isl_ast.c:342
__isl_give isl_ast_expr * isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr, int pos)
Definition isl_ast.c:377
__isl_export __isl_give isl_ast_node * isl_ast_node_mark_get_node(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1650
__isl_export __isl_give isl_ast_expr * isl_ast_node_for_get_inc(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1416
__isl_give isl_ast_node * isl_ast_node_if_get_else(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1517
__isl_export __isl_give isl_ast_node * isl_ast_node_for_get_body(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1348
__isl_give isl_id * isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
Definition isl_ast.c:313
__isl_export __isl_give isl_ast_expr * isl_ast_node_user_get_expr(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1629
__isl_export __isl_give isl_ast_expr * isl_ast_node_if_get_cond(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1568
__isl_export __isl_give isl_id * isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1640
__isl_export __isl_give isl_ast_expr * isl_ast_node_for_get_iterator(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1375
__isl_null isl_ast_node * isl_ast_node_free(__isl_take isl_ast_node *node)
Definition isl_ast.c:1180
__isl_give isl_ast_node * isl_ast_node_if_get_then(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1482
isl_bool isl_ast_node_if_has_else(__isl_keep isl_ast_node *node)
Definition isl_ast.c:1499
__isl_give isl_ast_expr * isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
Definition isl_ast.c:195
__isl_overload __isl_give isl_ast_expr * isl_ast_build_access_from_pw_multi_aff(__isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma)
__isl_export __isl_give isl_ast_build * isl_ast_build_from_context(__isl_take isl_set *set)
__isl_overload __isl_give isl_ast_expr * isl_ast_build_expr_from_set(__isl_keep isl_ast_build *build, __isl_take isl_set *set)
__isl_null isl_ast_build * isl_ast_build_free(__isl_take isl_ast_build *build)
@ isl_ast_expr_id
Definition ast_type.h:78
@ isl_ast_expr_op
Definition ast_type.h:77
#define isl_ast_op_le
Definition ast_type.h:66
#define isl_ast_op_lt
Definition ast_type.h:67
isl_ast_node_type
Definition ast_type.h:82
@ isl_ast_node_block
Definition ast_type.h:86
@ isl_ast_node_for
Definition ast_type.h:84
@ isl_ast_node_mark
Definition ast_type.h:87
@ isl_ast_node_if
Definition ast_type.h:85
@ isl_ast_node_error
Definition ast_type.h:83
@ isl_ast_node_user
Definition ast_type.h:88
#define isl_ast_op_type
Definition ast_type.h:46
#define isl_ast_op_call
Definition ast_type.h:70
isl::checked::ast_expr access_from(isl::checked::multi_pw_aff mpa) const
isl::checked::union_map get_schedule() const
boolean isa() const
__isl_give isl_ast_expr * release()
__isl_keep isl_ast_expr * get() const
isl::checked::ast_node_list children() const
isl::checked::ast_node body() const
isl::checked::ast_expr init() const
isl::checked::ast_expr cond() const
isl::checked::ast_expr inc() const
isl::checked::ast_expr iterator() const
isl::checked::id id() const
__isl_keep isl_ast_node * get() const
__isl_give isl_ast_node * release()
__isl_give isl_id_to_ast_expr * release()
isl::checked::id_to_ast_expr set(isl::checked::id key, isl::checked::ast_expr val) const
std::string get_name() const
__isl_keep isl_id * get() const
__isl_give isl_map * release()
isl::checked::set domain() const
__isl_give isl_set * copy() const &
isl::checked::set intersect(isl::checked::set set2) const
boolean is_empty() const
__isl_give isl_set * release()
isl::checked::union_set domain() const
__isl_give isl_union_set * release()
isl::checked::set_list get_set_list() const
long get_num_si() const
static isl::id_to_ast_expr alloc(isl::ctx ctx, int min_size)
SmallVector< Instruction *, 4 > EscapeUserVectorTy
Simple vector of instructions to store escape users.
static bool isParallel(const isl::ast_node &Node)
Is this loop a parallel loop?
Definition IslAst.cpp:581
static bool isExecutedInParallel(const isl::ast_node &Node)
Will the loop be run as thread parallel?
Definition IslAst.cpp:601
static isl::union_map getSchedule(const isl::ast_node &Node)
Get the nodes schedule or a nullptr if not available.
Definition IslAst.cpp:620
static isl::ast_build getBuild(const isl::ast_node &Node)
Get the nodes build context or a nullptr if not available.
Definition IslAst.cpp:637
static bool isReductionParallel(const isl::ast_node &Node)
Is this loop a reduction parallel loop?
Definition IslAst.cpp:596
llvm::MapVector< isl_id *, llvm::AssertingVH< llvm::Value > > IDToValueTy
A map from isl_ids to llvm::Values.
Value * preloadUnconditionally(__isl_take isl_set *AccessRange, isl_ast_build *Build, Instruction *AccInst)
Preload the memory access at AccessRange with Build.
void addParameters(__isl_take isl_set *Context)
Value * preloadInvariantLoad(const MemoryAccess &MA, __isl_take isl_set *Domain)
Preload the memory load access MA.
Value * getLatestValue(Value *Original) const
Return the most up-to-date version of the llvm::Value for code generation.
void create(__isl_take isl_ast_node *Node)
RegionGenerator RegionGen
The generator used to copy a non-affine region.
ScopAnnotator & Annotator
BlockGenerator::AllocaMapTy ScalarMap
Maps used by the block and region generator to demote scalars.
SmallVector< Function *, 8 > ParallelSubfunctions
A collection of all parallel subfunctions that have been created.
IslExprBuilder::IDToValueTy IDToValue
bool preloadInvariantEquivClass(InvariantEquivClassTy &IAClass)
Preload the invariant access equivalence class IAClass.
IslExprBuilder ExprBuilder
void createForSequential(isl::ast_node_for For, bool MarkParallel)
__isl_give isl_id_to_ast_expr * createNewAccesses(ScopStmt *Stmt, __isl_keep isl_ast_node *Node)
Create new access functions for modified memory accesses.
void createForParallel(__isl_take isl_ast_node *For)
Create LLVM-IR that executes a for node thread parallel.
bool preloadInvariantLoads()
Preload all memory loads that are invariant.
Value * generateSCEV(const SCEV *Expr)
Generate code for a given SCEV*.
bool materializeParameters()
Materialize all parameters in the current scop.
const DataLayout & DL
ValueMapT ValueMap
A set of Value -> Value remappings to apply when generating new code.
bool materializeValue(__isl_take isl_id *Id)
Materialize code for Id if it was not done before.
SmallSet< std::pair< const SCEV *, Type * >, 16 > PreloadedPtrs
Set to remember materialized invariant loads.
Value * materializeNonScopLoopInductionVariable(const Loop *L)
Materialize a canonical loop induction variable for L, which is a loop that is not present in the Sco...
virtual void createBlock(__isl_take isl_ast_node *Block)
virtual void createUser(__isl_take isl_ast_node *User)
ScalarEvolution & SE
void createSubstitutionsVector(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt, std::vector< LoopToScevMapT > &VLTS, std::vector< Value * > &IVS, __isl_take isl_id *IteratorID)
DominatorTree * GenDT
Relates to the region where the code is emitted into.
virtual void createFor(__isl_take isl_ast_node *For)
virtual void createMark(__isl_take isl_ast_node *Marker)
Generate code for a marker now.
void allocateNewArrays(BBPair StartExitBlocks)
Allocate memory for all new arrays created by Polly.
virtual isl::union_map getScheduleForAstNode(const isl::ast_node &Node)
Get the schedule for a given AST node.
PollyIRBuilder & Builder
void getReferencesInSubtree(const isl::ast_node &For, SetVector< Value * > &Values, SetVector< const Loop * > &Loops)
Compute the values and loops referenced in this subtree.
ScalarEvolution * GenSE
void generateCopyStmt(ScopStmt *Stmt, __isl_keep isl_id_to_ast_expr *NewAccesses)
Create code for a copy statement.
virtual void createIf(__isl_take isl_ast_node *If)
void createSubstitutions(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt, LoopToScevMapT &LTS)
Generate LLVM-IR that computes the values of the original induction variables in function of the newl...
isl::ast_expr getUpperBound(isl::ast_node_for For, CmpInst::Predicate &Predicate)
BlockGenerator::EscapeUsersAllocaMapTy EscapeMap
See BlockGenerator::EscapeMap.
BlockGenerator BlockGen
The generator used to copy a basic block.
BlockGenerator & getBlockGenerator()
Get the associated block generator.
int getNumberOfIterations(isl::ast_node_for For)
Return non-negative number of iterations in case of the following form of a loop and -1 otherwise.
Value * createRTC(isl_ast_expr *Condition)
Generate code that evaluates Condition at run-time.
IslExprBuilder & getExprBuilder()
MapVector< const Loop *, const SCEV * > OutsideLoopIterations
The current iteration of out-of-scop loops.
static MemAccInst dyn_cast(llvm::Value &V)
Definition ScopHelper.h:179
Represent memory accesses in statements.
Definition ScopInfo.h:426
Instruction * getAccessInstruction() const
Return the access instruction of this memory access.
Definition ScopInfo.h:880
bool isRead() const
Is this a read memory access?
Definition ScopInfo.h:755
isl::map getAddressFunction() const
Get an isl map describing the memory address accessed.
Definition ScopInfo.cpp:574
const ScopArrayInfo * getScopArrayInfo() const
Legacy name of getOriginalScopArrayInfo().
Definition ScopInfo.h:848
Value * getOriginalBaseAddr() const
Get the original base address of this access (e.g.
Definition ScopInfo.h:828
bool isArrayKind() const
Old name of isOriginalArrayKind.
Definition ScopInfo.h:950
This ParallelLoopGenerator subclass handles the generation of parallelized code, utilizing the GNU Op...
This ParallelLoopGenerator subclass handles the generation of parallelized code, utilizing the LLVM O...
Statement of the Scop.
Definition ScopInfo.h:1135
Scop * getParent()
Definition ScopInfo.h:1523
const std::vector< Instruction * > & getInstructions() const
Definition ScopInfo.h:1526
bool isBlockStmt() const
Return true if this statement represents a single basic block.
Definition ScopInfo.h:1316
size_t size() const
Definition ScopInfo.h:1519
Region * getRegion() const
Get the region represented by this ScopStmt (if any).
Definition ScopInfo.h:1325
BasicBlock * getBasicBlock() const
Get the BasicBlock represented by this ScopStmt (if any).
Definition ScopInfo.h:1313
bool isCopyStmt() const
Return true if this is a copy statement.
Definition ScopInfo.h:1319
bool isRegionStmt() const
Return true if this statement represents a whole region.
Definition ScopInfo.h:1328
Loop * getLoopForDimension(unsigned Dimension) const
Get the loop for a dimension.
isl::set getDomain() const
Get the iteration domain of this ScopStmt.
void setAstBuild(isl::ast_build B)
Set the isl AST build.
Definition ScopInfo.h:1557
iterator begin()
Definition ScopInfo.h:1515
ScalarEvolution * getSE() const
Return the scalar evolution.
isl::ctx getIslCtx() const
Get the isl context of this static control part.
LoopInfo * getLI() const
Return the LoopInfo used for this Scop.
Definition ScopInfo.h:2010
bool contains(const Loop *L) const
Check if L is contained in the SCoP.
Definition ScopInfo.h:2092
const Region & getRegion() const
Get the maximum region of this static control part.
Definition ScopInfo.h:2085
isl::set getContext() const
Get the constraint on parameter of this Scop.
Determine the nature of a value's use within a statement.
const SCEV * getScevExpr() const
Return the ScalarEvolution representation of Val.
static VirtualUse create(Scop *S, const Use &U, LoopInfo *LI, bool Virtual)
Get a VirtualUse for an llvm::Use.
UseKind getKind() const
Return the type of use.
#define __isl_take
Definition ctx.h:23
#define __isl_give
Definition ctx.h:20
#define __isl_keep
Definition ctx.h:26
__isl_export __isl_keep const char * isl_id_get_name(__isl_keep isl_id *id)
Definition isl_id.c:41
__isl_null isl_id * isl_id_free(__isl_take isl_id *id)
Definition isl_id.c:207
void * isl_id_get_user(__isl_keep isl_id *id)
Definition isl_id.c:36
enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
Definition isl_ast.c:276
enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
Definition isl_ast.c:907
#define isl_set
#define assert(exp)
__isl_export __isl_give isl_set * isl_map_domain(__isl_take isl_map *bmap)
Definition isl_map.c:8777
__isl_export __isl_give isl_set * isl_map_range(__isl_take isl_map *map)
Definition isl_map.c:6728
boolean manage(isl_bool val)
Definition cpp-checked.h:98
aff manage_copy(__isl_keep isl_aff *ptr)
std::forward_list< MemoryAccess * > MemoryAccessList
Ordered list type to hold accesses.
Definition ScopInfo.h:1086
void findValues(const llvm::SCEV *Expr, llvm::ScalarEvolution &SE, llvm::SetVector< llvm::Value * > &Values)
Find the values referenced by SCEVUnknowns in a given SCEV expression.
void findLoops(const llvm::SCEV *Expr, llvm::SetVector< const llvm::Loop * > &Loops)
Find the loops referenced from a SCEV expression.
llvm::Value * expandCodeFor(Scop &S, llvm::ScalarEvolution &SE, llvm::Function *GenFn, llvm::ScalarEvolution &GenSE, const llvm::DataLayout &DL, const char *Name, const llvm::SCEV *E, llvm::Type *Ty, llvm::BasicBlock::iterator IP, ValueMapT *VMap, LoopToScevMapT *LoopMap, llvm::BasicBlock *RTCBB)
Wrapper for SCEVExpander extended to all Polly features.
@ Value
MemoryKind::Value: Models an llvm::Value.
Definition ScopInfo.h:149
void addReferencesFromStmt(ScopStmt *Stmt, void *UserPtr, bool CreateScalarRefs=true)
Extract the out-of-scop values and SCEVs referenced from a ScopStmt.
BandAttr * getLoopAttr(const isl::id &Id)
Return the BandAttr of a loop's isl::id.
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::iota_range< unsigned > rangeIslSize(unsigned Begin, isl::size End)
Check that End is valid and return an iterator from Begin to End.
Definition ISLTools.cpp:597
llvm::DenseMap< const llvm::Loop *, llvm::SCEVUse > LoopToScevMapT
Same as llvm/Analysis/ScalarEvolutionExpressions.h.
Definition ScopHelper.h:41
llvm::DenseMap< llvm::AssertingVH< llvm::Value >, llvm::AssertingVH< llvm::Value > > ValueMapT
Type to remap values.
Definition ScopHelper.h:106
std::pair< llvm::BasicBlock *, llvm::BasicBlock * > BBPair
Type to hold region delimiters (entry & exit block).
Definition Utils.h:31
__isl_export __isl_give isl_set * isl_set_universe(__isl_take isl_space *space)
Definition isl_map.c:6985
__isl_export __isl_give isl_space * isl_set_get_space(__isl_keep isl_set *set)
Definition isl_map.c:604
__isl_export isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
Definition isl_map.c:9748
__isl_export __isl_give isl_set * isl_set_intersect_params(__isl_take isl_set *set, __isl_take isl_set *params)
Definition isl_map.c:4538
__isl_export __isl_give isl_set * isl_set_gist_params(__isl_take isl_set *set, __isl_take isl_set *context)
__isl_null isl_set * isl_set_free(__isl_take isl_set *set)
Definition isl_map.c:4055
__isl_export isl_bool isl_set_is_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
isl_bool isl_set_involves_dims(__isl_keep isl_set *set, enum isl_dim_type type, unsigned first, unsigned n)
Definition isl_map.c:3528
isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type)
Definition isl_map.c:132
__isl_give isl_id * isl_set_get_dim_id(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos)
Definition isl_map.c:1004
__isl_export isl_bool isl_set_is_empty(__isl_keep isl_set *set)
Definition isl_map.c:9828
@ isl_dim_param
Definition space_type.h:15
Represent the attributes of a loop.
Definition ScopHelper.h:538
Type for equivalent invariant accesses and their domain context.
Definition ScopInfo.h:1101
MemoryAccessList InvariantAccesses
Memory accesses now treated invariant.
Definition ScopInfo.h:1110
Type * AccessType
The type of the invariant access.
Definition ScopInfo.h:1122
isl::set ExecutionContext
The execution context under which the memory location is accessed.
Definition ScopInfo.h:1116
const SCEV * IdentifyingPointer
The pointer that identifies this equivalence class.
Definition ScopInfo.h:1103
static void createCPUPrinter(PollyIRBuilder &Builder, Args... args)
Print a set of LLVM-IR Values or StringRefs via printf.
static llvm::Value * getPrintableString(PollyIRBuilder &Builder, llvm::StringRef Str)
Generate a constant string into the builder's llvm::Module which can be passed to createCPUPrinter().
static TupleKindPtr Domain("Domain")
static TupleKindPtr Ctx
__isl_give isl_set * isl_set_from_union_set(__isl_take isl_union_set *uset)