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) {
237 Loop *Scope = LI->getLoopFor(BB);
242 for (BasicBlock *BB : Stmt->
getRegion()->blocks()) {
243 Loop *Scope = LI->getLoopFor(BB);
244 for (Instruction &Inst : *BB)
251 bool CreateScalarRefs) {
257 for (
auto &Access : *Stmt) {
258 if (References.ParamSpace) {
259 isl::space ParamSpace = Access->getLatestAccessRelation().get_space();
260 (*References.ParamSpace) =
261 References.ParamSpace->align_params(ParamSpace);
264 if (Access->isLatestArrayKind()) {
265 auto *BasePtr = Access->getLatestScopArrayInfo()->getBasePtr();
266 if (Instruction *OpInst = dyn_cast<Instruction>(BasePtr))
270 References.Values.insert(BasePtr);
274 if (CreateScalarRefs)
275 References.Values.insert(References.BlockGen.getOrCreateAlloca(*Access));
291 isl::id Id = Set.get_tuple_id();
292 auto *Stmt =
static_cast<ScopStmt *
>(Id.get_user());
322 SetVector<Value *> &Values,
323 SetVector<const Loop *> &Loops) {
324 SetVector<const SCEV *> SCEVs;
328 Values.insert_range(llvm::make_second_range(
IDToValue));
332 Values.insert(cast<SCEVUnknown>(I.second)->getValue());
337 for (
const SCEV *Expr : SCEVs) {
342 Values.remove_if([](
const Value *V) {
return isa<GlobalValue>(V); });
355 Loops.remove_if([
this](
const Loop *L) {
356 return S.contains(L) || L->contains(
S.getEntry());
365 SetVector<Value *> ReplacedValues;
366 for (
Value *V : Values) {
369 Values = ReplacedValues;
399 AncestorLoopAttr =
Annotator.getStagingAttrEnv();
401 Annotator.getStagingAttrEnv() = ChildLoopAttr;
408 "Nest must not overwrite loop attr environment");
409 Annotator.getStagingAttrEnv() = AncestorLoopAttr;
430 auto Id = BodyMark.
id();
431 if (strcmp(Id.get_name().c_str(),
"Loop Vectorizer Disabled") == 0)
438 Value *ValueLB, *ValueUB, *ValueInc;
440 BasicBlock *ExitBlock;
442 CmpInst::Predicate Predicate;
457 isl::id IteratorID = Iterator.get_id();
465 MaxType =
ExprBuilder.getWidestType(MaxType, ValueLB->getType());
466 MaxType =
ExprBuilder.getWidestType(MaxType, ValueUB->getType());
467 MaxType =
ExprBuilder.getWidestType(MaxType, ValueInc->getType());
469 if (MaxType != ValueLB->getType())
470 ValueLB =
Builder.CreateSExt(ValueLB, MaxType);
471 if (MaxType != ValueUB->getType())
472 ValueUB =
Builder.CreateSExt(ValueUB, MaxType);
473 if (MaxType != ValueInc->getType())
474 ValueInc =
Builder.CreateSExt(ValueInc, MaxType);
478 bool UseGuardBB = !
GenSE->isKnownPredicate(Predicate,
GenSE->getSCEV(ValueLB),
479 GenSE->getSCEV(ValueUB));
481 ExitBlock, Predicate, &
Annotator, MarkParallel, UseGuardBB,
482 LoopVectorizerDisabled);
491 Builder.SetInsertPoint(ExitBlock, ExitBlock->begin());
500 Value *ValueLB, *ValueUB, *ValueInc;
503 CmpInst::Predicate Predicate;
510 ParBB->setName(
"polly.parallel.for");
511 Builder.SetInsertPoint(ParBB, ParBB->begin());
527 if (Predicate == CmpInst::ICMP_SLT)
529 ValueUB,
Builder.CreateSExt(
Builder.getTrue(), ValueUB->getType()));
532 MaxType =
ExprBuilder.getWidestType(MaxType, ValueLB->getType());
533 MaxType =
ExprBuilder.getWidestType(MaxType, ValueUB->getType());
534 MaxType =
ExprBuilder.getWidestType(MaxType, ValueInc->getType());
536 if (MaxType != ValueLB->getType())
537 ValueLB =
Builder.CreateSExt(ValueLB, MaxType);
538 if (MaxType != ValueUB->getType())
539 ValueUB =
Builder.CreateSExt(ValueUB, MaxType);
540 if (MaxType != ValueInc->getType())
541 ValueInc =
Builder.CreateSExt(ValueInc, MaxType);
543 BasicBlock::iterator LoopBody;
545 SetVector<Value *> SubtreeValues;
546 SetVector<const Loop *> Loops;
554 for (
const Loop *L : Loops) {
556 SubtreeValues.insert(LoopInductionVar);
561 std::unique_ptr<ParallelLoopGenerator> ParallelLoopGenPtr;
572 IV = ParallelLoopGenPtr->createParallelLoop(
573 ValueLB, ValueUB, ValueInc, SubtreeValues, NewValues, &LoopBody);
574 BasicBlock::iterator AfterLoop =
Builder.GetInsertPoint();
577 Function *SubFn = LoopBody->getFunction();
583 Function *CallerFn =
Builder.GetInsertBlock()->getParent();
584 DominatorTree *CallerDT =
GenDT;
585 LoopInfo *CallerLI =
GenLI;
586 ScalarEvolution *CallerSE =
GenSE;
592 DominatorTree *SubDT = ParallelLoopGenPtr->getCalleeDominatorTree();
593 LoopInfo *SubLI = ParallelLoopGenPtr->getCalleeLoopInfo();
602 TargetLibraryInfoImpl BaselineInfoImpl(SubFn->getParent()->getTargetTriple());
603 TargetLibraryInfo CalleeTLI(BaselineInfoImpl, SubFn);
604 AssumptionCache CalleeAC(*SubFn);
605 std::unique_ptr<ScalarEvolution> SubSE = std::make_unique<ScalarEvolution>(
606 *SubFn, CalleeTLI, CalleeAC, *SubDT, *SubLI);
615 Builder.SetInsertPoint(LoopBody);
620 for (
auto &[OldVal, NewVal] :
ValueMap) {
621 NewVal = NewValues.lookup(NewVal);
633 for (
auto &[NewVal, NewNewVal] : NewValues) {
634 if (Instruction *NewValInst = dyn_cast<Instruction>((
Value *)NewVal)) {
635 if (
S.contains(NewValInst))
637 assert(NewValInst->getFunction() == &
S.getFunction());
644 for (
auto &[OldVal, NewVal] :
IDToValue) {
645 NewVal = NewValues.lookup(NewVal);
652 for (
auto &[OldVal, SubVal] :
ValueMap) {
653 Instruction *SubInst = dyn_cast<Instruction>((
Value *)SubVal);
654 assert(SubInst->getFunction() == SubFn &&
655 "Instructions from outside the subfn cannot be accessed within the "
659 Instruction *SubInst = dyn_cast<Instruction>((
Value *)SubVal);
660 assert(SubInst->getFunction() == SubFn &&
661 "Instructions from outside the subfn cannot be accessed within the "
667 for (
auto P : NewValues)
668 NewValuesReverse[P.second] = P.first;
670 Annotator.addAlternativeAliasBases(NewValuesReverse);
681 ValueMap = std::move(CallerGlobals);
682 ExprBuilder.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
683 RegionGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
684 BlockGen.switchGeneratedFunc(CallerFn, CallerDT, CallerLI, CallerSE);
685 Builder.SetInsertPoint(AfterLoop);
687 for (
const Loop *L : Loops)
710 Function *F =
Builder.GetInsertBlock()->getParent();
711 LLVMContext &Context = F->getContext();
713 BasicBlock *CondBB = SplitBlock(
Builder.GetInsertBlock(),
715 CondBB->setName(
"polly.cond");
716 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(),
GenDT,
GenLI);
717 MergeBB->setName(
"polly.merge");
718 BasicBlock *ThenBB = BasicBlock::Create(Context,
"polly.then", F);
719 BasicBlock *ElseBB = BasicBlock::Create(Context,
"polly.else", F);
721 GenDT->addNewBlock(ThenBB, CondBB);
722 GenDT->addNewBlock(ElseBB, CondBB);
723 GenDT->changeImmediateDominator(MergeBB, CondBB);
725 Loop *L =
GenLI->getLoopFor(CondBB);
727 L->addBasicBlockToLoop(ThenBB, *
GenLI);
728 L->addBasicBlockToLoop(ElseBB, *
GenLI);
731 CondBB->getTerminator()->eraseFromParent();
733 Builder.SetInsertPoint(CondBB);
735 Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
736 Builder.SetInsertPoint(ThenBB);
738 Builder.SetInsertPoint(ElseBB);
740 Builder.SetInsertPoint(ThenBB, ThenBB->begin());
744 Builder.SetInsertPoint(ElseBB, ElseBB->begin());
749 Builder.SetInsertPoint(MergeBB, MergeBB->begin());
763 assert(!Build.
is_null() &&
"Could not obtain isl_ast_build from user node");
766 for (
auto *MA : *Stmt) {
767 if (!MA->hasNewAccessRelation()) {
771 if (MA->getLatestScopArrayInfo()->getBasePtrOriginSAI())
775 dyn_cast<Instruction>(MA->getLatestScopArrayInfo()->getBasePtr());
783 "Only affine memory accesses can be code generated");
797 "Access relation not defined on full schedule domain");
799 "Access relation not defined on full domain");
814 NewAccesses = NewAccesses.
set(MA->getId(), AccessExpr);
823 "Expression of type 'op' expected");
825 "Operation of type 'call' expected");
841 std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
846 for (
Value *IV : IVS) {
860 auto ReadAccess = Stmt->
begin();
861 auto WriteAccess = ReadAccess++;
862 assert((*ReadAccess)->isRead() && (*WriteAccess)->isMustWrite());
863 assert((*ReadAccess)->getElementType() == (*WriteAccess)->getElementType() &&
864 "Accesses use the same data type");
865 assert((*ReadAccess)->isArrayKind() && (*WriteAccess)->isArrayKind());
867 isl_id_to_ast_expr_get(NewAccesses, (*ReadAccess)->getId().release());
870 isl_id_to_ast_expr_get(NewAccesses, (*WriteAccess)->getId().release());
871 auto *StoreAddr =
ExprBuilder.createAccessAddress(AccessExpr).first;
872 Builder.CreateStore(LoadValue, StoreAddr);
877 "trying to materialize loop induction variable twice");
878 const SCEV *OuterLIV =
SE.getAddRecExpr(
SE.getUnknown(
Builder.getInt64(0)),
907 BlockGen.copyStmt(*Stmt, LTS, NewAccesses);
909 RegionGen.copyStmt(*Stmt, LTS, NewAccesses);
912 isl_id_to_ast_expr_free(NewAccesses);
920 for (
int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
921 create(isl_ast_node_list_get_ast_node(List, i));
924 isl_ast_node_list_free(List);
930 llvm_unreachable(
"code generation error");
948 llvm_unreachable(
"Unknown isl_ast_node type");
961 SetVector<Value *> Values;
963 for (
auto *Val : Values) {
966 if (
auto *Inst = dyn_cast<Instruction>(Val)) {
967 if (
S.contains(Inst)) {
975 auto Address = MemInst ? MemInst.getPointerOperand() :
nullptr;
976 if (Address &&
SE.getUnknown(UndefValue::get(Address->getType())) ==
977 SE.getPointerBase(
SE.getSCEV(Address))) {
978 }
else if (
S.getStmtFor(Inst)) {
981 auto *
Domain =
S.getDomainConditions(Inst->getParent()).release();
987 V = UndefValue::get(ParamSCEV->getType());
993 if (
auto *IAClass =
S.lookupInvariantEquivClass(Val)) {
997 if (IAClass->InvariantAccesses.empty())
998 V = UndefValue::get(ParamSCEV->getType());
1027 for (
const SCEV *Param :
S.parameters()) {
1028 isl_id *Id =
S.getIdForParam(Param).release();
1037 Instruction *AccInst) {
1047 Type *Ty = AccInst->getType();
1049 auto *Ptr = AddressValue;
1050 auto Name = Ptr->getName();
1051 PreloadVal =
Builder.CreateLoad(Ty, Ptr, Name +
".load");
1052 if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal))
1053 PreloadInst->setAlignment(cast<LoadInst>(AccInst)->getAlign());
1057 if (
SE.isSCEVable(Ty))
1058 SE.forgetValue(AccInst);
1081 Type *AccInstTy = AccInst->getType();
1083 Value *PreloadVal =
nullptr;
1084 if (AlwaysExecuted) {
1104 "polly.preload.cond.overflown");
1105 Cond =
Builder.CreateAnd(Cond, OverflowHappened,
"polly.preload.cond.result");
1108 if (!Cond->getType()->isIntegerTy(1))
1109 Cond =
Builder.CreateIsNotNull(Cond);
1111 BasicBlock *CondBB = SplitBlock(
Builder.GetInsertBlock(),
1113 CondBB->setName(
"polly.preload.cond");
1115 BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(),
GenDT,
GenLI);
1116 MergeBB->setName(
"polly.preload.merge");
1118 Function *F =
Builder.GetInsertBlock()->getParent();
1119 LLVMContext &Context = F->getContext();
1120 BasicBlock *ExecBB = BasicBlock::Create(Context,
"polly.preload.exec", F);
1122 GenDT->addNewBlock(ExecBB, CondBB);
1123 if (Loop *L =
GenLI->getLoopFor(CondBB))
1124 L->addBasicBlockToLoop(ExecBB, *
GenLI);
1126 auto *CondBBTerminator = CondBB->getTerminator();
1127 Builder.SetInsertPoint(CondBB, CondBBTerminator->getIterator());
1128 Builder.CreateCondBr(Cond, ExecBB, MergeBB);
1129 CondBBTerminator->eraseFromParent();
1131 Builder.SetInsertPoint(ExecBB);
1134 Builder.SetInsertPoint(ExecBB, ExecBB->getTerminator()->getIterator());
1136 Builder.SetInsertPoint(MergeBB, MergeBB->getTerminator()->getIterator());
1137 auto *MergePHI =
Builder.CreatePHI(
1138 AccInstTy, 2,
"polly.preload." + AccInst->getName() +
".merge");
1139 PreloadVal = MergePHI;
1142 PreloadVal =
nullptr;
1143 PreAccInst = UndefValue::get(AccInstTy);
1146 MergePHI->addIncoming(PreAccInst, ExecBB);
1147 MergePHI->addIncoming(Constant::getNullValue(AccInstTy), CondBB);
1184 if (
auto *BaseIAClass =
S.lookupInvariantEquivClass(SAI->getBasePtr())) {
1190 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1191 ExecutionCtx = ExecutionCtx.
intersect(BaseExecutionCtx);
1196 for (
unsigned i = 1, e = SAI->getNumberOfDimensions(); i < e; ++i) {
1197 const SCEV *Dim = SAI->getDimensionSize(i);
1198 SetVector<Value *> Values;
1200 for (
auto *Val : Values) {
1201 if (
auto *BaseIAClass =
S.lookupInvariantEquivClass(Val)) {
1207 isl::set BaseExecutionCtx = BaseIAClass->ExecutionContext;
1208 ExecutionCtx = ExecutionCtx.
intersect(BaseExecutionCtx);
1214 Type *AccInstTy = AccInst->getType();
1222 assert(PreloadVal->getType() == MAAccInst->getType());
1226 if (
SE.isSCEVable(AccInstTy)) {
1227 isl_id *ParamId =
S.getIdForParam(
SE.getSCEV(AccInst)).release();
1233 BasicBlock *EntryBB = &
Builder.GetInsertBlock()->getParent()->getEntryBlock();
1234 auto *
Alloca =
new AllocaInst(AccInstTy,
DL.getAllocaAddrSpace(),
1235 AccInst->getName() +
".preload.s2a",
1236 EntryBB->getFirstInsertionPt());
1239 PreloadedPointer[PreloadVal] = AccInst;
1240 Annotator.addAlternativeAliasBases(PreloadedPointer);
1242 for (
auto *DerivedSAI : SAI->getDerivedSAIs()) {
1243 Value *BasePtr = DerivedSAI->getBasePtr();
1251 assert(BasePtr->getType() == PreloadVal->getType());
1252 DerivedSAI->setBasePtr(PreloadVal);
1265 for (
auto *U : MAAccInst->users())
1266 if (Instruction *UI = dyn_cast<Instruction>(U))
1267 if (!
S.contains(UI))
1268 EscapeUsers.push_back(UI);
1270 if (EscapeUsers.empty())
1274 std::make_pair(
Alloca, std::move(EscapeUsers));
1281 for (
auto &SAI :
S.arrays()) {
1282 if (SAI->getBasePtr())
1285 assert(SAI->getNumberOfDimensions() > 0 && SAI->getDimensionSize(0) &&
1286 "The size of the outermost dimension is used to declare newly "
1287 "created arrays that require memory allocation.");
1289 Type *NewArrayType =
nullptr;
1292 uint64_t ArraySizeInt = 1;
1293 for (
int i = SAI->getNumberOfDimensions() - 1; i >= 0; i--) {
1294 auto *DimSize = SAI->getDimensionSize(i);
1295 unsigned UnsignedDimSize =
static_cast<const SCEVConstant *
>(DimSize)
1300 NewArrayType = SAI->getElementType();
1302 NewArrayType = ArrayType::get(NewArrayType, UnsignedDimSize);
1303 ArraySizeInt *= UnsignedDimSize;
1306 if (SAI->isOnHeap()) {
1307 LLVMContext &
Ctx = NewArrayType->getContext();
1310 auto IntPtrTy =
DL.getIntPtrType(
Ctx);
1313 unsigned Size = SAI->getElemSizeInBytes();
1316 BasicBlock *
StartBlock = std::get<0>(StartExitBlocks);
1319 auto *CreatedArray =
Builder.CreateMalloc(
1320 IntPtrTy, SAI->getElementType(),
1321 ConstantInt::get(Type::getInt64Ty(
Ctx), Size),
1322 ConstantInt::get(Type::getInt64Ty(
Ctx), ArraySizeInt),
nullptr,
1325 SAI->setBasePtr(CreatedArray);
1328 BasicBlock *ExitingBlock = std::get<1>(StartExitBlocks);
1329 Builder.SetInsertPoint(ExitingBlock,
1330 ExitingBlock->getTerminator()->getIterator());
1331 Builder.CreateFree(CreatedArray);
1333 auto InstIt =
Builder.GetInsertBlock()
1339 auto *CreatedArray =
new AllocaInst(NewArrayType,
DL.getAllocaAddrSpace(),
1340 SAI->getName(), InstIt);
1343 SAI->setBasePtr(CreatedArray);
1349 auto &InvariantEquivClasses =
S.getInvariantAccesses();
1350 if (InvariantEquivClasses.empty())
1353 BasicBlock *PreLoadBB = SplitBlock(
Builder.GetInsertBlock(),
1355 PreLoadBB->setName(
"polly.preload.begin");
1356 Builder.SetInsertPoint(PreLoadBB, PreLoadBB->begin());
1358 for (
auto &IAClass : InvariantEquivClasses)
1375 Loop *L =
LI.getLoopFor(
S.getEntry());
1377 while (L !=
nullptr &&
S.contains(L))
1378 L = L->getParentLoop();
1380 while (L !=
nullptr) {
1382 L = L->getParentLoop();
1401 "Insert location points after last valid instruction");
1402 BasicBlock::iterator InsertLocation =
Builder.GetInsertPoint();
1405 "polly", Expr, Expr->getType(), InsertLocation,
1429 if (!RTC->getType()->isIntegerTy(1))
1430 RTC =
Builder.CreateIsNotNull(RTC);
1431 Value *OverflowHappened =
1435 auto *F =
Builder.GetInsertBlock()->getParent();
1438 "F: " + F->getName().str() +
" R: " +
S.getRegion().getNameStr() +
1440 RTC,
" Overflow: ", OverflowHappened,
1442 " (0 failed, -1 succeeded)\n"
1443 " (if one or both are 0 falling back to original code, if both are -1 "
1444 "executing Polly code)\n");
1447 RTC =
Builder.CreateAnd(RTC, OverflowHappened,
"polly.rtc.result");
1450 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_give isl_pw_multi_aff * isl_pw_multi_aff_from_set(__isl_take isl_set *set)
__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_give isl_ast_expr * isl_ast_expr_address_of(__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)
__isl_overload __isl_give isl_ast_expr * isl_ast_build_access_from_pw_multi_aff(__isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma)
__isl_export __isl_give isl_ast_build * isl_ast_build_from_context(__isl_take isl_set *set)
__isl_overload __isl_give isl_ast_expr * isl_ast_build_expr_from_set(__isl_keep isl_ast_build *build, __isl_take isl_set *set)
__isl_null isl_ast_build * isl_ast_build_free(__isl_take isl_ast_build *build)
isl::checked::ast_expr access_from(isl::checked::multi_pw_aff mpa) const
isl::checked::union_map get_schedule() 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
__isl_keep isl_id * get() const
__isl_give isl_map * release()
isl::checked::set domain() const
__isl_give isl_set * copy() const &
isl::checked::set intersect(isl::checked::set set2) const
__isl_give isl_set * release()
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)
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.
Value * preloadUnconditionally(__isl_take isl_set *AccessRange, isl_ast_build *Build, Instruction *AccInst)
Preload the memory access at AccessRange with Build.
void addParameters(__isl_take isl_set *Context)
Value * preloadInvariantLoad(const MemoryAccess &MA, __isl_take isl_set *Domain)
Preload the memory load access MA.
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.
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.
ValueMapT ValueMap
A set of Value -> Value remappings to apply when generating new code.
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)
__isl_export __isl_give isl_set * isl_map_range(__isl_take isl_map *map)
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::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_universe(__isl_take isl_space *space)
__isl_export __isl_give isl_space * isl_set_get_space(__isl_keep isl_set *set)
__isl_export isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
__isl_export __isl_give isl_set * isl_set_intersect_params(__isl_take isl_set *set, __isl_take isl_set *params)
__isl_export __isl_give isl_set * isl_set_gist_params(__isl_take isl_set *set, __isl_take isl_set *context)
__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 TupleKindPtr Domain("Domain")
__isl_give isl_set * isl_set_from_union_set(__isl_take isl_union_set *uset)