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