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
467/// Sign-extend or truncate V to Ty.
468///
469/// Returns V unchanged if it already has type Ty, sign-extends it if
470/// Ty is wider, or truncates it if Ty is narrower.
471static Value *castToType(IRBuilderBase &Builder, Value *V, Type *Ty) {
472 if (V->getType() == Ty)
473 return V;
474 return Builder.CreateSExtOrTrunc(V, Ty);
475}
476
477/// Returns true when V is known to fit in IntPtrTy without data loss.
478/// Accepts i64 constants such as 0 and 1 that ISL materialises as i64 even on
479/// 32-bit targets.
480static bool fitsInTy(Value *V, IntegerType *IntTy) {
481 if (V->getType()->getIntegerBitWidth() <= IntTy->getBitWidth())
482 return true;
483 if (auto *CI = dyn_cast<ConstantInt>(V))
484 return CI->getValue().isSignedIntN(IntTy->getBitWidth());
485 return false;
486}
487
489 bool MarkParallel) {
490 Value *ValueLB, *ValueUB, *ValueInc;
491 Type *MaxType;
492 BasicBlock *ExitBlock;
493 Value *IV;
494 CmpInst::Predicate Predicate;
495
496 bool LoopVectorizerDisabled = IsLoopVectorizerDisabled(For);
497
498 isl::ast_node Body = For.body();
499
500 // isl_ast_node_for_is_degenerate(For)
501 //
502 // TODO: For degenerated loops we could generate a plain assignment.
503 // However, for now we just reuse the logic for normal loops, which will
504 // create a loop with a single iteration.
505
506 isl::ast_expr Init = For.init();
507 isl::ast_expr Inc = For.inc();
508 isl::ast_expr Iterator = For.iterator();
509 isl::id IteratorID = Iterator.get_id();
510 isl::ast_expr UB = getUpperBound(For, Predicate);
511
512 ValueLB = ExprBuilder.create(Init.release());
513 ValueUB = ExprBuilder.create(UB.release());
514 ValueInc = ExprBuilder.create(Inc.release());
515
516 MaxType = ExprBuilder.getType(Iterator.get());
517 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
518 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
519 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
520
521 // Narrow the IV type to pointer size when all three bounds are known to fit.
522 // On 32-bit targets (e.g. Hexagon) this avoids i64 IVs and the truncations
523 // they cause in loop bodies. This also allows Hexagon to represent loops as
524 // Hardware loops. ISL materializes constants (e.g. LB=0, Inc=1)
525 // as i64 even when they fit in i32, so we accept those via isSignedIntN.
526 // Non-constant variables with a type wider than PtrBits are left unchanged
527 // to avoid an unsafe truncation.
528 IntegerType *IntPtrTy = Builder.getIntPtrTy(DL);
529 if (MaxType->getIntegerBitWidth() > IntPtrTy->getBitWidth() &&
530 fitsInTy(ValueLB, IntPtrTy) && fitsInTy(ValueUB, IntPtrTy) &&
531 fitsInTy(ValueInc, IntPtrTy))
532 MaxType = IntPtrTy;
533
534 // Coerce each bound to MaxType, using trunc when MaxType was narrowed.
535 ValueLB = castToType(Builder, ValueLB, MaxType);
536 ValueUB = castToType(Builder, ValueUB, MaxType);
537 ValueInc = castToType(Builder, ValueInc, MaxType);
538
539 // If we can show that LB <Predicate> UB holds at least once, we can
540 // omit the GuardBB in front of the loop.
541 bool UseGuardBB = !GenSE->isKnownPredicate(Predicate, GenSE->getSCEV(ValueLB),
542 GenSE->getSCEV(ValueUB));
543
544 // FIXME: This is a workaround for
545 // https://github.com/llvm/llvm-project/issues/198726.
546 // llvm.loop.vectorize.enable=true has an additional property beyond
547 // requesting vectorization — it implicitly allows FP operation reordering.
548 // This is a limitation of the metadata format: there is no way to separate
549 // the request for vectorization from the request for reassociating FP ops.
550 // Once LoopVectorize is fixed to not reorder FP ops without explicit
551 // permission, this workaround can be removed.
552 // For now, skip vectorize.enable for dist=1 FP loops to avoid correctness
553 // failures from FP reassociation.
554 bool SkipVectorizeEnableMetadata = hasLoopCarriedDependence(For, S);
555
556 IV = createLoop(ValueLB, ValueUB, ValueInc, Builder, *GenLI, *GenDT,
557 ExitBlock, Predicate, &Annotator, MarkParallel, UseGuardBB,
558 LoopVectorizerDisabled, SkipVectorizeEnableMetadata);
559 IDToValue[IteratorID.get()] = IV;
560
561 create(Body.release());
562
563 Annotator.popLoop(MarkParallel);
564
565 IDToValue.erase(IDToValue.find(IteratorID.get()));
566
567 Builder.SetInsertPoint(ExitBlock, ExitBlock->begin());
568
569 SequentialLoops++;
570}
571
573 isl_ast_node *Body;
574 isl_ast_expr *Init, *Inc, *Iterator, *UB;
575 isl_id *IteratorID;
576 Value *ValueLB, *ValueUB, *ValueInc;
577 Type *MaxType;
578 Value *IV;
579 CmpInst::Predicate Predicate;
580
581 // The preamble of parallel code interacts different than normal code with
582 // e.g., scalar initialization. Therefore, we ensure the parallel code is
583 // separated from the last basic block.
584 BasicBlock *ParBB =
585 SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), &DT, &LI);
586 ParBB->setName("polly.parallel.for");
587 Builder.SetInsertPoint(ParBB, ParBB->begin());
588
589 Body = isl_ast_node_for_get_body(For);
590 Init = isl_ast_node_for_get_init(For);
591 Inc = isl_ast_node_for_get_inc(For);
592 Iterator = isl_ast_node_for_get_iterator(For);
593 IteratorID = isl_ast_expr_get_id(Iterator);
594 UB = getUpperBound(isl::manage_copy(For).as<isl::ast_node_for>(), Predicate)
595 .release();
596
597 ValueLB = ExprBuilder.create(Init);
598 ValueUB = ExprBuilder.create(UB);
599 ValueInc = ExprBuilder.create(Inc);
600
601 // OpenMP always uses SLE. In case the isl generated AST uses a SLT
602 // expression, we need to adjust the loop bound by one.
603 if (Predicate == CmpInst::ICMP_SLT)
604 ValueUB = Builder.CreateAdd(
605 ValueUB, Builder.CreateSExt(Builder.getTrue(), ValueUB->getType()));
606
607 MaxType = ExprBuilder.getType(Iterator);
608 MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
609 MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
610 MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
611
612 // Narrow the IV type to pointer size when all three bounds are known to fit.
613 // On 32-bit targets (e.g. Hexagon) this avoids i64 IVs and the truncations
614 // they cause in loop bodies. ISL materializes constants (e.g. LB=0, Inc=1)
615 // as i64 even when they fit in i32, so we accept those via isSignedIntN.
616 // Non-constant variables with a type wider than PtrBits are left unchanged
617 // to avoid an unsafe truncation.
618 IntegerType *IntPtrTy = Builder.getIntPtrTy(DL);
619 if (MaxType->getIntegerBitWidth() > IntPtrTy->getBitWidth() &&
620 fitsInTy(ValueLB, IntPtrTy) && fitsInTy(ValueUB, IntPtrTy) &&
621 fitsInTy(ValueInc, IntPtrTy))
622 MaxType = IntPtrTy;
623
624 // Coerce each bound to MaxType, using trunc when MaxType was narrowed.
625 ValueLB = castToType(Builder, ValueLB, MaxType);
626 ValueUB = castToType(Builder, ValueUB, MaxType);
627 ValueInc = castToType(Builder, ValueInc, MaxType);
628
629 BasicBlock::iterator LoopBody;
630
631 SetVector<Value *> SubtreeValues;
632 SetVector<const Loop *> Loops;
633
634 getReferencesInSubtree(isl::manage_copy(For), SubtreeValues, Loops);
635
636 // Create for all loops we depend on values that contain the current loop
637 // iteration. These values are necessary to generate code for SCEVs that
638 // depend on such loops. As a result we need to pass them to the subfunction.
639 // See [Code generation of induction variables of loops outside Scops]
640 for (const Loop *L : Loops) {
641 Value *LoopInductionVar = materializeNonScopLoopInductionVariable(L);
642 SubtreeValues.insert(LoopInductionVar);
643 }
644
645 ValueMapT NewValues;
646
647 std::unique_ptr<ParallelLoopGenerator> ParallelLoopGenPtr;
648
649 switch (PollyOmpBackend) {
651 ParallelLoopGenPtr.reset(new ParallelLoopGeneratorGOMP(Builder, DL));
652 break;
654 ParallelLoopGenPtr.reset(new ParallelLoopGeneratorKMP(Builder, DL));
655 break;
656 }
657
658 IV = ParallelLoopGenPtr->createParallelLoop(
659 ValueLB, ValueUB, ValueInc, SubtreeValues, NewValues, &LoopBody);
660 BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
661
662 // Remember the parallel subfunction
663 Function *SubFn = LoopBody->getFunction();
664 ParallelSubfunctions.push_back(SubFn);
665
666 // We start working on the outlined function. Since DominatorTree/LoopInfo are
667 // not an inter-procedural passes, we temporarily switch them out. Save the
668 // old ones first.
669 Function *CallerFn = Builder.GetInsertBlock()->getParent();
670 DominatorTree *CallerDT = GenDT;
671 LoopInfo *CallerLI = GenLI;
672 ScalarEvolution *CallerSE = GenSE;
673 ValueMapT CallerGlobals = ValueMap;
675 MapVector<const Loop *, const SCEV *> OutsideLoopIterationsCopy =
677
678 // Get the analyses for the subfunction. ParallelLoopGenerator already create
679 // DominatorTree and LoopInfo for us.
680 DominatorTree *SubDT = ParallelLoopGenPtr->getCalleeDominatorTree();
681 LoopInfo *SubLI = ParallelLoopGenPtr->getCalleeLoopInfo();
682
683 // Create TargetLibraryInfo, AssumptionCachem and ScalarEvolution ourselves.
684 // TODO: Ideally, we would use the pass manager's TargetLibraryInfoPass and
685 // AssumptionAnalysis instead of our own. They contain more target-specific
686 // information than we have available here: TargetLibraryInfoImpl can be a
687 // derived class determined by TargetMachine, AssumptionCache can be
688 // configured using a TargetTransformInfo object also derived from
689 // TargetMachine.
690 TargetLibraryInfoImpl BaselineInfoImpl(SubFn->getParent()->getTargetTriple());
691 TargetLibraryInfo CalleeTLI(BaselineInfoImpl, SubFn);
692 AssumptionCache CalleeAC(*SubFn);
693 std::unique_ptr<ScalarEvolution> SubSE = std::make_unique<ScalarEvolution>(
694 *SubFn, CalleeTLI, CalleeAC, *SubDT, *SubLI);
695
696 // Switch to the subfunction
697 GenDT = SubDT;
698 GenLI = SubLI;
699 GenSE = SubSE.get();
700 BlockGen.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
701 RegionGen.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
702 ExprBuilder.switchGeneratedFunc(SubFn, GenDT, GenLI, GenSE);
703 Builder.SetInsertPoint(LoopBody);
704
705 // Update the ValueMap to use instructions in the subfunction. Note that
706 // "GlobalMap" used in BlockGenerator/IslExprBuilder is a reference to this
707 // ValueMap.
708 ValueMap.remove_if([&](auto &P) {
709 P.second = NewValues.lookup(P.second);
710 // Clean up any value that getReferencesInSubtree thinks we do not need.
711 return !P.second;
712 });
713
714 // This is for NewVals that do not appear in ValueMap (such as SCoP-invariant
715 // values whose original value can be reused as long as we are in the same
716 // function). No need to map the others.
717 for (auto &[NewVal, NewNewVal] : NewValues) {
718 if (Instruction *NewValInst = dyn_cast<Instruction>((Value *)NewVal)) {
719 if (S.contains(NewValInst))
720 continue;
721 assert(NewValInst->getFunction() == &S.getFunction());
722 }
723 assert(!ValueMap.contains(NewVal));
724 ValueMap[NewVal] = NewNewVal;
725 }
726
727 // Also update the IDToValue map to use instructions from the subfunction.
728 for (auto &[OldVal, NewVal] : IDToValue) {
729 NewVal = NewValues.lookup(NewVal);
730 assert(NewVal);
731 }
732 IDToValue[IteratorID] = IV;
733
734 // Also update OutsideLoopIterations to use values from the subfunction.
735 // SCEVExpander may fold identity operations (e.g. x+0 -> x), returning the
736 // original loop PHI instead of a new instruction. We need to remap these
737 // values through NewValues so GenSE (now SubSE) doesn't operate on values
738 // from the caller function.
739 for (auto &[L, S] : OutsideLoopIterations) {
740 if (auto *U = dyn_cast<SCEVUnknown>(S)) {
741 Value *NewVal = NewValues.lookup(U->getValue());
742 assert(NewVal && "must have a new value");
743 OutsideLoopIterations[L] = GenSE->getUnknown(NewVal);
744 }
745 }
746
747#ifndef NDEBUG
748 // Check whether the maps now exclusively refer to SubFn values.
749 for (auto &[OldVal, SubVal] : ValueMap) {
750 Instruction *SubInst = dyn_cast<Instruction>((Value *)SubVal);
751 assert(SubInst->getFunction() == SubFn &&
752 "Instructions from outside the subfn cannot be accessed within the "
753 "subfn");
754 }
755 for (auto &[Id, SubVal] : IDToValue) {
756 Instruction *SubInst = dyn_cast<Instruction>((Value *)SubVal);
757 assert(SubInst->getFunction() == SubFn &&
758 "Instructions from outside the subfn cannot be accessed within the "
759 "subfn");
760 }
761#endif
762
763 ValueMapT NewValuesReverse;
764 for (auto P : NewValues)
765 NewValuesReverse[P.second] = P.first;
766
767 Annotator.addAlternativeAliasBases(NewValuesReverse);
768
769 create(Body);
770
771 Annotator.resetAlternativeAliasBases();
772
773 // Resume working on the caller function.
774 GenDT = CallerDT;
775 GenLI = CallerLI;
776 GenSE = CallerSE;
777 IDToValue = std::move(IDToValueCopy);
778 ValueMap = std::move(CallerGlobals);
779 OutsideLoopIterations = std::move(OutsideLoopIterationsCopy);
780 ExprBuilder.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
781 RegionGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
782 BlockGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
783 Builder.SetInsertPoint(AfterLoop);
784
786 isl_ast_expr_free(Iterator);
787 isl_id_free(IteratorID);
788
789 ParallelLoops++;
790}
791
795 return;
796 }
797 bool Parallel = (IslAstInfo::isParallel(isl::manage_copy(For)) &&
799 createForSequential(isl::manage(For).as<isl::ast_node_for>(), Parallel);
800}
801
804
805 Function *F = Builder.GetInsertBlock()->getParent();
806 LLVMContext &Context = F->getContext();
807
808 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
809 Builder.GetInsertPoint(), GenDT, GenLI);
810 CondBB->setName("polly.cond");
811 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), GenDT, GenLI);
812 MergeBB->setName("polly.merge");
813 BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
814 BasicBlock *ElseBB = BasicBlock::Create(Context, "polly.else", F);
815
816 GenDT->addNewBlock(ThenBB, CondBB);
817 GenDT->addNewBlock(ElseBB, CondBB);
818 GenDT->changeImmediateDominator(MergeBB, CondBB);
819
820 Loop *L = GenLI->getLoopFor(CondBB);
821 if (L) {
822 L->addBasicBlockToLoop(ThenBB, *GenLI);
823 L->addBasicBlockToLoop(ElseBB, *GenLI);
824 }
825
826 CondBB->getTerminator()->eraseFromParent();
827
828 Builder.SetInsertPoint(CondBB);
829 Value *Predicate = ExprBuilder.create(Cond);
830 Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
831 Builder.SetInsertPoint(ThenBB);
832 Builder.CreateBr(MergeBB);
833 Builder.SetInsertPoint(ElseBB);
834 Builder.CreateBr(MergeBB);
835 Builder.SetInsertPoint(ThenBB, ThenBB->begin());
836
838
839 Builder.SetInsertPoint(ElseBB, ElseBB->begin());
840
843
844 Builder.SetInsertPoint(MergeBB, MergeBB->begin());
845
847
848 IfConditions++;
849}
850
851__isl_give isl_id_to_ast_expr *
853 __isl_keep isl_ast_node *Node) {
854 isl::id_to_ast_expr NewAccesses =
856
858 assert(!Build.is_null() && "Could not obtain isl_ast_build from user node");
859 Stmt->setAstBuild(Build);
860
861 for (auto *MA : *Stmt) {
862 if (!MA->hasNewAccessRelation()) {
864 if (!MA->isAffine())
865 continue;
866 if (MA->getLatestScopArrayInfo()->getBasePtrOriginSAI())
867 continue;
868
869 auto *BasePtr =
870 dyn_cast<Instruction>(MA->getLatestScopArrayInfo()->getBasePtr());
871 if (BasePtr && Stmt->getParent()->getRegion().contains(BasePtr))
872 continue;
873 } else {
874 continue;
875 }
876 }
877 assert(MA->isAffine() &&
878 "Only affine memory accesses can be code generated");
879
880 isl::union_map Schedule = Build.get_schedule();
881
882#ifndef NDEBUG
883 if (MA->isRead()) {
884 auto Dom = Stmt->getDomain().release();
885 auto SchedDom = isl_set_from_union_set(Schedule.domain().release());
886 auto AccDom = isl_map_domain(MA->getAccessRelation().release());
887 Dom = isl_set_intersect_params(Dom,
888 Stmt->getParent()->getContext().release());
889 SchedDom = isl_set_intersect_params(
890 SchedDom, Stmt->getParent()->getContext().release());
891 // Restrict to defined behavior context to match DeLICM's contract:
892 // new read accesses are only required to cover the defined-behavior
893 // subset of the domain.
894 auto *DefinedBehavior =
896 SchedDom =
897 isl_set_intersect_params(SchedDom, isl_set_copy(DefinedBehavior));
898 Dom = isl_set_intersect_params(Dom, DefinedBehavior);
899 assert(isl_set_is_subset(SchedDom, AccDom) != isl_bool_false &&
900 "Access relation not defined on full schedule domain");
901 assert(isl_set_is_subset(Dom, AccDom) != isl_bool_false &&
902 "Access relation not defined on full domain");
903 isl_set_free(AccDom);
904 isl_set_free(SchedDom);
905 isl_set_free(Dom);
906 }
907#endif
908
909 isl::pw_multi_aff PWAccRel = MA->applyScheduleToAccessRelation(Schedule);
910
911 // isl cannot generate an index expression for access-nothing accesses.
912 isl::set AccDomain = PWAccRel.domain();
913 if (AccDomain.is_empty())
914 continue;
915
916 isl::ast_expr AccessExpr = Build.access_from(PWAccRel);
917 NewAccesses = NewAccesses.set(MA->getId(), AccessExpr);
918 }
919
920 return NewAccesses.release();
921}
922
924 ScopStmt *Stmt, LoopToScevMapT &LTS) {
926 "Expression of type 'op' expected");
928 "Operation of type 'call' expected");
929 for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr) - 1; ++i) {
930 isl_ast_expr *SubExpr;
931 Value *V;
932
933 SubExpr = isl_ast_expr_get_op_arg(Expr, i + 1);
934 V = ExprBuilder.create(SubExpr);
935 ScalarEvolution *SE = Stmt->getParent()->getSE();
936 LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V);
937 }
938
939 isl_ast_expr_free(Expr);
940}
941
943 __isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
944 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
945 __isl_take isl_id *IteratorID) {
946 int i = 0;
947
948 Value *OldValue = IDToValue[IteratorID];
949 for (Value *IV : IVS) {
950 IDToValue[IteratorID] = IV;
951 createSubstitutions(isl_ast_expr_copy(Expr), Stmt, VLTS[i]);
952 i++;
953 }
954
955 IDToValue[IteratorID] = OldValue;
956 isl_id_free(IteratorID);
957 isl_ast_expr_free(Expr);
958}
959
961 ScopStmt *Stmt, __isl_keep isl_id_to_ast_expr *NewAccesses) {
962 assert(Stmt->size() == 2);
963 auto ReadAccess = Stmt->begin();
964 auto WriteAccess = ReadAccess++;
965 assert((*ReadAccess)->isRead() && (*WriteAccess)->isMustWrite());
966 assert((*ReadAccess)->getElementType() == (*WriteAccess)->getElementType() &&
967 "Accesses use the same data type");
968 assert((*ReadAccess)->isArrayKind() && (*WriteAccess)->isArrayKind());
969 auto *AccessExpr =
970 isl_id_to_ast_expr_get(NewAccesses, (*ReadAccess)->getId().release());
971 auto *LoadValue = ExprBuilder.create(AccessExpr);
972 AccessExpr =
973 isl_id_to_ast_expr_get(NewAccesses, (*WriteAccess)->getId().release());
974 auto *StoreAddr = ExprBuilder.createAccessAddress(AccessExpr).first;
975 Builder.CreateStore(LoadValue, StoreAddr);
976}
977
979 assert(!OutsideLoopIterations.contains(L) &&
980 "trying to materialize loop induction variable twice");
981 const SCEV *OuterLIV = SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)),
982 SE.getUnknown(Builder.getInt64(1)), L,
983 SCEV::FlagAnyWrap);
984 Value *V = generateSCEV(OuterLIV);
985 OutsideLoopIterations[L] = SE.getUnknown(V);
986 return V;
987}
988
990 LoopToScevMapT LTS;
991 isl_id *Id;
992 ScopStmt *Stmt;
993
995 isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
996 Id = isl_ast_expr_get_id(StmtExpr);
997 isl_ast_expr_free(StmtExpr);
998
999 LTS.insert_range(OutsideLoopIterations);
1000
1001 Stmt = (ScopStmt *)isl_id_get_user(Id);
1002 auto *NewAccesses = createNewAccesses(Stmt, User);
1003 if (Stmt->isCopyStmt()) {
1004 generateCopyStmt(Stmt, NewAccesses);
1005 isl_ast_expr_free(Expr);
1006 } else {
1007 createSubstitutions(Expr, Stmt, LTS);
1008
1009 if (Stmt->isBlockStmt())
1010 BlockGen.copyStmt(*Stmt, LTS, NewAccesses);
1011 else
1012 RegionGen.copyStmt(*Stmt, LTS, NewAccesses);
1013 }
1014
1015 isl_id_to_ast_expr_free(NewAccesses);
1016 isl_ast_node_free(User);
1017 isl_id_free(Id);
1018}
1019
1021 isl_ast_node_list *List = isl_ast_node_block_get_children(Block);
1022
1023 for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
1024 create(isl_ast_node_list_get_ast_node(List, i));
1025
1026 isl_ast_node_free(Block);
1027 isl_ast_node_list_free(List);
1028}
1029
1031 if (!TraceStmts)
1032 return;
1033
1034 // Sequence of strings to print.
1035 SmallVector<llvm::Value *, 8> Values;
1036 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "Scop: "));
1037
1038 auto Params = S.getParamSpace();
1039 for (int i : rangeIslSize(0, Params.dim(isl::dim::param))) {
1040 if (i != 0)
1041 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, " "));
1042
1043 isl::id PId = Params.get_dim_id(isl::dim::param, i);
1044 Values.push_back(
1046 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "="));
1047 Values.push_back(IDToValue.lookup(PId.get()));
1048 }
1049
1050 Values.push_back(RuntimeDebugBuilder::getPrintableString(Builder, "\n"));
1051 RuntimeDebugBuilder::createCPUPrinter(Builder, ArrayRef<Value *>(Values));
1052}
1053
1055 switch (isl_ast_node_get_type(Node)) {
1056 case isl_ast_node_error:
1057 llvm_unreachable("code generation error");
1058 case isl_ast_node_mark:
1059 createMark(Node);
1060 return;
1061 case isl_ast_node_for:
1062 createFor(Node);
1063 return;
1064 case isl_ast_node_if:
1065 createIf(Node);
1066 return;
1067 case isl_ast_node_user:
1068 createUser(Node);
1069 return;
1070 case isl_ast_node_block:
1071 createBlock(Node);
1072 return;
1073 }
1074
1075 llvm_unreachable("Unknown isl_ast_node type");
1076}
1077
1079 // If the Id is already mapped, skip it.
1080 if (!IDToValue.count(Id)) {
1081 auto *ParamSCEV = (const SCEV *)isl_id_get_user(Id);
1082 Value *V = nullptr;
1083
1084 // Parameters could refer to invariant loads that need to be
1085 // preloaded before we can generate code for the parameter. Thus,
1086 // check if any value referred to in ParamSCEV is an invariant load
1087 // and if so make sure its equivalence class is preloaded.
1088 SetVector<Value *> Values;
1089 findValues(ParamSCEV, SE, Values);
1090 for (auto *Val : Values) {
1091 // Check if the value is an instruction in a dead block within the SCoP
1092 // and if so do not code generate it.
1093 if (auto *Inst = dyn_cast<Instruction>(Val)) {
1094 if (S.contains(Inst)) {
1095 bool IsDead = true;
1096
1097 // Check for "undef" loads first, then if there is a statement for
1098 // the parent of Inst and lastly if the parent of Inst has an empty
1099 // domain. In the first and last case the instruction is dead but if
1100 // there is a statement or the domain is not empty Inst is not dead.
1101 auto MemInst = MemAccInst::dyn_cast(Inst);
1102 auto Address = MemInst ? MemInst.getPointerOperand() : nullptr;
1103 if (Address && SE.getUnknown(UndefValue::get(Address->getType())) ==
1104 SE.getPointerBase(SE.getSCEV(Address))) {
1105 } else if (S.getStmtFor(Inst)) {
1106 IsDead = false;
1107 } else {
1108 auto *Domain = S.getDomainConditions(Inst->getParent()).release();
1109 IsDead = isl_set_is_empty(Domain);
1111 }
1112
1113 if (IsDead) {
1114 V = UndefValue::get(ParamSCEV->getType());
1115 break;
1116 }
1117 }
1118 }
1119
1120 if (auto *IAClass = S.lookupInvariantEquivClass(Val)) {
1121 // Check if this invariant access class is empty, hence if we never
1122 // actually added a loads instruction to it. In that case it has no
1123 // (meaningful) users and we should not try to code generate it.
1124 if (IAClass->InvariantAccesses.empty())
1125 V = UndefValue::get(ParamSCEV->getType());
1126
1127 if (!preloadInvariantEquivClass(*IAClass)) {
1128 isl_id_free(Id);
1129 return false;
1130 }
1131 }
1132 }
1133
1134 V = V ? V : generateSCEV(ParamSCEV);
1135 IDToValue[Id] = V;
1136 }
1137
1138 isl_id_free(Id);
1139 return true;
1140}
1141
1143 for (unsigned i = 0, e = isl_set_dim(Set, isl_dim_param); i < e; ++i) {
1144 if (!isl_set_involves_dims(Set, isl_dim_param, i, 1))
1145 continue;
1147 if (!materializeValue(Id))
1148 return false;
1149 }
1150 return true;
1151}
1152
1154 for (const SCEV *Param : S.parameters()) {
1155 isl_id *Id = S.getIdForParam(Param).release();
1156 if (!materializeValue(Id))
1157 return false;
1158 }
1159 return true;
1160}
1161
1163 isl::ast_build Build,
1164 Instruction *AccInst) {
1165 isl::pw_multi_aff PWAccRel = isl::pw_multi_aff::from_set(AccessRange);
1166 PWAccRel = PWAccRel.gist_params(S.getContext());
1167 isl::ast_expr Access = Build.access_from(PWAccRel);
1168 isl::ast_expr Address = Access.address_of();
1169 Value *AddressValue = ExprBuilder.create(Address.release());
1170 Value *PreloadVal;
1171
1172 // Correct the type as the SAI might have a different type than the user
1173 // expects, especially if the base pointer is a struct.
1174 Type *Ty = AccInst->getType();
1175
1176 auto *Ptr = AddressValue;
1177 auto Name = Ptr->getName();
1178 PreloadVal = Builder.CreateLoad(Ty, Ptr, Name + ".load");
1179 if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal))
1180 PreloadInst->setAlignment(cast<LoadInst>(AccInst)->getAlign());
1181
1182 return PreloadVal;
1183}
1184
1186 isl::set Domain) {
1187 isl::set AccessRange = MA.getAddressFunction().range();
1188
1189 if (!materializeParameters(AccessRange.get()))
1190 return nullptr;
1191
1192 isl::ast_build Build =
1194 isl::set Universe = isl::set::universe(Domain.get_space());
1195 bool AlwaysExecuted = Domain.is_equal(Universe);
1196
1197 Instruction *AccInst = MA.getAccessInstruction();
1198 Type *AccInstTy = AccInst->getType();
1199
1200 if (AlwaysExecuted)
1201 return preloadUnconditionally(AccessRange, Build, AccInst);
1202
1203 if (!materializeParameters(Domain.get()))
1204 return nullptr;
1205
1206 isl::ast_expr DomainCond = Build.expr_from(Domain);
1207
1208 ExprBuilder.setTrackOverflow(true);
1209 Value *Cond = ExprBuilder.createBool(DomainCond.release());
1210 Value *OverflowHappened = Builder.CreateNot(ExprBuilder.getOverflowState(),
1211 "polly.preload.cond.overflown");
1212 Cond = Builder.CreateAnd(Cond, OverflowHappened, "polly.preload.cond.result");
1213 ExprBuilder.setTrackOverflow(false);
1214
1215 if (!Cond->getType()->isIntegerTy(1))
1216 Cond = Builder.CreateIsNotNull(Cond);
1217
1218 BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
1219 Builder.GetInsertPoint(), GenDT, GenLI);
1220 CondBB->setName("polly.preload.cond");
1221
1222 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), GenDT, GenLI);
1223 MergeBB->setName("polly.preload.merge");
1224
1225 Function *F = Builder.GetInsertBlock()->getParent();
1226 LLVMContext &Context = F->getContext();
1227 BasicBlock *ExecBB = BasicBlock::Create(Context, "polly.preload.exec", F);
1228
1229 GenDT->addNewBlock(ExecBB, CondBB);
1230 if (Loop *L = GenLI->getLoopFor(CondBB))
1231 L->addBasicBlockToLoop(ExecBB, *GenLI);
1232
1233 auto *CondBBTerminator = CondBB->getTerminator();
1234 Builder.SetInsertPoint(CondBB, CondBBTerminator->getIterator());
1235 Builder.CreateCondBr(Cond, ExecBB, MergeBB);
1236 CondBBTerminator->eraseFromParent();
1237
1238 Builder.SetInsertPoint(ExecBB);
1239 Builder.CreateBr(MergeBB);
1240
1241 Builder.SetInsertPoint(ExecBB, ExecBB->getTerminator()->getIterator());
1242 Value *PreAccInst = preloadUnconditionally(AccessRange, Build, AccInst);
1243 Builder.SetInsertPoint(MergeBB, MergeBB->getTerminator()->getIterator());
1244 auto *MergePHI = Builder.CreatePHI(
1245 AccInstTy, 2, "polly.preload." + AccInst->getName() + ".merge");
1246 Value *PreloadVal = MergePHI;
1247
1248 if (!PreAccInst) {
1249 PreloadVal = nullptr;
1250 PreAccInst = UndefValue::get(AccInstTy);
1251 }
1252
1253 MergePHI->addIncoming(PreAccInst, ExecBB);
1254 MergePHI->addIncoming(Constant::getNullValue(AccInstTy), CondBB);
1255
1256 return PreloadVal;
1257}
1258
1260 InvariantEquivClassTy &IAClass) {
1261 // For an equivalence class of invariant loads we pre-load the representing
1262 // element with the unified execution context. However, we have to map all
1263 // elements of the class to the one preloaded load as they are referenced
1264 // during the code generation and therefore need to be mapped.
1265 const MemoryAccessList &MAs = IAClass.InvariantAccesses;
1266 if (MAs.empty())
1267 return true;
1268
1269 MemoryAccess *MA = MAs.front();
1270 assert(MA->isArrayKind() && MA->isRead());
1271
1272 // If the access function was already mapped, the preload of this equivalence
1273 // class was triggered earlier already and doesn't need to be done again.
1274 if (ValueMap.count(MA->getAccessInstruction()))
1275 return true;
1276
1277 // Check for recursion which can be caused by additional constraints, e.g.,
1278 // non-finite loop constraints. In such a case we have to bail out and insert
1279 // a "false" runtime check that will cause the original code to be executed.
1280 auto PtrId = std::make_pair(IAClass.IdentifyingPointer, IAClass.AccessType);
1281 if (!PreloadedPtrs.insert(PtrId).second)
1282 return false;
1283
1284 // The execution context of the IAClass.
1285 isl::set &ExecutionCtx = IAClass.ExecutionContext;
1286
1287 // If the base pointer of this class is dependent on another one we have to
1288 // make sure it was preloaded already.
1289 auto *SAI = MA->getScopArrayInfo();
1290 if (auto *BaseIAClass = S.lookupInvariantEquivClass(SAI->getBasePtr())) {
1291 if (!preloadInvariantEquivClass(*BaseIAClass))
1292 return false;
1293
1294 // After we preloaded the BaseIAClass we adjusted the BaseExecutionCtx and
1295 // we need to refine the ExecutionCtx.
1296 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1297 ExecutionCtx = ExecutionCtx.intersect(BaseExecutionCtx);
1298 }
1299
1300 // If the size of a dimension is dependent on another class, make sure it is
1301 // preloaded.
1302 for (unsigned i = 1, e = SAI->getNumberOfDimensions(); i < e; ++i) {
1303 const SCEV *Dim = SAI->getDimensionSize(i);
1304 SetVector<Value *> Values;
1305 findValues(Dim, SE, Values);
1306 for (auto *Val : Values) {
1307 if (auto *BaseIAClass = S.lookupInvariantEquivClass(Val)) {
1308 if (!preloadInvariantEquivClass(*BaseIAClass))
1309 return false;
1310
1311 // After we preloaded the BaseIAClass we adjusted the BaseExecutionCtx
1312 // and we need to refine the ExecutionCtx.
1313 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1314 ExecutionCtx = ExecutionCtx.intersect(BaseExecutionCtx);
1315 }
1316 }
1317 }
1318
1319 Instruction *AccInst = MA->getAccessInstruction();
1320 Type *AccInstTy = AccInst->getType();
1321
1322 Value *PreloadVal = preloadInvariantLoad(*MA, ExecutionCtx);
1323 if (!PreloadVal)
1324 return false;
1325
1326 for (const MemoryAccess *MA : MAs) {
1327 Instruction *MAAccInst = MA->getAccessInstruction();
1328 assert(PreloadVal->getType() == MAAccInst->getType());
1329 ValueMap[MAAccInst] = PreloadVal;
1330 }
1331
1332 if (SE.isSCEVable(AccInstTy)) {
1333 isl_id *ParamId = S.getIdForParam(SE.getSCEV(AccInst)).release();
1334 if (ParamId)
1335 IDToValue[ParamId] = PreloadVal;
1336 isl_id_free(ParamId);
1337 }
1338
1339 BasicBlock *EntryBB = &Builder.GetInsertBlock()->getParent()->getEntryBlock();
1340 auto *Alloca = new AllocaInst(AccInstTy, DL.getAllocaAddrSpace(),
1341 AccInst->getName() + ".preload.s2a",
1342 EntryBB->getFirstInsertionPt());
1343 Builder.CreateStore(PreloadVal, Alloca);
1344 ValueMapT PreloadedPointer;
1345 PreloadedPointer[PreloadVal] = AccInst;
1346 Annotator.addAlternativeAliasBases(PreloadedPointer);
1347
1348 for (auto *DerivedSAI : SAI->getDerivedSAIs()) {
1349 Value *BasePtr = DerivedSAI->getBasePtr();
1350
1351 for (const MemoryAccess *MA : MAs) {
1352 // As the derived SAI information is quite coarse, any load from the
1353 // current SAI could be the base pointer of the derived SAI, however we
1354 // should only change the base pointer of the derived SAI if we actually
1355 // preloaded it.
1356 if (BasePtr == MA->getOriginalBaseAddr()) {
1357 assert(BasePtr->getType() == PreloadVal->getType());
1358 DerivedSAI->setBasePtr(PreloadVal);
1359 }
1360
1361 // For scalar derived SAIs we remap the alloca used for the derived value.
1362 if (BasePtr == MA->getAccessInstruction())
1363 ScalarMap[DerivedSAI] = Alloca;
1364 }
1365 }
1366
1367 for (const MemoryAccess *MA : MAs) {
1368 Instruction *MAAccInst = MA->getAccessInstruction();
1369 // Use the escape system to get the correct value to users outside the SCoP.
1371 for (auto *U : MAAccInst->users())
1372 if (Instruction *UI = dyn_cast<Instruction>(U))
1373 if (!S.contains(UI))
1374 EscapeUsers.push_back(UI);
1375
1376 if (EscapeUsers.empty())
1377 continue;
1378
1380 std::make_pair(Alloca, std::move(EscapeUsers));
1381 }
1382
1383 return true;
1384}
1385
1387 for (auto &SAI : S.arrays()) {
1388 if (SAI->getBasePtr())
1389 continue;
1390
1391 assert(SAI->getNumberOfDimensions() > 0 && SAI->getDimensionSize(0) &&
1392 "The size of the outermost dimension is used to declare newly "
1393 "created arrays that require memory allocation.");
1394
1395 Type *NewArrayType = nullptr;
1396
1397 // Get the size of the array = size(dim_1)*...*size(dim_n)
1398 uint64_t ArraySizeInt = 1;
1399 for (int i = SAI->getNumberOfDimensions() - 1; i >= 0; i--) {
1400 auto *DimSize = SAI->getDimensionSize(i);
1401 unsigned UnsignedDimSize = static_cast<const SCEVConstant *>(DimSize)
1402 ->getAPInt()
1403 .getLimitedValue();
1404
1405 if (!NewArrayType)
1406 NewArrayType = SAI->getElementType();
1407
1408 NewArrayType = ArrayType::get(NewArrayType, UnsignedDimSize);
1409 ArraySizeInt *= UnsignedDimSize;
1410 }
1411
1412 if (SAI->isOnHeap()) {
1413 LLVMContext &Ctx = NewArrayType->getContext();
1414
1415 // Get the IntPtrTy from the Datalayout
1416 auto IntPtrTy = DL.getIntPtrType(Ctx);
1417
1418 // Get the size of the element type in bits
1419 unsigned Size = SAI->getElemSizeInBytes();
1420
1421 // Insert the malloc call at polly.start
1422 BasicBlock *StartBlock = std::get<0>(StartExitBlocks);
1423 Builder.SetInsertPoint(StartBlock,
1424 StartBlock->getTerminator()->getIterator());
1425 auto *CreatedArray = Builder.CreateMalloc(
1426 IntPtrTy, SAI->getElementType(),
1427 ConstantInt::get(Type::getInt64Ty(Ctx), Size),
1428 ConstantInt::get(Type::getInt64Ty(Ctx), ArraySizeInt), nullptr,
1429 SAI->getName());
1430
1431 SAI->setBasePtr(CreatedArray);
1432
1433 // Insert the free call at polly.exiting
1434 BasicBlock *ExitingBlock = std::get<1>(StartExitBlocks);
1435 Builder.SetInsertPoint(ExitingBlock,
1436 ExitingBlock->getTerminator()->getIterator());
1437 Builder.CreateFree(CreatedArray);
1438 } else {
1439 auto InstIt = Builder.GetInsertBlock()
1440 ->getParent()
1441 ->getEntryBlock()
1442 .getTerminator()
1443 ->getIterator();
1444
1445 auto *CreatedArray = new AllocaInst(NewArrayType, DL.getAllocaAddrSpace(),
1446 SAI->getName(), InstIt);
1448 CreatedArray->setAlignment(Align(PollyTargetFirstLevelCacheLineSize));
1449 SAI->setBasePtr(CreatedArray);
1450 }
1451 }
1452}
1453
1455 auto &InvariantEquivClasses = S.getInvariantAccesses();
1456 if (InvariantEquivClasses.empty())
1457 return true;
1458
1459 BasicBlock *PreLoadBB = SplitBlock(Builder.GetInsertBlock(),
1460 Builder.GetInsertPoint(), GenDT, GenLI);
1461 PreLoadBB->setName("polly.preload.begin");
1462 Builder.SetInsertPoint(PreLoadBB, PreLoadBB->begin());
1463
1464 for (auto &IAClass : InvariantEquivClasses)
1465 if (!preloadInvariantEquivClass(IAClass))
1466 return false;
1467
1468 return true;
1469}
1470
1472 // Materialize values for the parameters of the SCoP.
1474
1475 // Generate values for the current loop iteration for all surrounding loops.
1476 //
1477 // We may also reference loops outside of the scop which do not contain the
1478 // scop itself, but as the number of such scops may be arbitrarily large we do
1479 // not generate code for them here, but only at the point of code generation
1480 // where these values are needed.
1481 Loop *L = LI.getLoopFor(S.getEntry());
1482
1483 while (L != nullptr && S.contains(L))
1484 L = L->getParentLoop();
1485
1486 while (L != nullptr) {
1488 L = L->getParentLoop();
1489 }
1490
1491 isl_set_free(Context);
1492}
1493
1495 /// We pass the insert location of our Builder, as Polly ensures during IR
1496 /// generation that there is always a valid CFG into which instructions are
1497 /// inserted. As a result, the insertpoint is known to be always followed by a
1498 /// terminator instruction. This means the insert point may be specified by a
1499 /// terminator instruction, but it can never point to an ->end() iterator
1500 /// which does not have a corresponding instruction. Hence, dereferencing
1501 /// the insertpoint to obtain an instruction is known to be save.
1502 ///
1503 /// We also do not need to update the Builder here, as new instructions are
1504 /// always inserted _before_ the given InsertLocation. As a result, the
1505 /// insert location remains valid.
1506 assert(Builder.GetInsertBlock()->end() != Builder.GetInsertPoint() &&
1507 "Insert location points after last valid instruction");
1508 BasicBlock::iterator InsertLocation = Builder.GetInsertPoint();
1509
1510 return expandCodeFor(S, SE, Builder.GetInsertBlock()->getParent(), *GenSE, DL,
1511 "polly", Expr, Expr->getType(), InsertLocation,
1512 &ValueMap, /*LoopToScevMap*/ nullptr,
1513 StartBlock->getSinglePredecessor());
1514}
1515
1516/// The AST expression we generate to perform the run-time check assumes
1517/// computations on integer types of infinite size. As we only use 64-bit
1518/// arithmetic we check for overflows, in case of which we set the result
1519/// of this run-time check to false to be conservatively correct,
1521 auto ExprBuilder = getExprBuilder();
1522
1523 // In case the AST expression has integers larger than 64 bit, bail out. The
1524 // resulting LLVM-IR will contain operations on types that use more than 64
1525 // bits. These are -- in case wrapping intrinsics are used -- translated to
1526 // runtime library calls that are not available on all systems (e.g., Android)
1527 // and consequently will result in linker errors.
1528 if (ExprBuilder.hasLargeInts(isl::manage_copy(Condition))) {
1529 isl_ast_expr_free(Condition);
1530 return Builder.getFalse();
1531 }
1532
1533 ExprBuilder.setTrackOverflow(true);
1534 Value *RTC = ExprBuilder.create(Condition);
1535 if (!RTC->getType()->isIntegerTy(1))
1536 RTC = Builder.CreateIsNotNull(RTC);
1537 Value *OverflowHappened =
1538 Builder.CreateNot(ExprBuilder.getOverflowState(), "polly.rtc.overflown");
1539
1541 auto *F = Builder.GetInsertBlock()->getParent();
1543 Builder,
1544 "F: " + F->getName().str() + " R: " + S.getRegion().getNameStr() +
1545 "RTC: ",
1546 RTC, " Overflow: ", OverflowHappened,
1547 "\n"
1548 " (0 failed, -1 succeeded)\n"
1549 " (if one or both are 0 falling back to original code, if both are -1 "
1550 "executing Polly code)\n");
1551 }
1552
1553 RTC = Builder.CreateAnd(RTC, OverflowHappened, "polly.rtc.result");
1554 ExprBuilder.setTrackOverflow(false);
1555
1556 if (!isa<ConstantInt>(RTC))
1557 VersionedScops++;
1558
1559 return RTC;
1560}
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 Value * castToType(IRBuilderBase &Builder, Value *V, Type *Ty)
Sign-extend or truncate V to Ty.
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))
static bool fitsInTy(Value *V, IntegerType *IntTy)
Returns true when V is known to fit in IntPtrTy without data loss.
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)