28#include "llvm/ADT/APInt.h"
29#include "llvm/ADT/PostOrderIterator.h"
30#include "llvm/ADT/SetVector.h"
31#include "llvm/ADT/SmallPtrSet.h"
32#include "llvm/ADT/Statistic.h"
33#include "llvm/Analysis/AssumptionCache.h"
34#include "llvm/Analysis/LoopInfo.h"
35#include "llvm/Analysis/RegionInfo.h"
36#include "llvm/Analysis/ScalarEvolution.h"
37#include "llvm/Analysis/ScalarEvolutionExpressions.h"
38#include "llvm/Analysis/TargetLibraryInfo.h"
39#include "llvm/IR/BasicBlock.h"
40#include "llvm/IR/Constant.h"
41#include "llvm/IR/Constants.h"
42#include "llvm/IR/DataLayout.h"
43#include "llvm/IR/DerivedTypes.h"
44#include "llvm/IR/Dominators.h"
45#include "llvm/IR/Function.h"
46#include "llvm/IR/InstrTypes.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/Instructions.h"
49#include "llvm/IR/Module.h"
50#include "llvm/IR/Type.h"
51#include "llvm/IR/Value.h"
52#include "llvm/Support/Casting.h"
53#include "llvm/Support/CommandLine.h"
54#include "llvm/Support/ErrorHandling.h"
55#include "llvm/TargetParser/Triple.h"
56#include "llvm/Transforms/Utils/BasicBlockUtils.h"
78#define DEBUG_TYPE "polly-codegen"
80STATISTIC(VersionedScops,
"Number of SCoPs that required versioning.");
82STATISTIC(SequentialLoops,
"Number of generated sequential for-loops");
83STATISTIC(ParallelLoops,
"Number of generated parallel for-loops");
84STATISTIC(IfConditions,
"Number of generated if-conditions");
90 "polly-codegen-emit-rtc-print",
91 cl::desc(
"Emit code that prints the runtime check result dynamically."),
99 "polly-codegen-generate-expressions",
100 cl::desc(
"Generate AST expressions for unmodified and modified accesses"),
104 "polly-target-first-level-cache-line-size",
105 cl::desc(
"The size of the first level cache line size specified in bytes."),
109 "polly-omp-backend", cl::desc(
"Choose the OpenMP library to use:"),
115 ICmpInst::Predicate &Predicate) {
119 "conditional expression is not an atomic upper bound");
125 Predicate = ICmpInst::ICMP_SLE;
128 Predicate = ICmpInst::ICMP_SLT;
131 llvm_unreachable(
"Unexpected comparison type in loop condition");
137 "conditional expression is not an atomic upper bound");
142 "Could not get the iterator");
144 isl::id IteratorID = Iterator.get_id();
147 "conditional expression is not an atomic upper bound");
149 return Cond.get_op_arg(1);
180 CmpInst::Predicate Predicate;
186 if (NumberIterations < 0)
188 if (Predicate == CmpInst::ICMP_SLT)
189 return NumberIterations;
191 return NumberIterations + 1;
195 Loop *UserScope,
const ValueMapT &GlobalMap,
196 SetVector<Value *> &Values,
197 SetVector<const SCEV *> &SCEVs) {
203 if (isa<GlobalValue>(SrcVal))
204 Values.insert(SrcVal);
219 if (
Value *NewVal = GlobalMap.lookup(SrcVal))
220 Values.insert(NewVal);
224 Loop *UserScope,
const ValueMapT &GlobalMap,
225 SetVector<Value *> &Values,
226 SetVector<const SCEV *> &SCEVs) {
227 for (Use &U : Inst->operands())
233 SetVector<const SCEV *> &SCEVs) {
238 Loop *Scope = BB ? LI->getLoopFor(BB) :
nullptr;
243 for (BasicBlock *BB : Stmt->
getRegion()->blocks()) {
244 Loop *Scope = LI->getLoopFor(BB);
245 for (Instruction &Inst : *BB)
252 bool CreateScalarRefs) {
258 for (
auto &Access : *Stmt) {
259 if (References.ParamSpace) {
260 isl::space ParamSpace = Access->getLatestAccessRelation().get_space();
261 (*References.ParamSpace) =
262 References.ParamSpace->align_params(ParamSpace);
265 if (Access->isLatestArrayKind()) {
266 auto *BasePtr = Access->getLatestScopArrayInfo()->getBasePtr();
267 if (Instruction *OpInst = dyn_cast<Instruction>(BasePtr))
271 References.Values.insert(BasePtr);
275 if (CreateScalarRefs)
276 References.Values.insert(References.BlockGen.getOrCreateAlloca(*Access));
292 isl::id Id = Set.get_tuple_id();
293 auto *Stmt =
static_cast<ScopStmt *
>(Id.get_user());
323 SetVector<Value *> &Values,
324 SetVector<const Loop *> &Loops) {
325 SetVector<const SCEV *> SCEVs;
329 Values.insert_range(llvm::make_second_range(
IDToValue));
333 Values.insert(cast<SCEVUnknown>(I.second)->getValue());
338 for (
const SCEV *Expr : SCEVs) {
343 Values.remove_if([](
const Value *V) {
return isa<GlobalValue>(V); });
356 Loops.remove_if([
this](
const Loop *L) {
357 return S.contains(L) || L->contains(
S.getEntry());
366 SetVector<Value *> ReplacedValues;
367 for (
Value *V : Values) {
370 Values = ReplacedValues;
400 AncestorLoopAttr =
Annotator.getStagingAttrEnv();
402 Annotator.getStagingAttrEnv() = ChildLoopAttr;
409 "Nest must not overwrite loop attr environment");
410 Annotator.getStagingAttrEnv() = AncestorLoopAttr;
431 auto Id = BodyMark.
id();
432 if (strcmp(Id.get_name().c_str(),
"Loop Vectorizer Disabled") == 0)
439 Value *ValueLB, *ValueUB, *ValueInc;
441 BasicBlock *ExitBlock;
443 CmpInst::Predicate Predicate;
458 isl::id IteratorID = Iterator.get_id();
466 MaxType =
ExprBuilder.getWidestType(MaxType, ValueLB->getType());
467 MaxType =
ExprBuilder.getWidestType(MaxType, ValueUB->getType());
468 MaxType =
ExprBuilder.getWidestType(MaxType, ValueInc->getType());
470 if (MaxType != ValueLB->getType())
471 ValueLB =
Builder.CreateSExt(ValueLB, MaxType);
472 if (MaxType != ValueUB->getType())
473 ValueUB =
Builder.CreateSExt(ValueUB, MaxType);
474 if (MaxType != ValueInc->getType())
475 ValueInc =
Builder.CreateSExt(ValueInc, MaxType);
479 bool UseGuardBB = !
GenSE->isKnownPredicate(Predicate,
GenSE->getSCEV(ValueLB),
480 GenSE->getSCEV(ValueUB));
482 ExitBlock, Predicate, &
Annotator, MarkParallel, UseGuardBB,
483 LoopVectorizerDisabled);
492 Builder.SetInsertPoint(ExitBlock, ExitBlock->begin());
501 Value *ValueLB, *ValueUB, *ValueInc;
504 CmpInst::Predicate Predicate;
511 ParBB->setName(
"polly.parallel.for");
512 Builder.SetInsertPoint(ParBB, ParBB->begin());
528 if (Predicate == CmpInst::ICMP_SLT)
530 ValueUB,
Builder.CreateSExt(
Builder.getTrue(), ValueUB->getType()));
533 MaxType =
ExprBuilder.getWidestType(MaxType, ValueLB->getType());
534 MaxType =
ExprBuilder.getWidestType(MaxType, ValueUB->getType());
535 MaxType =
ExprBuilder.getWidestType(MaxType, ValueInc->getType());
537 if (MaxType != ValueLB->getType())
538 ValueLB =
Builder.CreateSExt(ValueLB, MaxType);
539 if (MaxType != ValueUB->getType())
540 ValueUB =
Builder.CreateSExt(ValueUB, MaxType);
541 if (MaxType != ValueInc->getType())
542 ValueInc =
Builder.CreateSExt(ValueInc, MaxType);
544 BasicBlock::iterator LoopBody;
546 SetVector<Value *> SubtreeValues;
547 SetVector<const Loop *> Loops;
555 for (
const Loop *L : Loops) {
557 SubtreeValues.insert(LoopInductionVar);
562 std::unique_ptr<ParallelLoopGenerator> ParallelLoopGenPtr;
573 IV = ParallelLoopGenPtr->createParallelLoop(
574 ValueLB, ValueUB, ValueInc, SubtreeValues, NewValues, &LoopBody);
575 BasicBlock::iterator AfterLoop =
Builder.GetInsertPoint();
578 Function *SubFn = LoopBody->getFunction();
584 Function *CallerFn =
Builder.GetInsertBlock()->getParent();
585 DominatorTree *CallerDT =
GenDT;
586 LoopInfo *CallerLI =
GenLI;
587 ScalarEvolution *CallerSE =
GenSE;
590 MapVector<const Loop *, const SCEV *> OutsideLoopIterationsCopy =
595 DominatorTree *SubDT = ParallelLoopGenPtr->getCalleeDominatorTree();
596 LoopInfo *SubLI = ParallelLoopGenPtr->getCalleeLoopInfo();
605 TargetLibraryInfoImpl BaselineInfoImpl(SubFn->getParent()->getTargetTriple());
606 TargetLibraryInfo CalleeTLI(BaselineInfoImpl, SubFn);
607 AssumptionCache CalleeAC(*SubFn);
608 std::unique_ptr<ScalarEvolution> SubSE = std::make_unique<ScalarEvolution>(
609 *SubFn, CalleeTLI, CalleeAC, *SubDT, *SubLI);
618 Builder.SetInsertPoint(LoopBody);
624 P.second = NewValues.lookup(P.second);
632 for (
auto &[NewVal, NewNewVal] : NewValues) {
633 if (Instruction *NewValInst = dyn_cast<Instruction>((
Value *)NewVal)) {
634 if (
S.contains(NewValInst))
636 assert(NewValInst->getFunction() == &
S.getFunction());
643 for (
auto &[OldVal, NewVal] :
IDToValue) {
644 NewVal = NewValues.lookup(NewVal);
655 if (
auto *U = dyn_cast<SCEVUnknown>(
S)) {
656 Value *NewVal = NewValues.lookup(U->getValue());
657 assert(NewVal &&
"must have a new value");
664 for (
auto &[OldVal, SubVal] :
ValueMap) {
665 Instruction *SubInst = dyn_cast<Instruction>((
Value *)SubVal);
666 assert(SubInst->getFunction() == SubFn &&
667 "Instructions from outside the subfn cannot be accessed within the "
671 Instruction *SubInst = dyn_cast<Instruction>((
Value *)SubVal);
672 assert(SubInst->getFunction() == SubFn &&
673 "Instructions from outside the subfn cannot be accessed within the "
679 for (
auto P : NewValues)
680 NewValuesReverse[P.second] = P.first;
682 Annotator.addAlternativeAliasBases(NewValuesReverse);
693 ValueMap = std::move(CallerGlobals);
695 ExprBuilder.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
696 RegionGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
697 BlockGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
698 Builder.SetInsertPoint(AfterLoop);
720 Function *F =
Builder.GetInsertBlock()->getParent();
721 LLVMContext &Context = F->getContext();
723 BasicBlock *CondBB = SplitBlock(
Builder.GetInsertBlock(),
725 CondBB->setName(
"polly.cond");
726 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(),
GenDT,
GenLI);
727 MergeBB->setName(
"polly.merge");
728 BasicBlock *ThenBB = BasicBlock::Create(Context,
"polly.then", F);
729 BasicBlock *ElseBB = BasicBlock::Create(Context,
"polly.else", F);
731 GenDT->addNewBlock(ThenBB, CondBB);
732 GenDT->addNewBlock(ElseBB, CondBB);
733 GenDT->changeImmediateDominator(MergeBB, CondBB);
735 Loop *L =
GenLI->getLoopFor(CondBB);
737 L->addBasicBlockToLoop(ThenBB, *
GenLI);
738 L->addBasicBlockToLoop(ElseBB, *
GenLI);
741 CondBB->getTerminator()->eraseFromParent();
743 Builder.SetInsertPoint(CondBB);
745 Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
746 Builder.SetInsertPoint(ThenBB);
748 Builder.SetInsertPoint(ElseBB);
750 Builder.SetInsertPoint(ThenBB, ThenBB->begin());
754 Builder.SetInsertPoint(ElseBB, ElseBB->begin());
759 Builder.SetInsertPoint(MergeBB, MergeBB->begin());
773 assert(!Build.
is_null() &&
"Could not obtain isl_ast_build from user node");
776 for (
auto *MA : *Stmt) {
777 if (!MA->hasNewAccessRelation()) {
781 if (MA->getLatestScopArrayInfo()->getBasePtrOriginSAI())
785 dyn_cast<Instruction>(MA->getLatestScopArrayInfo()->getBasePtr());
793 "Only affine memory accesses can be code generated");
807 "Access relation not defined on full schedule domain");
809 "Access relation not defined on full domain");
824 NewAccesses = NewAccesses.
set(MA->getId(), AccessExpr);
833 "Expression of type 'op' expected");
835 "Operation of type 'call' expected");
851 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
856 for (
Value *IV : IVS) {
870 auto ReadAccess = Stmt->
begin();
871 auto WriteAccess = ReadAccess++;
872 assert((*ReadAccess)->isRead() && (*WriteAccess)->isMustWrite());
873 assert((*ReadAccess)->getElementType() == (*WriteAccess)->getElementType() &&
874 "Accesses use the same data type");
875 assert((*ReadAccess)->isArrayKind() && (*WriteAccess)->isArrayKind());
877 isl_id_to_ast_expr_get(NewAccesses, (*ReadAccess)->getId().release());
880 isl_id_to_ast_expr_get(NewAccesses, (*WriteAccess)->getId().release());
881 auto *StoreAddr =
ExprBuilder.createAccessAddress(AccessExpr).first;
882 Builder.CreateStore(LoadValue, StoreAddr);
887 "trying to materialize loop induction variable twice");
888 const SCEV *OuterLIV =
SE.getAddRecExpr(
SE.getUnknown(
Builder.getInt64(0)),
917 BlockGen.copyStmt(*Stmt, LTS, NewAccesses);
919 RegionGen.copyStmt(*Stmt, LTS, NewAccesses);
922 isl_id_to_ast_expr_free(NewAccesses);
930 for (
int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
931 create(isl_ast_node_list_get_ast_node(List, i));
934 isl_ast_node_list_free(List);
942 SmallVector<llvm::Value *, 8> Values;
945 auto Params =
S.getParamSpace();
964 llvm_unreachable(
"code generation error");
982 llvm_unreachable(
"Unknown isl_ast_node type");
995 SetVector<Value *> Values;
997 for (
auto *Val : Values) {
1000 if (
auto *Inst = dyn_cast<Instruction>(Val)) {
1001 if (
S.contains(Inst)) {
1009 auto Address = MemInst ? MemInst.getPointerOperand() :
nullptr;
1010 if (Address &&
SE.getUnknown(UndefValue::get(Address->getType())) ==
1011 SE.getPointerBase(
SE.getSCEV(Address))) {
1012 }
else if (
S.getStmtFor(Inst)) {
1015 auto *
Domain =
S.getDomainConditions(Inst->getParent()).release();
1021 V = UndefValue::get(ParamSCEV->getType());
1027 if (
auto *IAClass =
S.lookupInvariantEquivClass(Val)) {
1031 if (IAClass->InvariantAccesses.empty())
1032 V = UndefValue::get(ParamSCEV->getType());
1061 for (
const SCEV *Param :
S.parameters()) {
1062 isl_id *Id =
S.getIdForParam(Param).release();
1071 Instruction *AccInst) {
1081 Type *Ty = AccInst->getType();
1083 auto *Ptr = AddressValue;
1084 auto Name = Ptr->getName();
1085 PreloadVal =
Builder.CreateLoad(Ty, Ptr, Name +
".load");
1086 if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal))
1087 PreloadInst->setAlignment(cast<LoadInst>(AccInst)->getAlign());
1102 bool AlwaysExecuted =
Domain.is_equal(Universe);
1105 Type *AccInstTy = AccInst->getType();
1118 "polly.preload.cond.overflown");
1119 Cond =
Builder.CreateAnd(Cond, OverflowHappened,
"polly.preload.cond.result");
1122 if (!Cond->getType()->isIntegerTy(1))
1123 Cond =
Builder.CreateIsNotNull(Cond);
1125 BasicBlock *CondBB = SplitBlock(
Builder.GetInsertBlock(),
1127 CondBB->setName(
"polly.preload.cond");
1129 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(),
GenDT,
GenLI);
1130 MergeBB->setName(
"polly.preload.merge");
1132 Function *F =
Builder.GetInsertBlock()->getParent();
1133 LLVMContext &Context = F->getContext();
1134 BasicBlock *ExecBB = BasicBlock::Create(Context,
"polly.preload.exec", F);
1136 GenDT->addNewBlock(ExecBB, CondBB);
1137 if (Loop *L =
GenLI->getLoopFor(CondBB))
1138 L->addBasicBlockToLoop(ExecBB, *
GenLI);
1140 auto *CondBBTerminator = CondBB->getTerminator();
1141 Builder.SetInsertPoint(CondBB, CondBBTerminator->getIterator());
1142 Builder.CreateCondBr(Cond, ExecBB, MergeBB);
1143 CondBBTerminator->eraseFromParent();
1145 Builder.SetInsertPoint(ExecBB);
1148 Builder.SetInsertPoint(ExecBB, ExecBB->getTerminator()->getIterator());
1150 Builder.SetInsertPoint(MergeBB, MergeBB->getTerminator()->getIterator());
1151 auto *MergePHI =
Builder.CreatePHI(
1152 AccInstTy, 2,
"polly.preload." + AccInst->getName() +
".merge");
1153 Value *PreloadVal = MergePHI;
1156 PreloadVal =
nullptr;
1157 PreAccInst = UndefValue::get(AccInstTy);
1160 MergePHI->addIncoming(PreAccInst, ExecBB);
1161 MergePHI->addIncoming(Constant::getNullValue(AccInstTy), CondBB);
1197 if (
auto *BaseIAClass =
S.lookupInvariantEquivClass(SAI->getBasePtr())) {
1203 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1204 ExecutionCtx = ExecutionCtx.
intersect(BaseExecutionCtx);
1209 for (
unsigned i = 1, e = SAI->getNumberOfDimensions(); i < e; ++i) {
1210 const SCEV *Dim = SAI->getDimensionSize(i);
1211 SetVector<Value *> Values;
1213 for (
auto *Val : Values) {
1214 if (
auto *BaseIAClass =
S.lookupInvariantEquivClass(Val)) {
1220 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1221 ExecutionCtx = ExecutionCtx.
intersect(BaseExecutionCtx);
1227 Type *AccInstTy = AccInst->getType();
1235 assert(PreloadVal->getType() == MAAccInst->getType());
1239 if (
SE.isSCEVable(AccInstTy)) {
1240 isl_id *ParamId =
S.getIdForParam(
SE.getSCEV(AccInst)).release();
1246 BasicBlock *EntryBB = &
Builder.GetInsertBlock()->getParent()->getEntryBlock();
1247 auto *
Alloca =
new AllocaInst(AccInstTy,
DL.getAllocaAddrSpace(),
1248 AccInst->getName() +
".preload.s2a",
1249 EntryBB->getFirstInsertionPt());
1252 PreloadedPointer[PreloadVal] = AccInst;
1253 Annotator.addAlternativeAliasBases(PreloadedPointer);
1255 for (
auto *DerivedSAI : SAI->getDerivedSAIs()) {
1256 Value *BasePtr = DerivedSAI->getBasePtr();
1264 assert(BasePtr->getType() == PreloadVal->getType());
1265 DerivedSAI->setBasePtr(PreloadVal);
1278 for (
auto *U : MAAccInst->users())
1279 if (Instruction *UI = dyn_cast<Instruction>(U))
1280 if (!
S.contains(UI))
1281 EscapeUsers.push_back(UI);
1283 if (EscapeUsers.empty())
1287 std::make_pair(
Alloca, std::move(EscapeUsers));
1294 for (
auto &SAI :
S.arrays()) {
1295 if (SAI->getBasePtr())
1298 assert(SAI->getNumberOfDimensions() > 0 && SAI->getDimensionSize(0) &&
1299 "The size of the outermost dimension is used to declare newly "
1300 "created arrays that require memory allocation.");
1302 Type *NewArrayType =
nullptr;
1305 uint64_t ArraySizeInt = 1;
1306 for (
int i = SAI->getNumberOfDimensions() - 1; i >= 0; i--) {
1307 auto *DimSize = SAI->getDimensionSize(i);
1308 unsigned UnsignedDimSize =
static_cast<const SCEVConstant *
>(DimSize)
1313 NewArrayType = SAI->getElementType();
1315 NewArrayType = ArrayType::get(NewArrayType, UnsignedDimSize);
1316 ArraySizeInt *= UnsignedDimSize;
1319 if (SAI->isOnHeap()) {
1320 LLVMContext &
Ctx = NewArrayType->getContext();
1323 auto IntPtrTy =
DL.getIntPtrType(
Ctx);
1326 unsigned Size = SAI->getElemSizeInBytes();
1329 BasicBlock *
StartBlock = std::get<0>(StartExitBlocks);
1332 auto *CreatedArray =
Builder.CreateMalloc(
1333 IntPtrTy, SAI->getElementType(),
1334 ConstantInt::get(Type::getInt64Ty(
Ctx), Size),
1335 ConstantInt::get(Type::getInt64Ty(
Ctx), ArraySizeInt),
nullptr,
1338 SAI->setBasePtr(CreatedArray);
1341 BasicBlock *ExitingBlock = std::get<1>(StartExitBlocks);
1342 Builder.SetInsertPoint(ExitingBlock,
1343 ExitingBlock->getTerminator()->getIterator());
1344 Builder.CreateFree(CreatedArray);
1346 auto InstIt =
Builder.GetInsertBlock()
1352 auto *CreatedArray =
new AllocaInst(NewArrayType,
DL.getAllocaAddrSpace(),
1353 SAI->getName(), InstIt);
1356 SAI->setBasePtr(CreatedArray);
1362 auto &InvariantEquivClasses =
S.getInvariantAccesses();
1363 if (InvariantEquivClasses.empty())
1366 BasicBlock *PreLoadBB = SplitBlock(
Builder.GetInsertBlock(),
1368 PreLoadBB->setName(
"polly.preload.begin");
1369 Builder.SetInsertPoint(PreLoadBB, PreLoadBB->begin());
1371 for (
auto &IAClass : InvariantEquivClasses)
1388 Loop *L =
LI.getLoopFor(
S.getEntry());
1390 while (L !=
nullptr &&
S.contains(L))
1391 L = L->getParentLoop();
1393 while (L !=
nullptr) {
1395 L = L->getParentLoop();
1414 "Insert location points after last valid instruction");
1415 BasicBlock::iterator InsertLocation =
Builder.GetInsertPoint();
1418 "polly", Expr, Expr->getType(), InsertLocation,
1442 if (!RTC->getType()->isIntegerTy(1))
1443 RTC =
Builder.CreateIsNotNull(RTC);
1444 Value *OverflowHappened =
1448 auto *F =
Builder.GetInsertBlock()->getParent();
1451 "F: " + F->getName().str() +
" R: " +
S.getRegion().getNameStr() +
1453 RTC,
" Overflow: ", OverflowHappened,
1455 " (0 failed, -1 succeeded)\n"
1456 " (if one or both are 0 falling back to original code, if both are -1 "
1457 "executing Polly code)\n");
1460 RTC =
Builder.CreateAnd(RTC, OverflowHappened,
"polly.rtc.result");
1463 if (!isa<ConstantInt>(RTC))
static void findReferencesInInst(Instruction *Inst, ScopStmt *UserStmt, Loop *UserScope, const ValueMapT &GlobalMap, SetVector< Value * > &Values, SetVector< const SCEV * > &SCEVs)
static void findReferencesByUse(Value *SrcVal, ScopStmt *UserStmt, Loop *UserScope, const ValueMapT &GlobalMap, SetVector< Value * > &Values, SetVector< const SCEV * > &SCEVs)
static void addReferencesFromStmtSet(isl::set Set, SubtreeReferences *UserPtr)
Extract the out-of-scop values and SCEVs referenced from a set describing a ScopStmt.
static cl::opt< bool > PollyGenerateRTCPrint("polly-codegen-emit-rtc-print", cl::desc("Emit code that prints the runtime check result dynamically."), cl::Hidden, cl::cat(PollyCategory))
static void addReferencesFromStmtUnionSet(isl::union_set USet, SubtreeReferences &References)
Extract the out-of-scop values and SCEVs referenced from a union set referencing multiple ScopStmts.
static cl::opt< bool > PollyGenerateExpressions("polly-codegen-generate-expressions", cl::desc("Generate AST expressions for unmodified and modified accesses"), cl::Hidden, cl::cat(PollyCategory))
STATISTIC(VersionedScops, "Number of SCoPs that required versioning.")
static bool IsLoopVectorizerDisabled(isl::ast_node_for Node)
Restore the initial ordering of dimensions of the band node.
static void findReferencesInStmt(ScopStmt *Stmt, SetVector< Value * > &Values, ValueMapT &GlobalMap, SetVector< const SCEV * > &SCEVs)
static cl::opt< OpenMPBackend > PollyOmpBackend("polly-omp-backend", cl::desc("Choose the OpenMP library to use:"), cl::values(clEnumValN(OpenMPBackend::GNU, "GNU", "GNU OpenMP"), clEnumValN(OpenMPBackend::LLVM, "LLVM", "LLVM OpenMP")), cl::Hidden, cl::init(OpenMPBackend::GNU), cl::cat(PollyCategory))
static cl::opt< int > PollyTargetFirstLevelCacheLineSize("polly-target-first-level-cache-line-size", cl::desc("The size of the first level cache line size specified in bytes."), cl::Hidden, cl::init(64), cl::cat(PollyCategory))
OpenMPBackend
OpenMP backend options.
llvm::cl::OptionCategory PollyCategory
__isl_export __isl_give isl_ast_expr * isl_ast_node_for_get_init(__isl_keep isl_ast_node *node)
__isl_export __isl_give isl_ast_node_list * isl_ast_node_block_get_children(__isl_keep isl_ast_node *node)
__isl_null isl_ast_expr * isl_ast_expr_free(__isl_take isl_ast_expr *expr)
isl_size isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
enum isl_ast_expr_op_type isl_ast_expr_get_op_type(__isl_keep isl_ast_expr *expr)
__isl_give isl_ast_expr * isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr, int pos)
__isl_export __isl_give isl_ast_node * isl_ast_node_mark_get_node(__isl_keep isl_ast_node *node)
__isl_export __isl_give isl_ast_expr * isl_ast_node_for_get_inc(__isl_keep isl_ast_node *node)
__isl_give isl_ast_node * isl_ast_node_if_get_else(__isl_keep isl_ast_node *node)
__isl_export __isl_give isl_ast_node * isl_ast_node_for_get_body(__isl_keep isl_ast_node *node)
__isl_give isl_id * isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
__isl_export __isl_give isl_ast_expr * isl_ast_node_user_get_expr(__isl_keep isl_ast_node *node)
__isl_export __isl_give isl_ast_expr * isl_ast_node_if_get_cond(__isl_keep isl_ast_node *node)
__isl_export __isl_give isl_id * isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node)
__isl_export __isl_give isl_ast_expr * isl_ast_node_for_get_iterator(__isl_keep isl_ast_node *node)
__isl_null isl_ast_node * isl_ast_node_free(__isl_take isl_ast_node *node)
__isl_give isl_ast_node * isl_ast_node_if_get_then(__isl_keep isl_ast_node *node)
isl_bool isl_ast_node_if_has_else(__isl_keep isl_ast_node *node)
__isl_give isl_ast_expr * isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
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
__isl_give isl_ast_expr * release()
__isl_keep isl_ast_expr * get() const
isl::checked::ast_node_list children() const
isl::checked::ast_node body() const
isl::checked::ast_expr init() const
isl::checked::ast_expr cond() const
isl::checked::ast_expr inc() const
isl::checked::ast_expr iterator() const
isl::checked::id id() const
__isl_keep isl_ast_node * get() const
__isl_give isl_ast_node * release()
__isl_give isl_id_to_ast_expr * release()
isl::checked::id_to_ast_expr set(isl::checked::id key, isl::checked::ast_expr val) const
std::string get_name() const
__isl_keep isl_id * get() const
isl::checked::set range() const
isl::checked::pw_multi_aff gist_params(isl::checked::set set) const
isl::checked::set domain() const
isl::checked::set intersect(isl::checked::set set2) const
__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
static isl::id_to_ast_expr alloc(isl::ctx ctx, int min_size)
static isl::pw_multi_aff from_set(isl::set set)
static isl::set universe(isl::space space)
SmallVector< Instruction *, 4 > EscapeUserVectorTy
Simple vector of instructions to store escape users.
static bool isParallel(const isl::ast_node &Node)
Is this loop a parallel loop?
static bool isExecutedInParallel(const isl::ast_node &Node)
Will the loop be run as thread parallel?
static isl::union_map getSchedule(const isl::ast_node &Node)
Get the nodes schedule or a nullptr if not available.
static isl::ast_build getBuild(const isl::ast_node &Node)
Get the nodes build context or a nullptr if not available.
static bool isReductionParallel(const isl::ast_node &Node)
Is this loop a reduction parallel loop?
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.
void generateBeginScopTrace()
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)
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.
void getReferencesInSubtree(const isl::ast_node &For, SetVector< Value * > &Values, SetVector< const Loop * > &Loops)
Compute the values and loops referenced in this subtree.
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 <S)
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)
Represent memory accesses in statements.
Instruction * getAccessInstruction() const
Return the access instruction of this memory access.
bool isRead() const
Is this a read memory access?
isl::map getAddressFunction() const
Get an isl map describing the memory address accessed.
const ScopArrayInfo * getScopArrayInfo() const
Legacy name of getOriginalScopArrayInfo().
Value * getOriginalBaseAddr() const
Get the original base address of this access (e.g.
bool isArrayKind() const
Old name of isOriginalArrayKind.
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...
const std::vector< Instruction * > & getInstructions() const
bool isBlockStmt() const
Return true if this statement represents a single basic block.
Region * getRegion() const
Get the region represented by this ScopStmt (if any).
BasicBlock * getBasicBlock() const
Get the BasicBlock represented by this ScopStmt (if any).
bool isCopyStmt() const
Return true if this is a copy statement.
bool isRegionStmt() const
Return true if this statement represents a whole region.
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.
ScalarEvolution * getSE() const
Return the scalar evolution.
isl::ctx getIslCtx() const
Get the isl context of this static control part.
LoopInfo * getLI() const
Return the LoopInfo used for this Scop.
bool contains(const Loop *L) const
Check if L is contained in the SCoP.
const Region & getRegion() const
Get the maximum region of this static control part.
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.
__isl_export __isl_keep const char * isl_id_get_name(__isl_keep isl_id *id)
__isl_null isl_id * isl_id_free(__isl_take isl_id *id)
void * isl_id_get_user(__isl_keep isl_id *id)
enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
__isl_export __isl_give isl_set * isl_map_domain(__isl_take isl_map *bmap)
boolean manage(isl_bool val)
aff manage_copy(__isl_keep isl_aff *ptr)
std::forward_list< MemoryAccess * > MemoryAccessList
Ordered list type to hold accesses.
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.
void addReferencesFromStmt(ScopStmt *Stmt, void *UserPtr, bool CreateScalarRefs=true)
Extract the out-of-scop values and SCEVs referenced from a ScopStmt.
BandAttr * getLoopAttr(const isl::id &Id)
Return the BandAttr of a loop's isl::id.
Value * createLoop(Value *LowerBound, Value *UpperBound, Value *Stride, PollyIRBuilder &Builder, LoopInfo &LI, DominatorTree &DT, BasicBlock *&ExitBlock, ICmpInst::Predicate Predicate, ScopAnnotator *Annotator=nullptr, bool Parallel=false, bool UseGuard=true, bool LoopVectDisabled=false)
Create a scalar do/for-style loop.
llvm::iota_range< unsigned > rangeIslSize(unsigned Begin, isl::size End)
Check that End is valid and return an iterator from Begin to End.
llvm::DenseMap< const llvm::Loop *, llvm::SCEVUse > LoopToScevMapT
Same as llvm/Analysis/ScalarEvolutionExpressions.h.
llvm::DenseMap< llvm::AssertingVH< llvm::Value >, llvm::AssertingVH< llvm::Value > > ValueMapT
Type to remap values.
std::pair< llvm::BasicBlock *, llvm::BasicBlock * > BBPair
Type to hold region delimiters (entry & exit block).
__isl_export __isl_give isl_set * isl_set_intersect_params(__isl_take isl_set *set, __isl_take isl_set *params)
__isl_null isl_set * isl_set_free(__isl_take isl_set *set)
__isl_export isl_bool isl_set_is_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
isl_bool isl_set_involves_dims(__isl_keep isl_set *set, enum isl_dim_type type, unsigned first, unsigned n)
isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type)
__isl_give isl_id * isl_set_get_dim_id(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos)
__isl_export isl_bool isl_set_is_empty(__isl_keep isl_set *set)
Represent the attributes of a loop.
Type for equivalent invariant accesses and their domain context.
MemoryAccessList InvariantAccesses
Memory accesses now treated invariant.
Type * AccessType
The type of the invariant access.
isl::set ExecutionContext
The execution context under which the memory location is accessed.
const SCEV * IdentifyingPointer
The pointer that identifies this equivalence class.
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")
__isl_give isl_set * isl_set_from_union_set(__isl_take isl_union_set *uset)