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