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 MapVector<const Loop *, const SCEV *> OutsideLoopIterationsCopy =
592
593 // Get the analyses for the subfunction. ParallelLoopGenerator already create
594 // DominatorTree and LoopInfo for us.
595 DominatorTree *SubDT = ParallelLoopGenPtr->getCalleeDominatorTree();
596 LoopInfo *SubLI = ParallelLoopGenPtr->getCalleeLoopInfo();
597
598 // Create TargetLibraryInfo, AssumptionCachem and ScalarEvolution ourselves.
599 // TODO: Ideally, we would use the pass manager's TargetLibraryInfoPass and
600 // AssumptionAnalysis instead of our own. They contain more target-specific
601 // information than we have available here: TargetLibraryInfoImpl can be a
602 // derived class determined by TargetMachine, AssumptionCache can be
603 // configured using a TargetTransformInfo object also derived from
604 // TargetMachine.
605 TargetLibraryInfoImpl BaselineInfoImpl(SubFn->getParent()->getTargetTriple());
606 TargetLibraryInfo CalleeTLI(BaselineInfoImpl, SubFn);
607 AssumptionCache CalleeAC(*SubFn);
608 std::unique_ptr<ScalarEvolution> SubSE = std::make_unique<ScalarEvolution>(
609 *SubFn, CalleeTLI, CalleeAC, *SubDT, *SubLI);
610
611 // Switch to the subfunction
612 GenDT = SubDT;
613 GenLI = SubLI;
614 GenSE = SubSE.get();
615 BlockGen.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
616 RegionGen.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
617 ExprBuilder.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
618 Builder.SetInsertPoint(LoopBody);
619
620 // Update the ValueMap to use instructions in the subfunction. Note that
621 // "GlobalMap" used in BlockGenerator/IslExprBuilder is a reference to this
622 // ValueMap.
623 for (auto &[OldVal, NewVal] : ValueMap) {
624 NewVal = NewValues.lookup(NewVal);
625
626 // Clean-up any value that getReferencesInSubtree thinks we do not need.
627 // DenseMap::erase only writes a tombstone (and destroys OldVal/NewVal), so
628 // does not invalidate our iterator.
629 if (!NewVal)
630 ValueMap.erase(OldVal);
631 }
632
633 // This is for NewVals that do not appear in ValueMap (such as SCoP-invariant
634 // values whose original value can be reused as long as we are in the same
635 // function). No need to map the others.
636 for (auto &[NewVal, NewNewVal] : NewValues) {
637 if (Instruction *NewValInst = dyn_cast<Instruction>((Value *)NewVal)) {
638 if (S.contains(NewValInst))
639 continue;
640 assert(NewValInst->getFunction() == &S.getFunction());
641 }
642 assert(!ValueMap.contains(NewVal));
643 ValueMap[NewVal] = NewNewVal;
644 }
645
646 // Also update the IDToValue map to use instructions from the subfunction.
647 for (auto &[OldVal, NewVal] : IDToValue) {
648 NewVal = NewValues.lookup(NewVal);
649 assert(NewVal);
650 }
651 IDToValue[IteratorID] = IV;
652
653 // Also update OutsideLoopIterations to use values from the subfunction.
654 // SCEVExpander may fold identity operations (e.g. x+0 -> x), returning the
655 // original loop PHI instead of a new instruction. We need to remap these
656 // values through NewValues so GenSE (now SubSE) doesn't operate on values
657 // from the caller function.
658 for (auto &[L, S] : OutsideLoopIterations) {
659 if (auto *U = dyn_cast<SCEVUnknown>(S)) {
660 Value *NewVal = NewValues.lookup(U->getValue());
661 assert(NewVal && "must have a new value");
662 OutsideLoopIterations[L] = GenSE->getUnknown(NewVal);
663 }
664 }
665
666#ifndef NDEBUG
667 // Check whether the maps now exclusively refer to SubFn values.
668 for (auto &[OldVal, SubVal] : ValueMap) {
669 Instruction *SubInst = dyn_cast<Instruction>((Value *)SubVal);
670 assert(SubInst->getFunction() == SubFn &&
671 "Instructions from outside the subfn cannot be accessed within the "
672 "subfn");
673 }
674 for (auto &[Id, SubVal] : IDToValue) {
675 Instruction *SubInst = dyn_cast<Instruction>((Value *)SubVal);
676 assert(SubInst->getFunction() == SubFn &&
677 "Instructions from outside the subfn cannot be accessed within the "
678 "subfn");
679 }
680#endif
681
682 ValueMapT NewValuesReverse;
683 for (auto P : NewValues)
684 NewValuesReverse[P.second] = P.first;
685
686 Annotator.addAlternativeAliasBases(NewValuesReverse);
687
688 create(Body);
689
690 Annotator.resetAlternativeAliasBases();
691
692 // Resume working on the caller function.
693 GenDT = CallerDT;
694 GenLI = CallerLI;
695 GenSE = CallerSE;
696 IDToValue = std::move(IDToValueCopy);
697 ValueMap = std::move(CallerGlobals);
698 OutsideLoopIterations = std::move(OutsideLoopIterationsCopy);
699 ExprBuilder.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
700 RegionGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
701 BlockGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
702 Builder.SetInsertPoint(AfterLoop);
703
705 isl_ast_expr_free(Iterator);
706 isl_id_free(IteratorID);
707
708 ParallelLoops++;
709}
710
714 return;
715 }
716 bool Parallel = (IslAstInfo::isParallel(isl::manage_copy(For)) &&
718 createForSequential(isl::manage(For).as<isl::ast_node_for>(), Parallel);
719}
720
723
724 Function *F = Builder.GetInsertBlock()->getParent();
725 LLVMContext &Context = F->getContext();
726
727 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
728 Builder.GetInsertPoint(), GenDT, GenLI);
729 CondBB->setName("polly.cond");
730 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), GenDT, GenLI);
731 MergeBB->setName("polly.merge");
732 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
733 BasicBlock *ElseBB = BasicBlock::Create(Context, "polly.else", F);
734
735 GenDT->addNewBlock(ThenBB, CondBB);
736 GenDT->addNewBlock(ElseBB, CondBB);
737 GenDT->changeImmediateDominator(MergeBB, CondBB);
738
739 Loop *L = GenLI->getLoopFor(CondBB);
740 if (L) {
741 L->addBasicBlockToLoop(ThenBB, *GenLI);
742 L->addBasicBlockToLoop(ElseBB, *GenLI);
743 }
744
745 CondBB->getTerminator()->eraseFromParent();
746
747 Builder.SetInsertPoint(CondBB);
748 Value *Predicate = ExprBuilder.create(Cond);
749 Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
750 Builder.SetInsertPoint(ThenBB);
751 Builder.CreateBr(MergeBB);
752 Builder.SetInsertPoint(ElseBB);
753 Builder.CreateBr(MergeBB);
754 Builder.SetInsertPoint(ThenBB, ThenBB->begin());
755
757
758 Builder.SetInsertPoint(ElseBB, ElseBB->begin());
759
762
763 Builder.SetInsertPoint(MergeBB, MergeBB->begin());
764
766
767 IfConditions++;
768}
769
770__isl_give isl_id_to_ast_expr *
772 __isl_keep isl_ast_node *Node) {
773 isl::id_to_ast_expr NewAccesses =
775
777 assert(!Build.is_null() && "Could not obtain isl_ast_build from user node");
778 Stmt->setAstBuild(Build);
779
780 for (auto *MA : *Stmt) {
781 if (!MA->hasNewAccessRelation()) {
783 if (!MA->isAffine())
784 continue;
785 if (MA->getLatestScopArrayInfo()->getBasePtrOriginSAI())
786 continue;
787
788 auto *BasePtr =
789 dyn_cast<Instruction>(MA->getLatestScopArrayInfo()->getBasePtr());
790 if (BasePtr && Stmt->getParent()->getRegion().contains(BasePtr))
791 continue;
792 } else {
793 continue;
794 }
795 }
796 assert(MA->isAffine() &&
797 "Only affine memory accesses can be code generated");
798
799 isl::union_map Schedule = Build.get_schedule();
800
801#ifndef NDEBUG
802 if (MA->isRead()) {
803 auto Dom = Stmt->getDomain().release();
804 auto SchedDom = isl_set_from_union_set(Schedule.domain().release());
805 auto AccDom = isl_map_domain(MA->getAccessRelation().release());
806 Dom = isl_set_intersect_params(Dom,
807 Stmt->getParent()->getContext().release());
808 SchedDom = isl_set_intersect_params(
809 SchedDom, Stmt->getParent()->getContext().release());
810 assert(isl_set_is_subset(SchedDom, AccDom) &&
811 "Access relation not defined on full schedule domain");
812 assert(isl_set_is_subset(Dom, AccDom) &&
813 "Access relation not defined on full domain");
814 isl_set_free(AccDom);
815 isl_set_free(SchedDom);
816 isl_set_free(Dom);
817 }
818#endif
819
820 isl::pw_multi_aff PWAccRel = MA->applyScheduleToAccessRelation(Schedule);
821
822 // isl cannot generate an index expression for access-nothing accesses.
823 isl::set AccDomain = PWAccRel.domain();
824 if (AccDomain.is_empty())
825 continue;
826
827 isl::ast_expr AccessExpr = Build.access_from(PWAccRel);
828 NewAccesses = NewAccesses.set(MA->getId(), AccessExpr);
829 }
830
831 return NewAccesses.release();
832}
833
835 ScopStmt *Stmt, LoopToScevMapT &LTS) {
837 "Expression of type 'op' expected");
839 "Operation of type 'call' expected");
840 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr) - 1; ++i) {
841 isl_ast_expr *SubExpr;
842 Value *V;
843
844 SubExpr = isl_ast_expr_get_op_arg(Expr, i + 1);
845 V = ExprBuilder.create(SubExpr);
846 ScalarEvolution *SE = Stmt->getParent()->getSE();
847 LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V);
848 }
849
850 isl_ast_expr_free(Expr);
851}
852
854 __isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
855 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
856 __isl_take isl_id *IteratorID) {
857 int i = 0;
858
859 Value *OldValue = IDToValue[IteratorID];
860 for (Value *IV : IVS) {
861 IDToValue[IteratorID] = IV;
862 createSubstitutions(isl_ast_expr_copy(Expr), Stmt, VLTS[i]);
863 i++;
864 }
865
866 IDToValue[IteratorID] = OldValue;
867 isl_id_free(IteratorID);
868 isl_ast_expr_free(Expr);
869}
870
872 ScopStmt *Stmt, __isl_keep isl_id_to_ast_expr *NewAccesses) {
873 assert(Stmt->size() == 2);
874 auto ReadAccess = Stmt->begin();
875 auto WriteAccess = ReadAccess++;
876 assert((*ReadAccess)->isRead() && (*WriteAccess)->isMustWrite());
877 assert((*ReadAccess)->getElementType() == (*WriteAccess)->getElementType() &&
878 "Accesses use the same data type");
879 assert((*ReadAccess)->isArrayKind() && (*WriteAccess)->isArrayKind());
880 auto *AccessExpr =
881 isl_id_to_ast_expr_get(NewAccesses, (*ReadAccess)->getId().release());
882 auto *LoadValue = ExprBuilder.create(AccessExpr);
883 AccessExpr =
884 isl_id_to_ast_expr_get(NewAccesses, (*WriteAccess)->getId().release());
885 auto *StoreAddr = ExprBuilder.createAccessAddress(AccessExpr).first;
886 Builder.CreateStore(LoadValue, StoreAddr);
887}
888
890 assert(!OutsideLoopIterations.contains(L) &&
891 "trying to materialize loop induction variable twice");
892 const SCEV *OuterLIV = SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)),
893 SE.getUnknown(Builder.getInt64(1)), L,
894 SCEV::FlagAnyWrap);
895 Value *V = generateSCEV(OuterLIV);
896 OutsideLoopIterations[L] = SE.getUnknown(V);
897 return V;
898}
899
901 LoopToScevMapT LTS;
902 isl_id *Id;
903 ScopStmt *Stmt;
904
906 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
907 Id = isl_ast_expr_get_id(StmtExpr);
908 isl_ast_expr_free(StmtExpr);
909
910 LTS.insert_range(OutsideLoopIterations);
911
912 Stmt = (ScopStmt *)isl_id_get_user(Id);
913 auto *NewAccesses = createNewAccesses(Stmt, User);
914 if (Stmt->isCopyStmt()) {
915 generateCopyStmt(Stmt, NewAccesses);
916 isl_ast_expr_free(Expr);
917 } else {
918 createSubstitutions(Expr, Stmt, LTS);
919
920 if (Stmt->isBlockStmt())
921 BlockGen.copyStmt(*Stmt, LTS, NewAccesses);
922 else
923 RegionGen.copyStmt(*Stmt, LTS, NewAccesses);
924 }
925
926 isl_id_to_ast_expr_free(NewAccesses);
927 isl_ast_node_free(User);
928 isl_id_free(Id);
929}
930
932 isl_ast_node_list *List = isl_ast_node_block_get_children(Block);
933
934 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
935 create(isl_ast_node_list_get_ast_node(List, i));
936
937 isl_ast_node_free(Block);
938 isl_ast_node_list_free(List);
939}
940
942 if (!TraceStmts)
943 return;
944
945 // Sequence of strings to print.
946 SmallVector<llvm::Value *, 8> Values;
947 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "Scop: "));
948
949 auto Params = S.getParamSpace();
950 for (int i : rangeIslSize(0, Params.dim(isl::dim::param))) {
951 if (i != 0)
952 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, " "));
953
954 isl::id PId = Params.get_dim_id(isl::dim::param, i);
955 Values.push_back(
957 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "="));
958 Values.push_back(IDToValue.lookup(PId.get()));
959 }
960
961 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "\n"));
962 RuntimeDebugBuilder::createCPUPrinter(Builder, ArrayRef<Value *>(Values));
963}
964
966 switch (isl_ast_node_get_type(Node)) {
968 llvm_unreachable("code generation error");
970 createMark(Node);
971 return;
972 case isl_ast_node_for:
973 createFor(Node);
974 return;
975 case isl_ast_node_if:
976 createIf(Node);
977 return;
979 createUser(Node);
980 return;
982 createBlock(Node);
983 return;
984 }
985
986 llvm_unreachable("Unknown isl_ast_node type");
987}
988
990 // If the Id is already mapped, skip it.
991 if (!IDToValue.count(Id)) {
992 auto *ParamSCEV = (const SCEV *)isl_id_get_user(Id);
993 Value *V = nullptr;
994
995 // Parameters could refer to invariant loads that need to be
996 // preloaded before we can generate code for the parameter. Thus,
997 // check if any value referred to in ParamSCEV is an invariant load
998 // and if so make sure its equivalence class is preloaded.
999 SetVector<Value *> Values;
1000 findValues(ParamSCEV, SE, Values);
1001 for (auto *Val : Values) {
1002 // Check if the value is an instruction in a dead block within the SCoP
1003 // and if so do not code generate it.
1004 if (auto *Inst = dyn_cast<Instruction>(Val)) {
1005 if (S.contains(Inst)) {
1006 bool IsDead = true;
1007
1008 // Check for "undef" loads first, then if there is a statement for
1009 // the parent of Inst and lastly if the parent of Inst has an empty
1010 // domain. In the first and last case the instruction is dead but if
1011 // there is a statement or the domain is not empty Inst is not dead.
1012 auto MemInst = MemAccInst::dyn_cast(Inst);
1013 auto Address = MemInst ? MemInst.getPointerOperand() : nullptr;
1014 if (Address && SE.getUnknown(UndefValue::get(Address->getType())) ==
1015 SE.getPointerBase(SE.getSCEV(Address))) {
1016 } else if (S.getStmtFor(Inst)) {
1017 IsDead = false;
1018 } else {
1019 auto *Domain = S.getDomainConditions(Inst->getParent()).release();
1020 IsDead = isl_set_is_empty(Domain);
1022 }
1023
1024 if (IsDead) {
1025 V = UndefValue::get(ParamSCEV->getType());
1026 break;
1027 }
1028 }
1029 }
1030
1031 if (auto *IAClass = S.lookupInvariantEquivClass(Val)) {
1032 // Check if this invariant access class is empty, hence if we never
1033 // actually added a loads instruction to it. In that case it has no
1034 // (meaningful) users and we should not try to code generate it.
1035 if (IAClass->InvariantAccesses.empty())
1036 V = UndefValue::get(ParamSCEV->getType());
1037
1038 if (!preloadInvariantEquivClass(*IAClass)) {
1039 isl_id_free(Id);
1040 return false;
1041 }
1042 }
1043 }
1044
1045 V = V ? V : generateSCEV(ParamSCEV);
1046 IDToValue[Id] = V;
1047 }
1048
1049 isl_id_free(Id);
1050 return true;
1051}
1052
1054 for (unsigned i = 0, e = isl_set_dim(Set, isl_dim_param); i < e; ++i) {
1055 if (!isl_set_involves_dims(Set, isl_dim_param, i, 1))
1056 continue;
1058 if (!materializeValue(Id))
1059 return false;
1060 }
1061 return true;
1062}
1063
1065 for (const SCEV *Param : S.parameters()) {
1066 isl_id *Id = S.getIdForParam(Param).release();
1067 if (!materializeValue(Id))
1068 return false;
1069 }
1070 return true;
1071}
1072
1074 isl::ast_build Build,
1075 Instruction *AccInst) {
1076 isl::pw_multi_aff PWAccRel = isl::pw_multi_aff::from_set(AccessRange);
1077 PWAccRel = PWAccRel.gist_params(S.getContext());
1078 isl::ast_expr Access = Build.access_from(PWAccRel);
1079 isl::ast_expr Address = Access.address_of();
1080 Value *AddressValue = ExprBuilder.create(Address.release());
1081 Value *PreloadVal;
1082
1083 // Correct the type as the SAI might have a different type than the user
1084 // expects, especially if the base pointer is a struct.
1085 Type *Ty = AccInst->getType();
1086
1087 auto *Ptr = AddressValue;
1088 auto Name = Ptr->getName();
1089 PreloadVal = Builder.CreateLoad(Ty, Ptr, Name + ".load");
1090 if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal))
1091 PreloadInst->setAlignment(cast<LoadInst>(AccInst)->getAlign());
1092
1093 // TODO: This is only a hot fix for SCoP sequences that use the same load
1094 // instruction contained and hoisted by one of the SCoPs.
1095 if (SE.isSCEVable(Ty))
1096 SE.forgetValue(AccInst);
1097
1098 return PreloadVal;
1099}
1100
1102 isl::set Domain) {
1103 isl::set AccessRange = MA.getAddressFunction().range();
1104
1105 if (!materializeParameters(AccessRange.get()))
1106 return nullptr;
1107
1108 isl::ast_build Build =
1110 isl::set Universe = isl::set::universe(Domain.get_space());
1111 bool AlwaysExecuted = Domain.is_equal(Universe);
1112
1113 Instruction *AccInst = MA.getAccessInstruction();
1114 Type *AccInstTy = AccInst->getType();
1115
1116 if (AlwaysExecuted)
1117 return preloadUnconditionally(AccessRange, Build, AccInst);
1118
1119 if (!materializeParameters(Domain.get()))
1120 return nullptr;
1121
1122 isl::ast_expr DomainCond = Build.expr_from(Domain);
1123
1124 ExprBuilder.setTrackOverflow(true);
1125 Value *Cond = ExprBuilder.createBool(DomainCond.release());
1126 Value *OverflowHappened = Builder.CreateNot(ExprBuilder.getOverflowState(),
1127 "polly.preload.cond.overflown");
1128 Cond = Builder.CreateAnd(Cond, OverflowHappened, "polly.preload.cond.result");
1129 ExprBuilder.setTrackOverflow(false);
1130
1131 if (!Cond->getType()->isIntegerTy(1))
1132 Cond = Builder.CreateIsNotNull(Cond);
1133
1134 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1135 Builder.GetInsertPoint(), GenDT, GenLI);
1136 CondBB->setName("polly.preload.cond");
1137
1138 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), GenDT, GenLI);
1139 MergeBB->setName("polly.preload.merge");
1140
1141 Function *F = Builder.GetInsertBlock()->getParent();
1142 LLVMContext &Context = F->getContext();
1143 BasicBlock *ExecBB = BasicBlock::Create(Context, "polly.preload.exec", F);
1144
1145 GenDT->addNewBlock(ExecBB, CondBB);
1146 if (Loop *L = GenLI->getLoopFor(CondBB))
1147 L->addBasicBlockToLoop(ExecBB, *GenLI);
1148
1149 auto *CondBBTerminator = CondBB->getTerminator();
1150 Builder.SetInsertPoint(CondBB, CondBBTerminator->getIterator());
1151 Builder.CreateCondBr(Cond, ExecBB, MergeBB);
1152 CondBBTerminator->eraseFromParent();
1153
1154 Builder.SetInsertPoint(ExecBB);
1155 Builder.CreateBr(MergeBB);
1156
1157 Builder.SetInsertPoint(ExecBB, ExecBB->getTerminator()->getIterator());
1158 Value *PreAccInst = preloadUnconditionally(AccessRange, Build, AccInst);
1159 Builder.SetInsertPoint(MergeBB, MergeBB->getTerminator()->getIterator());
1160 auto *MergePHI = Builder.CreatePHI(
1161 AccInstTy, 2, "polly.preload." + AccInst->getName() + ".merge");
1162 Value *PreloadVal = MergePHI;
1163
1164 if (!PreAccInst) {
1165 PreloadVal = nullptr;
1166 PreAccInst = UndefValue::get(AccInstTy);
1167 }
1168
1169 MergePHI->addIncoming(PreAccInst, ExecBB);
1170 MergePHI->addIncoming(Constant::getNullValue(AccInstTy), CondBB);
1171
1172 return PreloadVal;
1173}
1174
1176 InvariantEquivClassTy &IAClass) {
1177 // For an equivalence class of invariant loads we pre-load the representing
1178 // element with the unified execution context. However, we have to map all
1179 // elements of the class to the one preloaded load as they are referenced
1180 // during the code generation and therefore need to be mapped.
1181 const MemoryAccessList &MAs = IAClass.InvariantAccesses;
1182 if (MAs.empty())
1183 return true;
1184
1185 MemoryAccess *MA = MAs.front();
1186 assert(MA->isArrayKind() && MA->isRead());
1187
1188 // If the access function was already mapped, the preload of this equivalence
1189 // class was triggered earlier already and doesn't need to be done again.
1190 if (ValueMap.count(MA->getAccessInstruction()))
1191 return true;
1192
1193 // Check for recursion which can be caused by additional constraints, e.g.,
1194 // non-finite loop constraints. In such a case we have to bail out and insert
1195 // a "false" runtime check that will cause the original code to be executed.
1196 auto PtrId = std::make_pair(IAClass.IdentifyingPointer, IAClass.AccessType);
1197 if (!PreloadedPtrs.insert(PtrId).second)
1198 return false;
1199
1200 // The execution context of the IAClass.
1201 isl::set &ExecutionCtx = IAClass.ExecutionContext;
1202
1203 // If the base pointer of this class is dependent on another one we have to
1204 // make sure it was preloaded already.
1205 auto *SAI = MA->getScopArrayInfo();
1206 if (auto *BaseIAClass = S.lookupInvariantEquivClass(SAI->getBasePtr())) {
1207 if (!preloadInvariantEquivClass(*BaseIAClass))
1208 return false;
1209
1210 // After we preloaded the BaseIAClass we adjusted the BaseExecutionCtx and
1211 // we need to refine the ExecutionCtx.
1212 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1213 ExecutionCtx = ExecutionCtx.intersect(BaseExecutionCtx);
1214 }
1215
1216 // If the size of a dimension is dependent on another class, make sure it is
1217 // preloaded.
1218 for (unsigned i = 1, e = SAI->getNumberOfDimensions(); i < e; ++i) {
1219 const SCEV *Dim = SAI->getDimensionSize(i);
1220 SetVector<Value *> Values;
1221 findValues(Dim, SE, Values);
1222 for (auto *Val : Values) {
1223 if (auto *BaseIAClass = S.lookupInvariantEquivClass(Val)) {
1224 if (!preloadInvariantEquivClass(*BaseIAClass))
1225 return false;
1226
1227 // After we preloaded the BaseIAClass we adjusted the BaseExecutionCtx
1228 // and we need to refine the ExecutionCtx.
1229 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1230 ExecutionCtx = ExecutionCtx.intersect(BaseExecutionCtx);
1231 }
1232 }
1233 }
1234
1235 Instruction *AccInst = MA->getAccessInstruction();
1236 Type *AccInstTy = AccInst->getType();
1237
1238 Value *PreloadVal = preloadInvariantLoad(*MA, ExecutionCtx);
1239 if (!PreloadVal)
1240 return false;
1241
1242 for (const MemoryAccess *MA : MAs) {
1243 Instruction *MAAccInst = MA->getAccessInstruction();
1244 assert(PreloadVal->getType() == MAAccInst->getType());
1245 ValueMap[MAAccInst] = PreloadVal;
1246 }
1247
1248 if (SE.isSCEVable(AccInstTy)) {
1249 isl_id *ParamId = S.getIdForParam(SE.getSCEV(AccInst)).release();
1250 if (ParamId)
1251 IDToValue[ParamId] = PreloadVal;
1252 isl_id_free(ParamId);
1253 }
1254
1255 BasicBlock *EntryBB = &Builder.GetInsertBlock()->getParent()->getEntryBlock();
1256 auto *Alloca = new AllocaInst(AccInstTy, DL.getAllocaAddrSpace(),
1257 AccInst->getName() + ".preload.s2a",
1258 EntryBB->getFirstInsertionPt());
1259 Builder.CreateStore(PreloadVal, Alloca);
1260 ValueMapT PreloadedPointer;
1261 PreloadedPointer[PreloadVal] = AccInst;
1262 Annotator.addAlternativeAliasBases(PreloadedPointer);
1263
1264 for (auto *DerivedSAI : SAI->getDerivedSAIs()) {
1265 Value *BasePtr = DerivedSAI->getBasePtr();
1266
1267 for (const MemoryAccess *MA : MAs) {
1268 // As the derived SAI information is quite coarse, any load from the
1269 // current SAI could be the base pointer of the derived SAI, however we
1270 // should only change the base pointer of the derived SAI if we actually
1271 // preloaded it.
1272 if (BasePtr == MA->getOriginalBaseAddr()) {
1273 assert(BasePtr->getType() == PreloadVal->getType());
1274 DerivedSAI->setBasePtr(PreloadVal);
1275 }
1276
1277 // For scalar derived SAIs we remap the alloca used for the derived value.
1278 if (BasePtr == MA->getAccessInstruction())
1279 ScalarMap[DerivedSAI] = Alloca;
1280 }
1281 }
1282
1283 for (const MemoryAccess *MA : MAs) {
1284 Instruction *MAAccInst = MA->getAccessInstruction();
1285 // Use the escape system to get the correct value to users outside the SCoP.
1287 for (auto *U : MAAccInst->users())
1288 if (Instruction *UI = dyn_cast<Instruction>(U))
1289 if (!S.contains(UI))
1290 EscapeUsers.push_back(UI);
1291
1292 if (EscapeUsers.empty())
1293 continue;
1294
1296 std::make_pair(Alloca, std::move(EscapeUsers));
1297 }
1298
1299 return true;
1300}
1301
1303 for (auto &SAI : S.arrays()) {
1304 if (SAI->getBasePtr())
1305 continue;
1306
1307 assert(SAI->getNumberOfDimensions() > 0 && SAI->getDimensionSize(0) &&
1308 "The size of the outermost dimension is used to declare newly "
1309 "created arrays that require memory allocation.");
1310
1311 Type *NewArrayType = nullptr;
1312
1313 // Get the size of the array = size(dim_1)*...*size(dim_n)
1314 uint64_t ArraySizeInt = 1;
1315 for (int i = SAI->getNumberOfDimensions() - 1; i >= 0; i--) {
1316 auto *DimSize = SAI->getDimensionSize(i);
1317 unsigned UnsignedDimSize = static_cast<const SCEVConstant *>(DimSize)
1318 ->getAPInt()
1319 .getLimitedValue();
1320
1321 if (!NewArrayType)
1322 NewArrayType = SAI->getElementType();
1323
1324 NewArrayType = ArrayType::get(NewArrayType, UnsignedDimSize);
1325 ArraySizeInt *= UnsignedDimSize;
1326 }
1327
1328 if (SAI->isOnHeap()) {
1329 LLVMContext &Ctx = NewArrayType->getContext();
1330
1331 // Get the IntPtrTy from the Datalayout
1332 auto IntPtrTy = DL.getIntPtrType(Ctx);
1333
1334 // Get the size of the element type in bits
1335 unsigned Size = SAI->getElemSizeInBytes();
1336
1337 // Insert the malloc call at polly.start
1338 BasicBlock *StartBlock = std::get<0>(StartExitBlocks);
1339 Builder.SetInsertPoint(StartBlock,
1340 StartBlock->getTerminator()->getIterator());
1341 auto *CreatedArray = Builder.CreateMalloc(
1342 IntPtrTy, SAI->getElementType(),
1343 ConstantInt::get(Type::getInt64Ty(Ctx), Size),
1344 ConstantInt::get(Type::getInt64Ty(Ctx), ArraySizeInt), nullptr,
1345 SAI->getName());
1346
1347 SAI->setBasePtr(CreatedArray);
1348
1349 // Insert the free call at polly.exiting
1350 BasicBlock *ExitingBlock = std::get<1>(StartExitBlocks);
1351 Builder.SetInsertPoint(ExitingBlock,
1352 ExitingBlock->getTerminator()->getIterator());
1353 Builder.CreateFree(CreatedArray);
1354 } else {
1355 auto InstIt = Builder.GetInsertBlock()
1356 ->getParent()
1357 ->getEntryBlock()
1358 .getTerminator()
1359 ->getIterator();
1360
1361 auto *CreatedArray = new AllocaInst(NewArrayType, DL.getAllocaAddrSpace(),
1362 SAI->getName(), InstIt);
1364 CreatedArray->setAlignment(Align(PollyTargetFirstLevelCacheLineSize));
1365 SAI->setBasePtr(CreatedArray);
1366 }
1367 }
1368}
1369
1371 auto &InvariantEquivClasses = S.getInvariantAccesses();
1372 if (InvariantEquivClasses.empty())
1373 return true;
1374
1375 BasicBlock *PreLoadBB = SplitBlock(Builder.GetInsertBlock(),
1376 Builder.GetInsertPoint(), GenDT, GenLI);
1377 PreLoadBB->setName("polly.preload.begin");
1378 Builder.SetInsertPoint(PreLoadBB, PreLoadBB->begin());
1379
1380 for (auto &IAClass : InvariantEquivClasses)
1381 if (!preloadInvariantEquivClass(IAClass))
1382 return false;
1383
1384 return true;
1385}
1386
1388 // Materialize values for the parameters of the SCoP.
1390
1391 // Generate values for the current loop iteration for all surrounding loops.
1392 //
1393 // We may also reference loops outside of the scop which do not contain the
1394 // scop itself, but as the number of such scops may be arbitrarily large we do
1395 // not generate code for them here, but only at the point of code generation
1396 // where these values are needed.
1397 Loop *L = LI.getLoopFor(S.getEntry());
1398
1399 while (L != nullptr && S.contains(L))
1400 L = L->getParentLoop();
1401
1402 while (L != nullptr) {
1404 L = L->getParentLoop();
1405 }
1406
1407 isl_set_free(Context);
1408}
1409
1411 /// We pass the insert location of our Builder, as Polly ensures during IR
1412 /// generation that there is always a valid CFG into which instructions are
1413 /// inserted. As a result, the insertpoint is known to be always followed by a
1414 /// terminator instruction. This means the insert point may be specified by a
1415 /// terminator instruction, but it can never point to an ->end() iterator
1416 /// which does not have a corresponding instruction. Hence, dereferencing
1417 /// the insertpoint to obtain an instruction is known to be save.
1418 ///
1419 /// We also do not need to update the Builder here, as new instructions are
1420 /// always inserted _before_ the given InsertLocation. As a result, the
1421 /// insert location remains valid.
1422 assert(Builder.GetInsertBlock()->end() != Builder.GetInsertPoint() &&
1423 "Insert location points after last valid instruction");
1424 BasicBlock::iterator InsertLocation = Builder.GetInsertPoint();
1425
1426 return expandCodeFor(S, SE, Builder.GetInsertBlock()->getParent(), *GenSE, DL,
1427 "polly", Expr, Expr->getType(), InsertLocation,
1428 &ValueMap, /*LoopToScevMap*/ nullptr,
1429 StartBlock->getSinglePredecessor());
1430}
1431
1432/// The AST expression we generate to perform the run-time check assumes
1433/// computations on integer types of infinite size. As we only use 64-bit
1434/// arithmetic we check for overflows, in case of which we set the result
1435/// of this run-time check to false to be conservatively correct,
1437 auto ExprBuilder = getExprBuilder();
1438
1439 // In case the AST expression has integers larger than 64 bit, bail out. The
1440 // resulting LLVM-IR will contain operations on types that use more than 64
1441 // bits. These are -- in case wrapping intrinsics are used -- translated to
1442 // runtime library calls that are not available on all systems (e.g., Android)
1443 // and consequently will result in linker errors.
1444 if (ExprBuilder.hasLargeInts(isl::manage_copy(Condition))) {
1445 isl_ast_expr_free(Condition);
1446 return Builder.getFalse();
1447 }
1448
1449 ExprBuilder.setTrackOverflow(true);
1450 Value *RTC = ExprBuilder.create(Condition);
1451 if (!RTC->getType()->isIntegerTy(1))
1452 RTC = Builder.CreateIsNotNull(RTC);
1453 Value *OverflowHappened =
1454 Builder.CreateNot(ExprBuilder.getOverflowState(), "polly.rtc.overflown");
1455
1457 auto *F = Builder.GetInsertBlock()->getParent();
1459 Builder,
1460 "F: " + F->getName().str() + " R: " + S.getRegion().getNameStr() +
1461 "RTC: ",
1462 RTC, " Overflow: ", OverflowHappened,
1463 "\n"
1464 " (0 failed, -1 succeeded)\n"
1465 " (if one or both are 0 falling back to original code, if both are -1 "
1466 "executing Polly code)\n");
1467 }
1468
1469 RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result");
1470 ExprBuilder.setTrackOverflow(false);
1471
1472 if (!isa<ConstantInt>(RTC))
1473 VersionedScops++;
1474
1475 return RTC;
1476}
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_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_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_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
static isl::ast_build from_context(isl::set set)
isl::checked::ast_expr access_from(isl::checked::multi_pw_aff mpa) const
isl::checked::union_map get_schedule() const
isl::checked::ast_expr expr_from(isl::checked::pw_aff pa) 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::checked::set range() const
isl::checked::pw_multi_aff gist_params(isl::checked::set set) const
isl::checked::set domain() const
isl::checked::set intersect(isl::checked::set set2) const
boolean is_empty() const
__isl_give isl_set * release()
__isl_keep isl_set * get() const
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)
static isl::pw_multi_aff from_set(isl::set set)
static isl::set universe(isl::space space)
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.
void addParameters(__isl_take isl_set *Context)
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.
Value * preloadUnconditionally(isl::set AccessRange, isl::ast_build Build, Instruction *AccInst)
Preload the memory access at AccessRange with Build.
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.
Value * preloadInvariantLoad(const MemoryAccess &MA, isl::set Domain)
Preload the memory load access MA.
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:427
Instruction * getAccessInstruction() const
Return the access instruction of this memory access.
Definition ScopInfo.h:881
bool isRead() const
Is this a read memory access?
Definition ScopInfo.h:756
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:849
Value * getOriginalBaseAddr() const
Get the original base address of this access (e.g.
Definition ScopInfo.h:829
bool isArrayKind() const
Old name of isOriginalArrayKind.
Definition ScopInfo.h:951
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:1136
Scop * getParent()
Definition ScopInfo.h:1524
const std::vector< Instruction * > & getInstructions() const
Definition ScopInfo.h:1527
bool isBlockStmt() const
Return true if this statement represents a single basic block.
Definition ScopInfo.h:1317
size_t size() const
Definition ScopInfo.h:1520
Region * getRegion() const
Get the region represented by this ScopStmt (if any).
Definition ScopInfo.h:1326
BasicBlock * getBasicBlock() const
Get the BasicBlock represented by this ScopStmt (if any).
Definition ScopInfo.h:1314
bool isCopyStmt() const
Return true if this is a copy statement.
Definition ScopInfo.h:1320
bool isRegionStmt() const
Return true if this statement represents a whole region.
Definition ScopInfo.h:1329
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:1558
iterator begin()
Definition ScopInfo.h:1516
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:2012
bool contains(const Loop *L) const
Check if L is contained in the SCoP.
Definition ScopInfo.h:2094
const Region & getRegion() const
Get the maximum region of this static control part.
Definition ScopInfo.h:2087
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
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:1087
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:150
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_intersect_params(__isl_take isl_set *set, __isl_take isl_set *params)
Definition isl_map.c:4538
__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:1102
MemoryAccessList InvariantAccesses
Memory accesses now treated invariant.
Definition ScopInfo.h:1111
Type * AccessType
The type of the invariant access.
Definition ScopInfo.h:1123
isl::set ExecutionContext
The execution context under which the memory location is accessed.
Definition ScopInfo.h:1117
const SCEV * IdentifyingPointer
The pointer that identifies this equivalence class.
Definition ScopInfo.h:1104
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)