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!");
219 if (isa<DbgInfoIntrinsic>(Inst))
222 Instruction *NewInst = Inst->clone();
225 for (
Value *OldOperand : Inst->operands()) {
230 assert(!isa<StoreInst>(NewInst) &&
231 "Store instructions are always needed!");
232 NewInst->deleteValue();
238 NewInst->replaceUsesOfWith(OldOperand, NewOperand);
242 BBMap[Inst] = NewInst;
244 assert(NewInst->getModule() == Inst->getModule() &&
245 "Expecting instructions to be in the same module");
247 if (!NewInst->getType()->isVoidTy())
248 NewInst->setName(
"p_" + Inst->getName());
254 isl_id_to_ast_expr *NewAccesses) {
265 Type *ExpectedType) {
266 isl_ast_expr *AccessExpr = isl_id_to_ast_expr_get(NewAccesses, Id);
274 "If expression was not generated, must use the original pointer value");
292 return LI.getLoopFor(StmtBB);
297 isl_id_to_ast_expr *NewAccesses) {
304 Builder.CreateAlignedLoad(Load->getType(), NewPointer, Load->getAlign(),
305 Load->getName() +
"_p_scalar_");
309 ": ", ScalarLoad,
"\n");
316 isl_id_to_ast_expr *NewAccesses) {
323 generateLocationAccessed(Stmt, Store, BBMap, LTS, NewAccesses);
324 Value *ValueOperand = getNewValue(Stmt, Store->getValueOperand(), BBMap,
325 LTS, getLoopForStmt(Stmt));
327 if (PollyDebugPrinting)
328 RuntimeDebugBuilder::createCPUPrinter(Builder,
"Store to ", NewPointer,
329 ": ", ValueOperand,
"\n");
331 Builder.CreateAlignedStore(ValueOperand, NewPointer, Store->getAlign());
343 isl_id_to_ast_expr *NewAccesses) {
346 if (Inst->isTerminator())
353 if (
auto *Load = dyn_cast<LoadInst>(Inst)) {
357 BBMap[Load] = NewLoad;
361 if (
auto *Store = dyn_cast<StoreInst>(Inst)) {
370 if (
auto *
PHI = dyn_cast<PHINode>(Inst)) {
384 auto NewBB =
Builder.GetInsertBlock();
385 for (
auto I = NewBB->rbegin(); I != NewBB->rend(); I++) {
386 Instruction *NewInst = &*I;
388 if (!isInstructionTriviallyDead(NewInst))
391 for (
auto Pair : BBMap)
392 if (
Pair.second == NewInst) {
393 BBMap.erase(
Pair.first);
396 NewInst->eraseFromParent();
404 "Only block statements can be copied by the block generator");
409 copyBB(Stmt, BB, BBMap, LTS, NewAccesses);
414 BasicBlock *CopyBB = SplitBlock(
Builder.GetInsertBlock(),
416 CopyBB->setName(
"polly.stmt." + BB->getName());
422 isl_id_to_ast_expr *NewAccesses) {
423 BasicBlock *CopyBB =
splitBB(BB);
424 Builder.SetInsertPoint(CopyBB, CopyBB->begin());
428 copyBB(Stmt, BB, CopyBB, BBMap, LTS, NewAccesses);
438 ScalarEvolution *
GenSE) {
441 GenFn ==
GenLI->getTopLevelLoops().front()->getHeader()->getParent());
449 isl_id_to_ast_expr *NewAccesses) {
459 for (Instruction &Inst : *BB)
470 assert(!
Array->isArrayKind() &&
"Trying to get alloca for array kind");
498 Type *Ty =
Array->getElementType();
501 if (
Array->isPHIKind())
506 const DataLayout &DL =
Builder.GetInsertBlock()->getDataLayout();
509 new AllocaInst(Ty, DL.getAllocaAddrSpace(),
nullptr,
510 DL.getPrefTypeAlign(Ty), ScalarBase->getName() + NameExt);
511 BasicBlock *EntryBB = &
Builder.GetInsertBlock()->getParent()->getEntryBlock();
512 Addr->insertBefore(EntryBB->getFirstInsertionPt());
518 Instruction *Inst = cast<Instruction>(
Array->getBasePtr());
527 for (User *U : Inst->users()) {
530 Instruction *UI = dyn_cast<Instruction>(U);
537 EscapeUsers.push_back(UI);
541 if (EscapeUsers.empty())
548 EscapeMap[Inst] = std::make_pair(ScalarAddr, std::move(EscapeUsers));
555 if (MA->isOriginalArrayKind() || MA->isWrite())
561 auto AccDom = MA->getAccessRelation().domain();
562 assert(!StmtDom.is_subset(AccDom).is_false() &&
563 "Scalar must be loaded in all statement instances");
568 BBMap[MA->getAccessValue()] =
Builder.CreateLoad(
569 MA->getElementType(), Address, Address->getName() +
".reload");
587 isl::ast_build RestrictedBuild = AstBuild.restrict(ScheduledDomain);
591 IsInSetExpr =
Builder.CreateICmpNE(
592 IsInSetExpr, ConstantInt::get(IsInSetExpr->getType(), 0));
599 const std::function<
void()> &GenThenFunc) {
604 bool IsPartialWrite =
607 if (!IsPartialWrite) {
617 if (
auto *Const = dyn_cast<ConstantInt>(Cond))
621 BasicBlock *HeadBlock =
Builder.GetInsertBlock();
622 StringRef BlockName = HeadBlock->getName();
625 DomTreeUpdater DTU(
GenDT, DomTreeUpdater::UpdateStrategy::Eager);
626 SplitBlockAndInsertIfThen(Cond,
Builder.GetInsertPoint(),
false,
nullptr,
628 CondBrInst *Branch = cast<CondBrInst>(HeadBlock->getTerminator());
629 BasicBlock *ThenBlock = Branch->getSuccessor(0);
630 BasicBlock *TailBlock = Branch->getSuccessor(1);
633 if (
auto *CondInst = dyn_cast<Instruction>(Cond))
634 CondInst->setName(
"polly." + Subject +
".cond");
635 ThenBlock->setName(BlockName +
"." + Subject +
".partial");
636 TailBlock->setName(BlockName +
".cont");
640 Builder.SetInsertPoint(ThenBlock, ThenBlock->getFirstInsertionPt());
642 Builder.SetInsertPoint(TailBlock, TailBlock->getFirstInsertionPt());
647 raw_string_ostream OS(Result);
648 Val->printAsOperand(OS,
false);
666 "The stmt must have a valid instance");
673 SmallVector<llvm::Value *, 8> Values;
691 DenseSet<Instruction *> Encountered;
696 for (Instruction *Inst : Stmt.
insts()) {
700 if (isa<PHINode>(Inst)) {
705 Values.push_back(
getNewValue(Stmt, Inst, BBMap, LTS,
706 LI.getLoopFor(Inst->getParent())));
708 for (
Value *Op : Inst->operand_values()) {
711 auto *OpInst = dyn_cast<Instruction>(Op);
714 if (!
S->contains(OpInst))
719 if (Encountered.count(OpInst))
728 Values.push_back(
getNewValue(Stmt, OpInst, BBMap, LTS,
729 LI.getLoopFor(Inst->getParent())));
730 Encountered.insert(OpInst);
734 Encountered.insert(Inst);
751 "Region statements need to use the generateScalarStores() function in "
752 "the RegionGenerator");
755 if (MA->isOriginalArrayKind() || MA->isRead())
758 isl::set AccDom = MA->getAccessRelation().domain();
759 std::string Subject = MA->getId().get_name();
762 Stmt, AccDom, Subject.c_str(), [&,
this, MA]() {
763 Value *Val = MA->getAccessValue();
764 if (MA->isAnyPHIKind()) {
765 assert(MA->getIncoming().size() >= 1 &&
766 "Block statements have exactly one exiting block, or "
768 "with same incoming block and value");
769 assert(std::all_of(MA->getIncoming().begin(),
770 MA->getIncoming().end(),
771 [&](std::pair<BasicBlock *, Value *> p) -> bool {
772 return p.first == Stmt.getBasicBlock();
774 "Incoming block must be statement's block");
775 Val = MA->getIncoming()[0].second;
781 assert((!isa<Instruction>(Val) ||
782 GenDT->dominates(cast<Instruction>(Val)->getParent(),
784 "Domination violation");
785 assert((!isa<Instruction>(Address) ||
786 GenDT->dominates(cast<Instruction>(Address)->getParent(),
788 "Domination violation");
790 Builder.CreateStore(Val, Address);
796 BasicBlock *ExitBB =
S.getExit();
797 BasicBlock *PreEntryBB =
S.getEnteringBlock();
801 for (
auto &
Array :
S.arrays()) {
802 if (
Array->getNumberOfDimensions() != 0)
804 if (
Array->isPHIKind()) {
809 auto PHI = cast<PHINode>(
Array->getBasePtr());
811 for (
auto BI =
PHI->block_begin(), BE =
PHI->block_end(); BI != BE; BI++)
812 if (!
S.contains(*BI) && *BI != PreEntryBB)
813 llvm_unreachable(
"Incoming edges from outside the scop should always "
814 "come from PreEntryBB");
816 int Idx =
PHI->getBasicBlockIndex(PreEntryBB);
820 Value *ScalarValue =
PHI->getIncomingValue(Idx);
826 auto *Inst = dyn_cast<Instruction>(
Array->getBasePtr());
828 if (Inst &&
S.contains(Inst))
835 if (
auto *
PHI = dyn_cast_or_null<PHINode>(Inst))
836 if (!
S.hasSingleExitEdge() &&
PHI->getBasicBlockIndex(ExitBB) >= 0)
845 BasicBlock *ExitBB =
S.getExitingBlock();
847 BasicBlock *MergeBB =
S.getExit();
850 BasicBlock *OptExitBB = *(pred_begin(MergeBB));
851 if (OptExitBB == ExitBB)
852 OptExitBB = *(++pred_begin(MergeBB));
854 Builder.SetInsertPoint(OptExitBB, OptExitBB->getTerminator()->getIterator());
855 for (
const auto &EscapeMapping :
EscapeMap) {
858 Instruction *EscapeInst = EscapeMapping.first;
859 const auto &EscapeMappingValue = EscapeMapping.second;
861 auto *ScalarAddr = cast<AllocaInst>(&*EscapeMappingValue.first);
864 Value *EscapeInstReload =
865 Builder.CreateLoad(ScalarAddr->getAllocatedType(), ScalarAddr,
866 EscapeInst->getName() +
".final_reload");
868 Builder.CreateBitOrPointerCast(EscapeInstReload, EscapeInst->getType());
871 PHINode *MergePHI = PHINode::Create(EscapeInst->getType(), 2,
872 EscapeInst->getName() +
".merge");
873 MergePHI->insertBefore(MergeBB->getFirstInsertionPt());
876 MergePHI->addIncoming(EscapeInstReload, OptExitBB);
877 MergePHI->addIncoming(EscapeInst, ExitBB);
881 if (
SE.isSCEVable(EscapeInst->getType()))
882 SE.forgetValue(EscapeInst);
885 for (Instruction *EUser : EscapeUsers)
886 EUser->replaceUsesOfWith(EscapeInst, MergePHI);
891 for (
auto &
Array :
S.arrays()) {
893 if (
Array->getNumberOfDimensions() != 0)
896 if (
Array->isPHIKind())
899 auto *Inst = dyn_cast<Instruction>(
Array->getBasePtr());
907 if (!
S.contains(Inst))
915 if (
S.hasSingleExitEdge())
918 auto *ExitBB =
S.getExitingBlock();
919 auto *MergeBB =
S.getExit();
920 auto *AfterMergeBB = MergeBB->getSingleSuccessor();
921 BasicBlock *OptExitBB = *(pred_begin(MergeBB));
922 if (OptExitBB == ExitBB)
923 OptExitBB = *(++pred_begin(MergeBB));
925 Builder.SetInsertPoint(OptExitBB, OptExitBB->getTerminator()->getIterator());
927 for (
auto &SAI :
S.arrays()) {
928 auto *Val = SAI->getBasePtr();
934 if (!SAI->isExitPHIKind())
937 PHINode *
PHI = dyn_cast<PHINode>(Val);
941 if (
PHI->getParent() != AfterMergeBB)
944 std::string Name =
PHI->getName().str();
946 Value *Reload =
Builder.CreateLoad(SAI->getElementType(), ScalarAddr,
947 Name +
".ph.final_reload");
948 Reload =
Builder.CreateBitOrPointerCast(Reload,
PHI->getType());
949 Value *OriginalValue =
PHI->getIncomingValueForBlock(MergeBB);
950 assert((!isa<Instruction>(OriginalValue) ||
951 cast<Instruction>(OriginalValue)->getParent() != MergeBB) &&
952 "Original value must no be one we just generated.");
953 auto *MergePHI = PHINode::Create(
PHI->getType(), 2, Name +
".ph.merge");
954 MergePHI->insertBefore(MergeBB->getFirstInsertionPt());
955 MergePHI->addIncoming(Reload, OptExitBB);
956 MergePHI->addIncoming(OriginalValue, ExitBB);
957 int Idx =
PHI->getBasicBlockIndex(MergeBB);
958 PHI->setIncomingValue(Idx, MergePHI);
964 if (Stmt.isCopyStmt())
966 else if (Stmt.isBlockStmt())
967 for (
auto &Inst : *Stmt.getBasicBlock())
968 SE.forgetValue(&Inst);
969 else if (Stmt.isRegionStmt())
970 for (
auto *BB : Stmt.getRegion()->blocks())
971 for (
auto &Inst : *BB)
972 SE.forgetValue(&Inst);
974 llvm_unreachable(
"Unexpected statement type found");
977 for (
const auto &EscapeMapping :
EscapeMap) {
979 for (Instruction *EUser : EscapeUsers) {
980 if (Loop *L =
LI.getLoopFor(EUser->getParent()))
983 L = L->getParentLoop();
998 BasicBlock *BBCopy) {
1000 BasicBlock *BBIDom =
DT.getNode(BB)->getIDom()->getBlock();
1001 BasicBlock *BBCopyIDom =
EndBlockMap.lookup(BBIDom);
1004 GenDT->changeImmediateDominator(BBCopy, BBCopyIDom);
1019 for (
auto ExitingBB : predecessors(R->getExit())) {
1021 if (!R->contains(ExitingBB))
1024 if (!DT.dominates(BB, ExitingBB))
1034 BasicBlock *Common =
nullptr;
1035 for (
auto ExitingBB : predecessors(R->getExit())) {
1037 if (!R->contains(ExitingBB))
1046 Common = DT.findNearestCommonDominator(Common, ExitingBB);
1049 assert(Common && R->contains(Common));
1056 "Only region statements can be copied by the region generator");
1072 BasicBlock *EntryBB = R->getEntry();
1073 BasicBlock *EntryBBCopy = SplitBlock(
Builder.GetInsertBlock(),
1075 EntryBBCopy->setName(
"polly.stmt." + EntryBB->getName() +
".entry");
1076 Builder.SetInsertPoint(EntryBBCopy, EntryBBCopy->begin());
1082 for (
auto PI = pred_begin(EntryBB), PE = pred_end(EntryBB); PI != PE; ++PI)
1083 if (!R->contains(*PI)) {
1089 std::deque<BasicBlock *> Blocks;
1090 SmallSetVector<BasicBlock *, 8> SeenBlocks;
1091 Blocks.push_back(EntryBB);
1092 SeenBlocks.insert(EntryBB);
1094 while (!Blocks.empty()) {
1095 BasicBlock *BB = Blocks.front();
1099 BasicBlock *BBCopy =
splitBB(BB);
1111 InitBBMap = &EntryBBMap;
1112 auto Inserted =
RegionMaps.insert(std::make_pair(BBCopy, *InitBBMap));
1113 ValueMapT &RegionMap = Inserted.first->second;
1116 Builder.SetInsertPoint(BBCopy, BBCopy->begin());
1117 copyBB(Stmt, BB, BBCopy, RegionMap, LTS, IdToAstExp);
1125 addOperandToPHI(Stmt, PHINodePair.first, PHINodePair.second, BB, LTS);
1129 for (
auto SI = succ_begin(BB),
SE = succ_end(BB); SI !=
SE; SI++)
1130 if (R->contains(*SI) && SeenBlocks.insert(*SI))
1131 Blocks.push_back(*SI);
1135 ValueMap.insert_range(RegionMap);
1139 BasicBlock *ExitBBCopy = SplitBlock(
Builder.GetInsertBlock(),
1141 ExitBBCopy->setName(
"polly.stmt." + R->getExit()->getName() +
".exit");
1147 "Common exit dominator must be within region; at least the entry node "
1149 GenDT->changeImmediateDominator(ExitBBCopy, ExitDomBBCopy);
1153 for (BasicBlock *BB : SeenBlocks) {
1157 Instruction *TI = BB->getTerminator();
1158 if (isa<UnreachableInst>(TI)) {
1159 while (!BBCopyEnd->empty())
1160 BBCopyEnd->begin()->eraseFromParent();
1161 new UnreachableInst(BBCopyEnd->getContext(), BBCopyEnd);
1165 Instruction *BICopy = BBCopyEnd->getTerminator();
1170 Builder.SetInsertPoint(BBCopyEnd, BICopy->getIterator());
1172 BICopy->eraseFromParent();
1177 for (BasicBlock *BB : SeenBlocks) {
1178 Loop *L =
LI.getLoopFor(BB);
1179 if (L ==
nullptr || L->getHeader() != BB || !R->contains(L))
1185 PHINode::Create(
Builder.getInt32Ty(), 2,
"polly.subregion.iv");
1186 Instruction *LoopPHIInc = BinaryOperator::CreateAdd(
1187 LoopPHI,
Builder.getInt32(1),
"polly.subregion.iv.inc");
1188 LoopPHI->insertBefore(BBCopy->begin());
1189 LoopPHIInc->insertBefore(BBCopy->getTerminator()->getIterator());
1191 for (
auto *PredBB : predecessors(BB)) {
1192 if (!R->contains(PredBB))
1194 if (L->contains(PredBB))
1195 LoopPHI->addIncoming(LoopPHIInc,
EndBlockMap[PredBB]);
1197 LoopPHI->addIncoming(NullVal,
EndBlockMap[PredBB]);
1200 for (
auto *PredBBCopy : predecessors(BBCopy))
1201 if (LoopPHI->getBasicBlockIndex(PredBBCopy) < 0)
1202 LoopPHI->addIncoming(NullVal, PredBBCopy);
1204 LTS[L] =
SE.getUnknown(LoopPHI);
1208 Builder.SetInsertPoint(ExitBBCopy, ExitBBCopy->getFirstInsertionPt());
1224 PollyIRBuilder::InsertPointGuard IPGuard(
Builder);
1226 BasicBlock *NewSubregionExit =
Builder.GetInsertBlock();
1230 if (OrigPHI->getParent() != SubR->getExit()) {
1231 BasicBlock *FormerExit = SubR->getExitingBlock();
1236 PHINode *NewPHI = PHINode::Create(OrigPHI->getType(), Incoming.size(),
1237 "polly." + OrigPHI->getName(),
1238 NewSubregionExit->getFirstNonPHIIt());
1241 for (
auto &
Pair : Incoming) {
1242 BasicBlock *OrigIncomingBlock =
Pair.first;
1243 BasicBlock *NewIncomingBlockStart =
StartBlockMap.lookup(OrigIncomingBlock);
1244 BasicBlock *NewIncomingBlockEnd =
EndBlockMap.lookup(OrigIncomingBlock);
1245 Builder.SetInsertPoint(NewIncomingBlockEnd,
1246 NewIncomingBlockEnd->getTerminator()->getIterator());
1252 Value *NewIncomingValue =
1253 getNewValue(*Stmt, OrigIncomingValue, *LocalBBMap, LTS, L);
1254 NewPHI->addIncoming(NewIncomingValue, NewIncomingBlockEnd);
1265 Loop *L =
LI.getLoopFor(Stmt->
getRegion()->getExit());
1269 assert(!Incoming.empty() &&
1270 "PHI WRITEs must have originate from at least one incoming block");
1273 if (Incoming.size() == 1) {
1274 Value *OldVal = Incoming[0].second;
1289 __isl_keep isl_id_to_ast_expr *NewAccesses) {
1291 "Block statements need to use the generateScalarStores() "
1292 "function in the BlockGenerator");
1301 SmallDenseMap<MemoryAccess *, Value *> NewExitScalars;
1303 if (MA->isOriginalArrayKind() || MA->isRead())
1307 NewExitScalars[MA] = NewVal;
1311 if (MA->isOriginalArrayKind() || MA->isRead())
1314 isl::set AccDom = MA->getAccessRelation().domain();
1315 std::string Subject = MA->getId().get_name();
1317 Stmt, AccDom, Subject.c_str(), [&,
this, MA]() {
1318 Value *NewVal = NewExitScalars.lookup(MA);
1319 assert(NewVal &&
"The exit scalar must be determined before");
1320 Value *Address = getImplicitAddress(*MA, getLoopForStmt(Stmt), LTS,
1321 BBMap, NewAccesses);
1322 assert((!isa<Instruction>(NewVal) ||
1323 GenDT->dominates(cast<Instruction>(NewVal)->getParent(),
1324 Builder.GetInsertBlock())) &&
1325 "Domination violation");
1326 assert((!isa<Instruction>(Address) ||
1327 GenDT->dominates(cast<Instruction>(Address)->getParent(),
1328 Builder.GetInsertBlock())) &&
1329 "Domination violation");
1330 Builder.CreateStore(NewVal, Address);
1336 PHINode *PHICopy, BasicBlock *IncomingBB,
1345 "Bad incoming block for PHI in non-affine region");
1351 "Incoming PHI block did not have a BBMap");
1354 Value *OpCopy =
nullptr;
1357 Value *Op =
PHI->getIncomingValueForBlock(IncomingBB);
1361 auto IP =
Builder.GetInsertPoint();
1362 if (IP->getParent() != BBCopyEnd)
1363 Builder.SetInsertPoint(BBCopyEnd,
1364 BBCopyEnd->getTerminator()->getIterator());
1366 if (IP->getParent() != BBCopyEnd)
1373 if (PHICopy->getBasicBlockIndex(BBCopyEnd) >= 0)
1380 assert(OpCopy &&
"Incoming PHI value was not copied properly");
1381 PHICopy->addIncoming(OpCopy, BBCopyEnd);
1387 unsigned NumIncoming =
PHI->getNumIncomingValues();
1389 Builder.CreatePHI(
PHI->getType(), NumIncoming,
"polly." +
PHI->getName());
1390 PHICopy->moveBefore(PHICopy->getParent()->getFirstNonPHIIt());
1391 BBMap[
PHI] = PHICopy;
1393 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 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")