23#include "llvm/Analysis/DomTreeUpdater.h"
24#include "llvm/Analysis/LoopInfo.h"
25#include "llvm/Analysis/RegionInfo.h"
26#include "llvm/Analysis/ScalarEvolution.h"
27#include "llvm/Transforms/Utils/BasicBlockUtils.h"
28#include "llvm/Transforms/Utils/Local.h"
35static cl::opt<bool>
Aligned(
"enable-polly-aligned",
36 cl::desc(
"Assumed aligned memory accesses."),
41 "polly-codegen-add-debug-printing",
42 cl::desc(
"Add printf calls that show the values loaded/stored."),
47 "polly-codegen-trace-stmts",
48 cl::desc(
"Add printf calls that print the statement being executed"),
52 "polly-codegen-trace-scalars",
53 cl::desc(
"Add printf calls that print the values of all scalar values "
54 "used in a statement. Requires -polly-codegen-trace-stmts."),
69 if (!
SE.isSCEVable(Old->getType()))
72 const SCEV *Scev =
SE.getSCEVAtScope(Old, L);
76 if (isa<SCEVCouldNotCompute>(Scev))
80 VTV.insert_range(BBMap);
84 const DataLayout &DL =
S.getFunction().getDataLayout();
85 auto IP =
Builder.GetInsertPoint();
88 "Only instructions can be insert points for SCEVExpander");
90 S,
SE,
Builder.GetInsertBlock()->getParent(), *
GenSE, DL,
"polly", Scev,
91 Old->getType(), IP, &VTV, <S,
StartBlock->getSinglePredecessor());
93 BBMap[Old] = Expanded;
100 auto lookupGlobally = [
this](
Value *Old) ->
Value * {
119 if (Old->getType()->getScalarSizeInBits() <
120 New->getType()->getScalarSizeInBits())
121 New =
Builder.CreateTruncOrBitCast(New, Old->getType());
126 Value *New =
nullptr;
128 switch (VUse.getKind()) {
131 New = BBMap.lookup(Old);
140 if ((New = lookupGlobally(Old)))
143 assert(!BBMap.count(Old));
161 if ((New = BBMap.lookup(Old)))
177 if ((New = lookupGlobally(Old)))
189 if ((New = BBMap.lookup(Old)))
200 New = lookupGlobally(Old);
206 "Intra and inter-stmt values are never global");
207 New = BBMap.lookup(Old);
210 assert(New &&
"Unexpected scalar dependence in region!");
216 Instruction *NewInst = Inst->clone();
219 for (
Value *OldOperand : Inst->operands()) {
224 assert(!isa<StoreInst>(NewInst) &&
225 "Store instructions are always needed!");
226 NewInst->deleteValue();
232 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
236 BBMap[Inst] = NewInst;
238 assert(NewInst->getModule() == Inst->getModule() &&
239 "Expecting instructions to be in the same module");
241 if (!NewInst->getType()->isVoidTy())
242 NewInst->setName(
"p_" + Inst->getName());
248 isl_id_to_ast_expr *NewAccesses) {
259 Type *ExpectedType) {
260 isl_ast_expr *AccessExpr = isl_id_to_ast_expr_get(NewAccesses, Id);
268 "If expression was not generated, must use the original pointer value");
286 return LI.getLoopFor(StmtBB);
291 isl_id_to_ast_expr *NewAccesses) {
298 Builder.CreateAlignedLoad(Load->getType(), NewPointer, Load->getAlign(),
299 Load->getName() +
"_p_scalar_");
303 ": ", ScalarLoad,
"\n");
310 isl_id_to_ast_expr *NewAccesses) {
317 generateLocationAccessed(Stmt, Store, BBMap, LTS, NewAccesses);
318 Value *ValueOperand = getNewValue(Stmt, Store->getValueOperand(), BBMap,
319 LTS, getLoopForStmt(Stmt));
321 if (PollyDebugPrinting)
322 RuntimeDebugBuilder::createCPUPrinter(Builder,
"Store to ", NewPointer,
323 ": ", ValueOperand,
"\n");
325 Builder.CreateAlignedStore(ValueOperand, NewPointer, Store->getAlign());
337 isl_id_to_ast_expr *NewAccesses) {
340 if (Inst->isTerminator())
347 if (
auto *Load = dyn_cast<LoadInst>(Inst)) {
351 BBMap[Load] = NewLoad;
355 if (
auto *Store = dyn_cast<StoreInst>(Inst)) {
364 if (
auto *
PHI = dyn_cast<PHINode>(Inst)) {
378 auto NewBB =
Builder.GetInsertBlock();
379 for (
auto I = NewBB->rbegin(); I != NewBB->rend(); I++) {
380 Instruction *NewInst = &*I;
382 if (!isInstructionTriviallyDead(NewInst))
385 BBMap.remove_if([&](
const auto &
Pair) {
return Pair.second == NewInst; });
387 NewInst->eraseFromParent();
395 "Only block statements can be copied by the block generator");
400 copyBB(Stmt, BB, BBMap, LTS, NewAccesses);
405 BasicBlock *CopyBB = SplitBlock(
Builder.GetInsertBlock(),
407 CopyBB->setName(
"polly.stmt." + BB->getName());
413 isl_id_to_ast_expr *NewAccesses) {
414 BasicBlock *CopyBB =
splitBB(BB);
415 Builder.SetInsertPoint(CopyBB->begin());
419 copyBB(Stmt, BB, CopyBB, BBMap, LTS, NewAccesses);
429 ScalarEvolution *
GenSE) {
432 GenFn ==
GenLI->getTopLevelLoops().front()->getHeader()->getParent());
440 isl_id_to_ast_expr *NewAccesses) {
450 for (Instruction &Inst : *BB)
461 assert(!
Array->isArrayKind() &&
"Trying to get alloca for array kind");
489 Type *Ty =
Array->getElementType();
492 if (
Array->isPHIKind())
497 const DataLayout &DL =
Builder.getDataLayout();
500 new AllocaInst(Ty, DL.getAllocaAddrSpace(),
nullptr,
501 DL.getPrefTypeAlign(Ty), ScalarBase->getName() + NameExt);
502 BasicBlock *EntryBB = &
Builder.GetInsertBlock()->getParent()->getEntryBlock();
503 Addr->insertBefore(EntryBB->getFirstInsertionPt());
509 Instruction *Inst = cast<Instruction>(
Array->getBasePtr());
518 for (User *U : Inst->users()) {
521 Instruction *UI = dyn_cast<Instruction>(U);
528 EscapeUsers.push_back(UI);
532 if (EscapeUsers.empty())
539 EscapeMap[Inst] = std::make_pair(ScalarAddr, std::move(EscapeUsers));
546 if (MA->isOriginalArrayKind() || MA->isWrite())
557 auto AccDom = MA->getAccessRelation().domain();
558 assert(!StmtDom.is_subset(AccDom).is_false() &&
559 "Scalar must be loaded in all statement instances");
564 BBMap[MA->getAccessValue()] =
Builder.CreateLoad(
565 MA->getElementType(), Address, Address->getName() +
".reload");
583 isl::ast_build RestrictedBuild = AstBuild.restrict(ScheduledDomain);
587 IsInSetExpr =
Builder.CreateICmpNE(
588 IsInSetExpr, ConstantInt::get(IsInSetExpr->getType(), 0));
595 const std::function<
void()> &GenThenFunc) {
600 bool IsPartialWrite =
603 if (!IsPartialWrite) {
613 if (
auto *Const = dyn_cast<ConstantInt>(Cond))
617 BasicBlock *HeadBlock =
Builder.GetInsertBlock();
618 StringRef BlockName = HeadBlock->getName();
621 DomTreeUpdater DTU(
GenDT, DomTreeUpdater::UpdateStrategy::Eager);
622 SplitBlockAndInsertIfThen(Cond,
Builder.GetInsertPoint(),
false,
nullptr,
624 CondBrInst *Branch = cast<CondBrInst>(HeadBlock->getTerminator());
625 BasicBlock *ThenBlock = Branch->getSuccessor(0);
626 BasicBlock *TailBlock = Branch->getSuccessor(1);
629 if (
auto *CondInst = dyn_cast<Instruction>(Cond))
630 CondInst->setName(
"polly." + Subject +
".cond");
631 ThenBlock->setName(BlockName +
"." + Subject +
".partial");
632 TailBlock->setName(BlockName +
".cont");
636 Builder.SetInsertPoint(ThenBlock->getFirstInsertionPt());
638 Builder.SetInsertPoint(TailBlock->getFirstInsertionPt());
643 raw_string_ostream OS(Result);
644 Val->printAsOperand(OS,
false);
662 "The stmt must have a valid instance");
669 SmallVector<llvm::Value *, 8> Values;
687 DenseSet<Instruction *> Encountered;
692 for (Instruction *Inst : Stmt.
insts()) {
696 if (isa<PHINode>(Inst)) {
701 Values.push_back(
getNewValue(Stmt, Inst, BBMap, LTS,
702 LI.getLoopFor(Inst->getParent())));
704 for (
Value *Op : Inst->operand_values()) {
707 auto *OpInst = dyn_cast<Instruction>(Op);
710 if (!
S->contains(OpInst))
715 if (Encountered.count(OpInst))
724 Values.push_back(
getNewValue(Stmt, OpInst, BBMap, LTS,
725 LI.getLoopFor(Inst->getParent())));
726 Encountered.insert(OpInst);
730 Encountered.insert(Inst);
747 "Region statements need to use the generateScalarStores() function in "
748 "the RegionGenerator");
751 if (MA->isOriginalArrayKind() || MA->isRead())
754 isl::set AccDom = MA->getAccessRelation().domain();
755 std::string Subject = MA->getId().get_name();
758 Stmt, AccDom, Subject.c_str(), [&,
this, MA]() {
759 Value *Val = MA->getAccessValue();
760 if (MA->isAnyPHIKind()) {
761 assert(MA->getIncoming().size() >= 1 &&
762 "Block statements have exactly one exiting block, or "
764 "with same incoming block and value");
765 assert(std::all_of(MA->getIncoming().begin(),
766 MA->getIncoming().end(),
767 [&](std::pair<BasicBlock *, Value *> p) -> bool {
768 return p.first == Stmt.getBasicBlock();
770 "Incoming block must be statement's block");
771 Val = MA->getIncoming()[0].second;
777 assert((!isa<Instruction>(Val) ||
778 GenDT->dominates(cast<Instruction>(Val)->getParent(),
780 "Domination violation");
781 assert((!isa<Instruction>(Address) ||
782 GenDT->dominates(cast<Instruction>(Address)->getParent(),
784 "Domination violation");
786 Builder.CreateStore(Val, Address);
792 BasicBlock *ExitBB =
S.getExit();
793 BasicBlock *PreEntryBB =
S.getEnteringBlock();
797 for (
auto &
Array :
S.arrays()) {
798 if (
Array->getNumberOfDimensions() != 0)
800 if (
Array->isPHIKind()) {
805 auto PHI = cast<PHINode>(
Array->getBasePtr());
807 for (
auto BI =
PHI->block_begin(), BE =
PHI->block_end(); BI != BE; BI++)
808 if (!
S.contains(*BI) && *BI != PreEntryBB)
809 llvm_unreachable(
"Incoming edges from outside the scop should always "
810 "come from PreEntryBB");
812 int Idx =
PHI->getBasicBlockIndex(PreEntryBB);
816 Value *ScalarValue =
PHI->getIncomingValue(Idx);
822 auto *Inst = dyn_cast<Instruction>(
Array->getBasePtr());
824 if (Inst &&
S.contains(Inst))
831 if (
auto *
PHI = dyn_cast_or_null<PHINode>(Inst))
832 if (!
S.hasSingleExitEdge() &&
PHI->getBasicBlockIndex(ExitBB) >= 0)
841 BasicBlock *ExitBB =
S.getExitingBlock();
843 BasicBlock *MergeBB =
S.getExit();
846 BasicBlock *OptExitBB = *(pred_begin(MergeBB));
847 if (OptExitBB == ExitBB)
848 OptExitBB = *(++pred_begin(MergeBB));
850 Builder.SetInsertPoint(OptExitBB->getTerminator()->getIterator());
851 for (
const auto &EscapeMapping :
EscapeMap) {
854 Instruction *EscapeInst = EscapeMapping.first;
855 const auto &EscapeMappingValue = EscapeMapping.second;
857 auto *ScalarAddr = cast<AllocaInst>(&*EscapeMappingValue.first);
860 Value *EscapeInstReload =
861 Builder.CreateLoad(ScalarAddr->getAllocatedType(), ScalarAddr,
862 EscapeInst->getName() +
".final_reload");
864 Builder.CreateBitOrPointerCast(EscapeInstReload, EscapeInst->getType());
867 PHINode *MergePHI = PHINode::Create(EscapeInst->getType(), 2,
868 EscapeInst->getName() +
".merge");
869 MergePHI->insertBefore(MergeBB->getFirstInsertionPt());
872 MergePHI->addIncoming(EscapeInstReload, OptExitBB);
873 MergePHI->addIncoming(EscapeInst, ExitBB);
877 if (
SE.isSCEVable(EscapeInst->getType()))
878 SE.forgetValue(EscapeInst);
881 for (Instruction *EUser : EscapeUsers)
882 EUser->replaceUsesOfWith(EscapeInst, MergePHI);
887 for (
auto &
Array :
S.arrays()) {
889 if (
Array->getNumberOfDimensions() != 0)
892 if (
Array->isPHIKind())
895 auto *Inst = dyn_cast<Instruction>(
Array->getBasePtr());
903 if (!
S.contains(Inst))
911 if (
S.hasSingleExitEdge())
914 auto *ExitBB =
S.getExitingBlock();
915 auto *MergeBB =
S.getExit();
916 auto *AfterMergeBB = MergeBB->getSingleSuccessor();
917 BasicBlock *OptExitBB = *(pred_begin(MergeBB));
918 if (OptExitBB == ExitBB)
919 OptExitBB = *(++pred_begin(MergeBB));
921 Builder.SetInsertPoint(OptExitBB->getTerminator()->getIterator());
923 for (
auto &SAI :
S.arrays()) {
924 auto *Val = SAI->getBasePtr();
930 if (!SAI->isExitPHIKind())
933 PHINode *
PHI = dyn_cast<PHINode>(Val);
937 if (
PHI->getParent() != AfterMergeBB)
940 std::string Name =
PHI->getName().str();
942 Value *Reload =
Builder.CreateLoad(SAI->getElementType(), ScalarAddr,
943 Name +
".ph.final_reload");
944 Reload =
Builder.CreateBitOrPointerCast(Reload,
PHI->getType());
945 Value *OriginalValue =
PHI->getIncomingValueForBlock(MergeBB);
946 assert((!isa<Instruction>(OriginalValue) ||
947 cast<Instruction>(OriginalValue)->getParent() != MergeBB) &&
948 "Original value must no be one we just generated.");
949 auto *MergePHI = PHINode::Create(
PHI->getType(), 2, Name +
".ph.merge");
950 MergePHI->insertBefore(MergeBB->getFirstInsertionPt());
951 MergePHI->addIncoming(Reload, OptExitBB);
952 MergePHI->addIncoming(OriginalValue, ExitBB);
953 int Idx =
PHI->getBasicBlockIndex(MergeBB);
954 PHI->setIncomingValue(Idx, MergePHI);
960 if (Stmt.isCopyStmt())
962 else if (Stmt.isBlockStmt())
963 for (
auto &Inst : *Stmt.getBasicBlock())
964 SE.forgetValue(&Inst);
965 else if (Stmt.isRegionStmt())
966 for (
auto *BB : Stmt.getRegion()->blocks())
967 for (
auto &Inst : *BB)
968 SE.forgetValue(&Inst);
970 llvm_unreachable(
"Unexpected statement type found");
973 for (
const auto &EscapeMapping :
EscapeMap) {
975 for (Instruction *EUser : EscapeUsers) {
976 if (Loop *L =
LI.getLoopFor(EUser->getParent()))
979 L = L->getParentLoop();
994 BasicBlock *BBCopy) {
996 BasicBlock *BBIDom =
DT.getNode(BB)->getIDom()->getBlock();
997 BasicBlock *BBCopyIDom =
EndBlockMap.lookup(BBIDom);
1000 GenDT->changeImmediateDominator(BBCopy, BBCopyIDom);
1015 for (
auto ExitingBB : predecessors(R->getExit())) {
1017 if (!R->contains(ExitingBB))
1020 if (!DT.dominates(BB, ExitingBB))
1030 BasicBlock *Common =
nullptr;
1031 for (
auto ExitingBB : predecessors(R->getExit())) {
1033 if (!R->contains(ExitingBB))
1042 Common = DT.findNearestCommonDominator(Common, ExitingBB);
1045 assert(Common && R->contains(Common));
1052 "Only region statements can be copied by the region generator");
1068 BasicBlock *EntryBB = R->getEntry();
1069 BasicBlock *EntryBBCopy = SplitBlock(
Builder.GetInsertBlock(),
1071 EntryBBCopy->setName(
"polly.stmt." + EntryBB->getName() +
".entry");
1072 Builder.SetInsertPoint(EntryBBCopy->begin());
1078 for (
auto PI = pred_begin(EntryBB), PE = pred_end(EntryBB); PI != PE; ++PI)
1079 if (!R->contains(*PI)) {
1085 std::deque<BasicBlock *> Blocks;
1086 SmallSetVector<BasicBlock *, 8> SeenBlocks;
1087 Blocks.push_back(EntryBB);
1088 SeenBlocks.insert(EntryBB);
1090 while (!Blocks.empty()) {
1091 BasicBlock *BB = Blocks.front();
1095 BasicBlock *BBCopy =
splitBB(BB);
1107 InitBBMap = &EntryBBMap;
1108 auto Inserted =
RegionMaps.insert(std::make_pair(BBCopy, *InitBBMap));
1109 ValueMapT &RegionMap = Inserted.first->second;
1112 Builder.SetInsertPoint(BBCopy->begin());
1113 copyBB(Stmt, BB, BBCopy, RegionMap, LTS, IdToAstExp);
1121 addOperandToPHI(Stmt, PHINodePair.first, PHINodePair.second, BB, LTS);
1125 for (
auto SI = succ_begin(BB),
SE = succ_end(BB); SI !=
SE; SI++)
1126 if (R->contains(*SI) && SeenBlocks.insert(*SI))
1127 Blocks.push_back(*SI);
1131 ValueMap.insert_range(RegionMap);
1135 BasicBlock *ExitBBCopy = SplitBlock(
Builder.GetInsertBlock(),
1137 ExitBBCopy->setName(
"polly.stmt." + R->getExit()->getName() +
".exit");
1143 "Common exit dominator must be within region; at least the entry node "
1145 GenDT->changeImmediateDominator(ExitBBCopy, ExitDomBBCopy);
1149 for (BasicBlock *BB : SeenBlocks) {
1153 Instruction *TI = BB->getTerminator();
1154 if (isa<UnreachableInst>(TI)) {
1155 while (!BBCopyEnd->empty())
1156 BBCopyEnd->begin()->eraseFromParent();
1157 new UnreachableInst(BBCopyEnd->getContext(), BBCopyEnd);
1161 Instruction *BICopy = BBCopyEnd->getTerminator();
1166 Builder.SetInsertPoint(BICopy->getIterator());
1168 BICopy->eraseFromParent();
1173 for (BasicBlock *BB : SeenBlocks) {
1174 Loop *L =
LI.getLoopFor(BB);
1175 if (L ==
nullptr || L->getHeader() != BB || !R->contains(L))
1181 PHINode::Create(
Builder.getInt32Ty(), 2,
"polly.subregion.iv");
1182 Instruction *LoopPHIInc = BinaryOperator::CreateAdd(
1183 LoopPHI,
Builder.getInt32(1),
"polly.subregion.iv.inc");
1184 LoopPHI->insertBefore(BBCopy->begin());
1185 LoopPHIInc->insertBefore(BBCopy->getTerminator()->getIterator());
1187 for (
auto *PredBB : predecessors(BB)) {
1188 if (!R->contains(PredBB))
1190 if (L->contains(PredBB))
1191 LoopPHI->addIncoming(LoopPHIInc,
EndBlockMap[PredBB]);
1193 LoopPHI->addIncoming(NullVal,
EndBlockMap[PredBB]);
1196 for (
auto *PredBBCopy : predecessors(BBCopy))
1197 if (LoopPHI->getBasicBlockIndex(PredBBCopy) < 0)
1198 LoopPHI->addIncoming(NullVal, PredBBCopy);
1200 LTS[L] =
SE.getUnknown(LoopPHI);
1204 Builder.SetInsertPoint(ExitBBCopy->getFirstInsertionPt());
1220 PollyIRBuilder::InsertPointGuard IPGuard(
Builder);
1222 BasicBlock *NewSubregionExit =
Builder.GetInsertBlock();
1226 if (OrigPHI->getParent() != SubR->getExit()) {
1227 BasicBlock *FormerExit = SubR->getExitingBlock();
1232 PHINode *NewPHI = PHINode::Create(OrigPHI->getType(), Incoming.size(),
1233 "polly." + OrigPHI->getName(),
1234 NewSubregionExit->getFirstNonPHIIt());
1237 for (
auto &
Pair : Incoming) {
1238 BasicBlock *OrigIncomingBlock =
Pair.first;
1239 BasicBlock *NewIncomingBlockStart =
StartBlockMap.lookup(OrigIncomingBlock);
1240 BasicBlock *NewIncomingBlockEnd =
EndBlockMap.lookup(OrigIncomingBlock);
1241 Builder.SetInsertPoint(NewIncomingBlockEnd->getTerminator()->getIterator());
1247 Value *NewIncomingValue =
1248 getNewValue(*Stmt, OrigIncomingValue, *LocalBBMap, LTS, L);
1249 NewPHI->addIncoming(NewIncomingValue, NewIncomingBlockEnd);
1260 Loop *L =
LI.getLoopFor(Stmt->
getRegion()->getExit());
1264 assert(!Incoming.empty() &&
1265 "PHI WRITEs must have originate from at least one incoming block");
1268 if (Incoming.size() == 1) {
1269 Value *OldVal = Incoming[0].second;
1284 __isl_keep isl_id_to_ast_expr *NewAccesses) {
1286 "Block statements need to use the generateScalarStores() "
1287 "function in the BlockGenerator");
1296 SmallDenseMap<MemoryAccess *, Value *> NewExitScalars;
1298 if (MA->isOriginalArrayKind() || MA->isRead())
1302 NewExitScalars[MA] = NewVal;
1306 if (MA->isOriginalArrayKind() || MA->isRead())
1309 isl::set AccDom = MA->getAccessRelation().domain();
1310 std::string Subject = MA->getId().get_name();
1312 Stmt, AccDom, Subject.c_str(), [&,
this, MA]() {
1313 Value *NewVal = NewExitScalars.lookup(MA);
1314 assert(NewVal &&
"The exit scalar must be determined before");
1315 Value *Address = getImplicitAddress(*MA, getLoopForStmt(Stmt), LTS,
1316 BBMap, NewAccesses);
1317 assert((!isa<Instruction>(NewVal) ||
1318 GenDT->dominates(cast<Instruction>(NewVal)->getParent(),
1319 Builder.GetInsertBlock())) &&
1320 "Domination violation");
1321 assert((!isa<Instruction>(Address) ||
1322 GenDT->dominates(cast<Instruction>(Address)->getParent(),
1323 Builder.GetInsertBlock())) &&
1324 "Domination violation");
1325 Builder.CreateStore(NewVal, Address);
1331 PHINode *PHICopy, BasicBlock *IncomingBB,
1340 "Bad incoming block for PHI in non-affine region");
1346 "Incoming PHI block did not have a BBMap");
1349 Value *OpCopy =
nullptr;
1352 Value *Op =
PHI->getIncomingValueForBlock(IncomingBB);
1356 auto IP =
Builder.GetInsertPoint();
1357 if (IP->getParent() != BBCopyEnd)
1358 Builder.SetInsertPoint(BBCopyEnd->getTerminator()->getIterator());
1360 if (IP->getParent() != BBCopyEnd)
1367 if (PHICopy->getBasicBlockIndex(BBCopyEnd) >= 0)
1374 assert(OpCopy &&
"Incoming PHI value was not copied properly");
1375 PHICopy->addIncoming(OpCopy, BBCopyEnd);
1381 unsigned NumIncoming =
PHI->getNumIncomingValues();
1383 Builder.CreatePHI(
PHI->getType(), NumIncoming,
"polly." +
PHI->getName());
1384 PHICopy->moveBefore(PHICopy->getParent()->getFirstNonPHIIt());
1385 BBMap[
PHI] = PHICopy;
1387 for (BasicBlock *IncomingBB :
PHI->blocks())
static cl::opt< bool > Aligned("enable-polly-aligned", cl::desc("Assumed aligned memory accesses."), cl::Hidden, cl::cat(PollyCategory))
static bool isDominatingSubregionExit(const DominatorTree &DT, Region *R, BasicBlock *BB)
static BasicBlock * findExitDominator(DominatorTree &DT, Region *R)
static cl::opt< bool, true > TraceStmtsX("polly-codegen-trace-stmts", cl::desc("Add printf calls that print the statement being executed"), cl::location(TraceStmts), cl::Hidden, cl::cat(PollyCategory))
static cl::opt< bool, true > DebugPrintingX("polly-codegen-add-debug-printing", cl::desc("Add printf calls that show the values loaded/stored."), cl::location(PollyDebugPrinting), cl::Hidden, cl::cat(PollyCategory))
static std::string getInstName(Value *Val)
static cl::opt< bool > TraceScalars("polly-codegen-trace-scalars", cl::desc("Add printf calls that print the values of all scalar values " "used in a statement. Requires -polly-codegen-trace-stmts."), cl::Hidden, cl::cat(PollyCategory))
llvm::cl::OptionCategory PollyCategory
__isl_give isl_ast_expr * isl_ast_expr_address_of(__isl_take isl_ast_expr *expr)
isl::checked::union_map get_schedule() const
isl::checked::ast_expr expr_from(isl::checked::pw_aff pa) const
__isl_give isl_ast_expr * copy() const &
__isl_give isl_id * release()
std::string get_name() const
isl::checked::map reverse() const
isl::checked::set range() const
isl::checked::set domain() const
isl::checked::pw_aff at(int pos) const
isl::checked::set intersect_params(isl::checked::set params) const
boolean is_subset(const isl::checked::set &set2) const
isl::checked::set apply(isl::checked::map map) const
isl::checked::union_map intersect_domain(isl::checked::space space) const
static isl::map from_union_map(isl::union_map umap)
static isl::pw_multi_aff from_map(isl::map map)
Loop * getLoopForStmt(const ScopStmt &Stmt) const
Get the innermost loop that surrounds the statement Stmt.
EscapeUsersAllocaMapTy & EscapeMap
Map from instructions to their escape users as well as the alloca.
Value * getImplicitAddress(MemoryAccess &Access, Loop *L, LoopToScevMapT <S, ValueMapT &BBMap, __isl_keep isl_id_to_ast_expr *NewAccesses)
Generate the pointer value that is accesses by Access.
DominatorTree & DT
The dominator tree of this function.
BasicBlock * splitBB(BasicBlock *BB)
Split BB to create a new one we can use to clone BB in.
void generateBeginStmtTrace(ScopStmt &Stmt, LoopToScevMapT <S, ValueMapT &BBMap)
When statement tracing is enabled, build the print instructions for printing the current statement in...
Value * trySynthesizeNewValue(ScopStmt &Stmt, Value *Old, ValueMapT &BBMap, LoopToScevMapT <S, Loop *L) const
Try to synthesize a new value.
void generateScalarLoads(ScopStmt &Stmt, LoopToScevMapT <S, ValueMapT &BBMap, __isl_keep isl_id_to_ast_expr *NewAccesses)
Generate reload of scalars demoted to memory and needed by Stmt.
AllocaMapTy & ScalarMap
Map to resolve scalar dependences for PHI operands and scalars.
DenseMap< const ScopArrayInfo *, AssertingVH< AllocaInst > > AllocaMapTy
Map types to resolve scalar dependences.
void createExitPHINodeMerges(Scop &S)
Create exit PHI node merges for PHI nodes with more than two edges from inside the scop.
void copyInstScalar(ScopStmt &Stmt, Instruction *Inst, ValueMapT &BBMap, LoopToScevMapT <S)
Value * generateArrayLoad(ScopStmt &Stmt, LoadInst *load, ValueMapT &BBMap, LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses)
Value * buildContainsCondition(ScopStmt &Stmt, const isl::set &Subdomain)
Generate instructions that compute whether one instance of Set is executed.
void finalizeSCoP(Scop &S)
Finalize the code generation for the SCoP S.
void createScalarInitialization(Scop &S)
Initialize the memory of demoted scalars.
SmallVector< Instruction *, 4 > EscapeUserVectorTy
Simple vector of instructions to store escape users.
bool canSyntheziseInStmt(ScopStmt &Stmt, Instruction *Inst)
Helper to determine if Inst can be synthesized in Stmt.
virtual void generateScalarStores(ScopStmt &Stmt, LoopToScevMapT <S, ValueMapT &BBMap, __isl_keep isl_id_to_ast_expr *NewAccesses)
Generate the scalar stores for the given statement.
IslExprBuilder * ExprBuilder
void handleOutsideUsers(const Scop &S, ScopArrayInfo *Array)
Handle users of Array outside the SCoP.
void createScalarFinalization(Scop &S)
Promote the values of demoted scalars after the SCoP.
void switchGeneratedFunc(Function *GenFn, DominatorTree *GenDT, LoopInfo *GenLI, ScalarEvolution *GenSE)
Change the function that code is emitted into.
Value * getNewValue(ScopStmt &Stmt, Value *Old, ValueMapT &BBMap, LoopToScevMapT <S, Loop *L) const
Get the new version of a value.
ValueMapT & GlobalMap
A map from llvm::Values referenced in the old code to a new set of llvm::Values, which is used to rep...
void findOutsideUsers(Scop &S)
Find scalar statements that have outside users.
void generateArrayStore(ScopStmt &Stmt, StoreInst *store, ValueMapT &BBMap, LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses)
DominatorTree * GenDT
Relates to the region where the code is emitted into.
MapVector< Instruction *, std::pair< AssertingVH< Value >, EscapeUserVectorTy > > EscapeUsersAllocaMapTy
Map type to resolve escaping users for scalar instructions.
BasicBlock * copyBB(ScopStmt &Stmt, BasicBlock *BB, ValueMapT &BBMap, LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses)
Copy the given basic block.
virtual void copyPHIInstruction(ScopStmt &, PHINode *, ValueMapT &, LoopToScevMapT &)
Copy a single PHI instruction.
void copyStmt(ScopStmt &Stmt, LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses)
Copy the basic block.
BasicBlock * StartBlock
The first basic block after the RTC.
void copyInstruction(ScopStmt &Stmt, Instruction *Inst, ValueMapT &BBMap, LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses)
Copy a single Instruction.
void invalidateScalarEvolution(Scop &S)
Invalidate the scalar evolution expressions for a scop.
BlockGenerator(PollyIRBuilder &Builder, LoopInfo &LI, ScalarEvolution &SE, DominatorTree &DT, AllocaMapTy &ScalarMap, EscapeUsersAllocaMapTy &EscapeMap, ValueMapT &GlobalMap, IslExprBuilder *ExprBuilder, BasicBlock *StartBlock)
Create a generator for basic blocks.
void removeDeadInstructions(BasicBlock *BB, ValueMapT &BBMap)
Remove dead instructions generated for BB.
Value * generateLocationAccessed(ScopStmt &Stmt, MemAccInst Inst, ValueMapT &BBMap, LoopToScevMapT <S, isl_id_to_ast_expr *NewAccesses)
Generate the operand address.
Value * getOrCreateAlloca(const MemoryAccess &Access)
Return the alloca for Access.
void generateConditionalExecution(ScopStmt &Stmt, const isl::set &Subdomain, StringRef Subject, const std::function< void()> &GenThenFunc)
Generate code that executes in a subset of Stmt's domain.
LLVM-IR generator for isl_ast_expr[essions].
Utility proxy to wrap the common members of LoadInst and StoreInst.
llvm::Value * getPointerOperand() const
Represent memory accesses in statements.
const ScopArrayInfo * getLatestScopArrayInfo() const
Get the ScopArrayInfo object for the base address, or the one set by setNewAccessRelation().
bool isAnyPHIKind() const
Old name of isOriginalAnyPHIKind().
bool isLatestArrayKind() const
Whether storage memory is either an custom .s2a/.phiops alloca (false) or an existing pointer into an...
Instruction * getAccessInstruction() const
Return the access instruction of this memory access.
isl::id getId() const
Get identifier for the memory access.
ArrayRef< std::pair< BasicBlock *, Value * > > getIncoming() const
Return the list of possible PHI/ExitPHI values.
ScopStmt * getStatement() const
Get the statement that contains this memory access.
isl::map getAccessRelation() const
Old name of getLatestAccessRelation().
Value * getAccessValue() const
Return the access value of this memory access.
std::pair< PHINode *, PHINode * > PHINodePairTy
Mapping to remember PHI nodes that still need incoming values.
void copyStmt(ScopStmt &Stmt, LoopToScevMapT <S, __isl_keep isl_id_to_ast_expr *IdToAstExp)
Copy the region statement Stmt.
DenseMap< BasicBlock *, SmallVector< PHINodePairTy, 4 > > IncompletePHINodeMap
void addOperandToPHI(ScopStmt &Stmt, PHINode *PHI, PHINode *PHICopy, BasicBlock *IncomingBB, LoopToScevMapT <S)
Add the new operand from the copy of IncomingBB to PHICopy.
void copyPHIInstruction(ScopStmt &Stmt, PHINode *Inst, ValueMapT &BBMap, LoopToScevMapT <S) override
Copy a single PHI instruction.
DenseMap< BasicBlock *, BasicBlock * > EndBlockMap
A map from old to the last new block in the region, that was created to model the old basic block.
Value * getExitScalar(MemoryAccess *MA, LoopToScevMapT <S, ValueMapT &BBMap)
DenseMap< BasicBlock *, BasicBlock * > StartBlockMap
A map from old to the first new block in the region, that was created to model the old basic block.
void generateScalarStores(ScopStmt &Stmt, LoopToScevMapT <S, ValueMapT &BBMAp, __isl_keep isl_id_to_ast_expr *NewAccesses) override
Generate the scalar stores for the given statement.
DenseMap< BasicBlock *, ValueMapT > RegionMaps
The "BBMaps" for the whole region (one for each block).
PHINode * buildExitPHI(MemoryAccess *MA, LoopToScevMapT <S, ValueMapT &BBMap, Loop *L)
Create a PHI that combines the incoming values from all incoming blocks that are in the subregion.
BasicBlock * repairDominance(BasicBlock *BB, BasicBlock *BBCopy)
Repair the dominance tree after we created a copy block for BB.
A class to store information about arrays in the SCoP.
MemoryAccess & getArrayAccessFor(const Instruction *Inst) const
Return the only array access for Inst.
BasicBlock * getEntryBlock() const
Return a BasicBlock from this statement.
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).
bool represents(BasicBlock *BB) const
Return whether this statement represents BB.
iterator_range< std::vector< Instruction * >::const_iterator > insts() const
The range of instructions in this statement.
BasicBlock * getBasicBlock() const
Get the BasicBlock represented by this ScopStmt (if any).
const char * getBaseName() const
isl::ast_build getAstBuild() const
Get the isl AST build.
MemoryAccess * getArrayAccessOrNULLFor(const Instruction *Inst) const
Return the only array access for Inst, if existing.
bool isRegionStmt() const
Return true if this statement represents a whole region.
isl::set getDomain() const
Get the iteration domain of this ScopStmt.
isl::set getBestKnownDefinedBehaviorContext() const
Return the define behavior context, or if not available, its approximation from all other contexts.
isl::set getContext() const
Get the constraint on parameter of this Scop.
static VirtualUse create(Scop *S, const Use &U, LoopInfo *LI, bool Virtual)
Get a VirtualUse for an llvm::Use.
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.
@ Array
MemoryKind::Array: Models a one or multi-dimensional array.
@ Value
MemoryKind::Value: Models an llvm::Value.
@ PHI
MemoryKind::PHI: Models PHI nodes within the SCoP.
llvm::iota_range< unsigned > rangeIslSize(unsigned Begin, isl::size End)
Check that End is valid and return an iterator from Begin to End.
llvm::IRBuilder< llvm::ConstantFolder, IRInserter > PollyIRBuilder
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.
bool isIgnoredIntrinsic(const llvm::Value *V)
Return true iff V is an intrinsic that we ignore during code generation.
bool canSynthesize(const llvm::Value *V, const Scop &S, llvm::ScalarEvolution *SE, llvm::Loop *Scope)
Check whether a value an be synthesized by the code generator.
static void createCPUPrinter(PollyIRBuilder &Builder, Args... args)
Print a set of LLVM-IR Values or StringRefs via printf.
static bool isPrintable(llvm::Type *Ty)
Return whether an llvm::Value of the type Ty is printable for debugging.
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")