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 BBMap.remove_if([&](
const auto &
Pair) {
return Pair.second == NewInst; });
393 NewInst->eraseFromParent();
401 "Only block statements can be copied by the block generator");
406 copyBB(Stmt, BB, BBMap, LTS, NewAccesses);
411 BasicBlock *CopyBB = SplitBlock(
Builder.GetInsertBlock(),
413 CopyBB->setName(
"polly.stmt." + BB->getName());
419 isl_id_to_ast_expr *NewAccesses) {
420 BasicBlock *CopyBB =
splitBB(BB);
421 Builder.SetInsertPoint(CopyBB, CopyBB->begin());
425 copyBB(Stmt, BB, CopyBB, BBMap, LTS, NewAccesses);
435 ScalarEvolution *
GenSE) {
438 GenFn ==
GenLI->getTopLevelLoops().front()->getHeader()->getParent());
446 isl_id_to_ast_expr *NewAccesses) {
456 for (Instruction &Inst : *BB)
467 assert(!
Array->isArrayKind() &&
"Trying to get alloca for array kind");
495 Type *Ty =
Array->getElementType();
498 if (
Array->isPHIKind())
503 const DataLayout &DL =
Builder.GetInsertBlock()->getDataLayout();
506 new AllocaInst(Ty, DL.getAllocaAddrSpace(),
nullptr,
507 DL.getPrefTypeAlign(Ty), ScalarBase->getName() + NameExt);
508 BasicBlock *EntryBB = &
Builder.GetInsertBlock()->getParent()->getEntryBlock();
509 Addr->insertBefore(EntryBB->getFirstInsertionPt());
515 Instruction *Inst = cast<Instruction>(
Array->getBasePtr());
524 for (User *U : Inst->users()) {
527 Instruction *UI = dyn_cast<Instruction>(U);
534 EscapeUsers.push_back(UI);
538 if (EscapeUsers.empty())
545 EscapeMap[Inst] = std::make_pair(ScalarAddr, std::move(EscapeUsers));
552 if (MA->isOriginalArrayKind() || MA->isWrite())
563 auto AccDom = MA->getAccessRelation().domain();
564 assert(!StmtDom.is_subset(AccDom).is_false() &&
565 "Scalar must be loaded in all statement instances");
570 BBMap[MA->getAccessValue()] =
Builder.CreateLoad(
571 MA->getElementType(), Address, Address->getName() +
".reload");
589 isl::ast_build RestrictedBuild = AstBuild.restrict(ScheduledDomain);
593 IsInSetExpr =
Builder.CreateICmpNE(
594 IsInSetExpr, ConstantInt::get(IsInSetExpr->getType(), 0));
601 const std::function<
void()> &GenThenFunc) {
606 bool IsPartialWrite =
609 if (!IsPartialWrite) {
619 if (
auto *Const = dyn_cast<ConstantInt>(Cond))
623 BasicBlock *HeadBlock =
Builder.GetInsertBlock();
624 StringRef BlockName = HeadBlock->getName();
627 DomTreeUpdater DTU(
GenDT, DomTreeUpdater::UpdateStrategy::Eager);
628 SplitBlockAndInsertIfThen(Cond,
Builder.GetInsertPoint(),
false,
nullptr,
630 CondBrInst *Branch = cast<CondBrInst>(HeadBlock->getTerminator());
631 BasicBlock *ThenBlock = Branch->getSuccessor(0);
632 BasicBlock *TailBlock = Branch->getSuccessor(1);
635 if (
auto *CondInst = dyn_cast<Instruction>(Cond))
636 CondInst->setName(
"polly." + Subject +
".cond");
637 ThenBlock->setName(BlockName +
"." + Subject +
".partial");
638 TailBlock->setName(BlockName +
".cont");
642 Builder.SetInsertPoint(ThenBlock, ThenBlock->getFirstInsertionPt());
644 Builder.SetInsertPoint(TailBlock, TailBlock->getFirstInsertionPt());
649 raw_string_ostream OS(Result);
650 Val->printAsOperand(OS,
false);
668 "The stmt must have a valid instance");
675 SmallVector<llvm::Value *, 8> Values;
693 DenseSet<Instruction *> Encountered;
698 for (Instruction *Inst : Stmt.
insts()) {
702 if (isa<PHINode>(Inst)) {
707 Values.push_back(
getNewValue(Stmt, Inst, BBMap, LTS,
708 LI.getLoopFor(Inst->getParent())));
710 for (
Value *Op : Inst->operand_values()) {
713 auto *OpInst = dyn_cast<Instruction>(Op);
716 if (!
S->contains(OpInst))
721 if (Encountered.count(OpInst))
730 Values.push_back(
getNewValue(Stmt, OpInst, BBMap, LTS,
731 LI.getLoopFor(Inst->getParent())));
732 Encountered.insert(OpInst);
736 Encountered.insert(Inst);
753 "Region statements need to use the generateScalarStores() function in "
754 "the RegionGenerator");
757 if (MA->isOriginalArrayKind() || MA->isRead())
760 isl::set AccDom = MA->getAccessRelation().domain();
761 std::string Subject = MA->getId().get_name();
764 Stmt, AccDom, Subject.c_str(), [&,
this, MA]() {
765 Value *Val = MA->getAccessValue();
766 if (MA->isAnyPHIKind()) {
767 assert(MA->getIncoming().size() >= 1 &&
768 "Block statements have exactly one exiting block, or "
770 "with same incoming block and value");
771 assert(std::all_of(MA->getIncoming().begin(),
772 MA->getIncoming().end(),
773 [&](std::pair<BasicBlock *, Value *> p) -> bool {
774 return p.first == Stmt.getBasicBlock();
776 "Incoming block must be statement's block");
777 Val = MA->getIncoming()[0].second;
783 assert((!isa<Instruction>(Val) ||
784 GenDT->dominates(cast<Instruction>(Val)->getParent(),
786 "Domination violation");
787 assert((!isa<Instruction>(Address) ||
788 GenDT->dominates(cast<Instruction>(Address)->getParent(),
790 "Domination violation");
792 Builder.CreateStore(Val, Address);
798 BasicBlock *ExitBB =
S.getExit();
799 BasicBlock *PreEntryBB =
S.getEnteringBlock();
803 for (
auto &
Array :
S.arrays()) {
804 if (
Array->getNumberOfDimensions() != 0)
806 if (
Array->isPHIKind()) {
811 auto PHI = cast<PHINode>(
Array->getBasePtr());
813 for (
auto BI =
PHI->block_begin(), BE =
PHI->block_end(); BI != BE; BI++)
814 if (!
S.contains(*BI) && *BI != PreEntryBB)
815 llvm_unreachable(
"Incoming edges from outside the scop should always "
816 "come from PreEntryBB");
818 int Idx =
PHI->getBasicBlockIndex(PreEntryBB);
822 Value *ScalarValue =
PHI->getIncomingValue(Idx);
828 auto *Inst = dyn_cast<Instruction>(
Array->getBasePtr());
830 if (Inst &&
S.contains(Inst))
837 if (
auto *
PHI = dyn_cast_or_null<PHINode>(Inst))
838 if (!
S.hasSingleExitEdge() &&
PHI->getBasicBlockIndex(ExitBB) >= 0)
847 BasicBlock *ExitBB =
S.getExitingBlock();
849 BasicBlock *MergeBB =
S.getExit();
852 BasicBlock *OptExitBB = *(pred_begin(MergeBB));
853 if (OptExitBB == ExitBB)
854 OptExitBB = *(++pred_begin(MergeBB));
856 Builder.SetInsertPoint(OptExitBB, OptExitBB->getTerminator()->getIterator());
857 for (
const auto &EscapeMapping :
EscapeMap) {
860 Instruction *EscapeInst = EscapeMapping.first;
861 const auto &EscapeMappingValue = EscapeMapping.second;
863 auto *ScalarAddr = cast<AllocaInst>(&*EscapeMappingValue.first);
866 Value *EscapeInstReload =
867 Builder.CreateLoad(ScalarAddr->getAllocatedType(), ScalarAddr,
868 EscapeInst->getName() +
".final_reload");
870 Builder.CreateBitOrPointerCast(EscapeInstReload, EscapeInst->getType());
873 PHINode *MergePHI = PHINode::Create(EscapeInst->getType(), 2,
874 EscapeInst->getName() +
".merge");
875 MergePHI->insertBefore(MergeBB->getFirstInsertionPt());
878 MergePHI->addIncoming(EscapeInstReload, OptExitBB);
879 MergePHI->addIncoming(EscapeInst, ExitBB);
883 if (
SE.isSCEVable(EscapeInst->getType()))
884 SE.forgetValue(EscapeInst);
887 for (Instruction *EUser : EscapeUsers)
888 EUser->replaceUsesOfWith(EscapeInst, MergePHI);
893 for (
auto &
Array :
S.arrays()) {
895 if (
Array->getNumberOfDimensions() != 0)
898 if (
Array->isPHIKind())
901 auto *Inst = dyn_cast<Instruction>(
Array->getBasePtr());
909 if (!
S.contains(Inst))
917 if (
S.hasSingleExitEdge())
920 auto *ExitBB =
S.getExitingBlock();
921 auto *MergeBB =
S.getExit();
922 auto *AfterMergeBB = MergeBB->getSingleSuccessor();
923 BasicBlock *OptExitBB = *(pred_begin(MergeBB));
924 if (OptExitBB == ExitBB)
925 OptExitBB = *(++pred_begin(MergeBB));
927 Builder.SetInsertPoint(OptExitBB, OptExitBB->getTerminator()->getIterator());
929 for (
auto &SAI :
S.arrays()) {
930 auto *Val = SAI->getBasePtr();
936 if (!SAI->isExitPHIKind())
939 PHINode *
PHI = dyn_cast<PHINode>(Val);
943 if (
PHI->getParent() != AfterMergeBB)
946 std::string Name =
PHI->getName().str();
948 Value *Reload =
Builder.CreateLoad(SAI->getElementType(), ScalarAddr,
949 Name +
".ph.final_reload");
950 Reload =
Builder.CreateBitOrPointerCast(Reload,
PHI->getType());
951 Value *OriginalValue =
PHI->getIncomingValueForBlock(MergeBB);
952 assert((!isa<Instruction>(OriginalValue) ||
953 cast<Instruction>(OriginalValue)->getParent() != MergeBB) &&
954 "Original value must no be one we just generated.");
955 auto *MergePHI = PHINode::Create(
PHI->getType(), 2, Name +
".ph.merge");
956 MergePHI->insertBefore(MergeBB->getFirstInsertionPt());
957 MergePHI->addIncoming(Reload, OptExitBB);
958 MergePHI->addIncoming(OriginalValue, ExitBB);
959 int Idx =
PHI->getBasicBlockIndex(MergeBB);
960 PHI->setIncomingValue(Idx, MergePHI);
966 if (Stmt.isCopyStmt())
968 else if (Stmt.isBlockStmt())
969 for (
auto &Inst : *Stmt.getBasicBlock())
970 SE.forgetValue(&Inst);
971 else if (Stmt.isRegionStmt())
972 for (
auto *BB : Stmt.getRegion()->blocks())
973 for (
auto &Inst : *BB)
974 SE.forgetValue(&Inst);
976 llvm_unreachable(
"Unexpected statement type found");
979 for (
const auto &EscapeMapping :
EscapeMap) {
981 for (Instruction *EUser : EscapeUsers) {
982 if (Loop *L =
LI.getLoopFor(EUser->getParent()))
985 L = L->getParentLoop();
1000 BasicBlock *BBCopy) {
1002 BasicBlock *BBIDom =
DT.getNode(BB)->getIDom()->getBlock();
1003 BasicBlock *BBCopyIDom =
EndBlockMap.lookup(BBIDom);
1006 GenDT->changeImmediateDominator(BBCopy, BBCopyIDom);
1021 for (
auto ExitingBB : predecessors(R->getExit())) {
1023 if (!R->contains(ExitingBB))
1026 if (!DT.dominates(BB, ExitingBB))
1036 BasicBlock *Common =
nullptr;
1037 for (
auto ExitingBB : predecessors(R->getExit())) {
1039 if (!R->contains(ExitingBB))
1048 Common = DT.findNearestCommonDominator(Common, ExitingBB);
1051 assert(Common && R->contains(Common));
1058 "Only region statements can be copied by the region generator");
1074 BasicBlock *EntryBB = R->getEntry();
1075 BasicBlock *EntryBBCopy = SplitBlock(
Builder.GetInsertBlock(),
1077 EntryBBCopy->setName(
"polly.stmt." + EntryBB->getName() +
".entry");
1078 Builder.SetInsertPoint(EntryBBCopy, EntryBBCopy->begin());
1084 for (
auto PI = pred_begin(EntryBB), PE = pred_end(EntryBB); PI != PE; ++PI)
1085 if (!R->contains(*PI)) {
1091 std::deque<BasicBlock *> Blocks;
1092 SmallSetVector<BasicBlock *, 8> SeenBlocks;
1093 Blocks.push_back(EntryBB);
1094 SeenBlocks.insert(EntryBB);
1096 while (!Blocks.empty()) {
1097 BasicBlock *BB = Blocks.front();
1101 BasicBlock *BBCopy =
splitBB(BB);
1113 InitBBMap = &EntryBBMap;
1114 auto Inserted =
RegionMaps.insert(std::make_pair(BBCopy, *InitBBMap));
1115 ValueMapT &RegionMap = Inserted.first->second;
1118 Builder.SetInsertPoint(BBCopy, BBCopy->begin());
1119 copyBB(Stmt, BB, BBCopy, RegionMap, LTS, IdToAstExp);
1127 addOperandToPHI(Stmt, PHINodePair.first, PHINodePair.second, BB, LTS);
1131 for (
auto SI = succ_begin(BB),
SE = succ_end(BB); SI !=
SE; SI++)
1132 if (R->contains(*SI) && SeenBlocks.insert(*SI))
1133 Blocks.push_back(*SI);
1137 ValueMap.insert_range(RegionMap);
1141 BasicBlock *ExitBBCopy = SplitBlock(
Builder.GetInsertBlock(),
1143 ExitBBCopy->setName(
"polly.stmt." + R->getExit()->getName() +
".exit");
1149 "Common exit dominator must be within region; at least the entry node "
1151 GenDT->changeImmediateDominator(ExitBBCopy, ExitDomBBCopy);
1155 for (BasicBlock *BB : SeenBlocks) {
1159 Instruction *TI = BB->getTerminator();
1160 if (isa<UnreachableInst>(TI)) {
1161 while (!BBCopyEnd->empty())
1162 BBCopyEnd->begin()->eraseFromParent();
1163 new UnreachableInst(BBCopyEnd->getContext(), BBCopyEnd);
1167 Instruction *BICopy = BBCopyEnd->getTerminator();
1172 Builder.SetInsertPoint(BBCopyEnd, BICopy->getIterator());
1174 BICopy->eraseFromParent();
1179 for (BasicBlock *BB : SeenBlocks) {
1180 Loop *L =
LI.getLoopFor(BB);
1181 if (L ==
nullptr || L->getHeader() != BB || !R->contains(L))
1187 PHINode::Create(
Builder.getInt32Ty(), 2,
"polly.subregion.iv");
1188 Instruction *LoopPHIInc = BinaryOperator::CreateAdd(
1189 LoopPHI,
Builder.getInt32(1),
"polly.subregion.iv.inc");
1190 LoopPHI->insertBefore(BBCopy->begin());
1191 LoopPHIInc->insertBefore(BBCopy->getTerminator()->getIterator());
1193 for (
auto *PredBB : predecessors(BB)) {
1194 if (!R->contains(PredBB))
1196 if (L->contains(PredBB))
1197 LoopPHI->addIncoming(LoopPHIInc,
EndBlockMap[PredBB]);
1199 LoopPHI->addIncoming(NullVal,
EndBlockMap[PredBB]);
1202 for (
auto *PredBBCopy : predecessors(BBCopy))
1203 if (LoopPHI->getBasicBlockIndex(PredBBCopy) < 0)
1204 LoopPHI->addIncoming(NullVal, PredBBCopy);
1206 LTS[L] =
SE.getUnknown(LoopPHI);
1210 Builder.SetInsertPoint(ExitBBCopy, ExitBBCopy->getFirstInsertionPt());
1226 PollyIRBuilder::InsertPointGuard IPGuard(
Builder);
1228 BasicBlock *NewSubregionExit =
Builder.GetInsertBlock();
1232 if (OrigPHI->getParent() != SubR->getExit()) {
1233 BasicBlock *FormerExit = SubR->getExitingBlock();
1238 PHINode *NewPHI = PHINode::Create(OrigPHI->getType(), Incoming.size(),
1239 "polly." + OrigPHI->getName(),
1240 NewSubregionExit->getFirstNonPHIIt());
1243 for (
auto &
Pair : Incoming) {
1244 BasicBlock *OrigIncomingBlock =
Pair.first;
1245 BasicBlock *NewIncomingBlockStart =
StartBlockMap.lookup(OrigIncomingBlock);
1246 BasicBlock *NewIncomingBlockEnd =
EndBlockMap.lookup(OrigIncomingBlock);
1247 Builder.SetInsertPoint(NewIncomingBlockEnd,
1248 NewIncomingBlockEnd->getTerminator()->getIterator());
1254 Value *NewIncomingValue =
1255 getNewValue(*Stmt, OrigIncomingValue, *LocalBBMap, LTS, L);
1256 NewPHI->addIncoming(NewIncomingValue, NewIncomingBlockEnd);
1267 Loop *L =
LI.getLoopFor(Stmt->
getRegion()->getExit());
1271 assert(!Incoming.empty() &&
1272 "PHI WRITEs must have originate from at least one incoming block");
1275 if (Incoming.size() == 1) {
1276 Value *OldVal = Incoming[0].second;
1291 __isl_keep isl_id_to_ast_expr *NewAccesses) {
1293 "Block statements need to use the generateScalarStores() "
1294 "function in the BlockGenerator");
1303 SmallDenseMap<MemoryAccess *, Value *> NewExitScalars;
1305 if (MA->isOriginalArrayKind() || MA->isRead())
1309 NewExitScalars[MA] = NewVal;
1313 if (MA->isOriginalArrayKind() || MA->isRead())
1316 isl::set AccDom = MA->getAccessRelation().domain();
1317 std::string Subject = MA->getId().get_name();
1319 Stmt, AccDom, Subject.c_str(), [&,
this, MA]() {
1320 Value *NewVal = NewExitScalars.lookup(MA);
1321 assert(NewVal &&
"The exit scalar must be determined before");
1322 Value *Address = getImplicitAddress(*MA, getLoopForStmt(Stmt), LTS,
1323 BBMap, NewAccesses);
1324 assert((!isa<Instruction>(NewVal) ||
1325 GenDT->dominates(cast<Instruction>(NewVal)->getParent(),
1326 Builder.GetInsertBlock())) &&
1327 "Domination violation");
1328 assert((!isa<Instruction>(Address) ||
1329 GenDT->dominates(cast<Instruction>(Address)->getParent(),
1330 Builder.GetInsertBlock())) &&
1331 "Domination violation");
1332 Builder.CreateStore(NewVal, Address);
1338 PHINode *PHICopy, BasicBlock *IncomingBB,
1347 "Bad incoming block for PHI in non-affine region");
1353 "Incoming PHI block did not have a BBMap");
1356 Value *OpCopy =
nullptr;
1359 Value *Op =
PHI->getIncomingValueForBlock(IncomingBB);
1363 auto IP =
Builder.GetInsertPoint();
1364 if (IP->getParent() != BBCopyEnd)
1365 Builder.SetInsertPoint(BBCopyEnd,
1366 BBCopyEnd->getTerminator()->getIterator());
1368 if (IP->getParent() != BBCopyEnd)
1375 if (PHICopy->getBasicBlockIndex(BBCopyEnd) >= 0)
1382 assert(OpCopy &&
"Incoming PHI value was not copied properly");
1383 PHICopy->addIncoming(OpCopy, BBCopyEnd);
1389 unsigned NumIncoming =
PHI->getNumIncomingValues();
1391 Builder.CreatePHI(
PHI->getType(), NumIncoming,
"polly." +
PHI->getName());
1392 PHICopy->moveBefore(PHICopy->getParent()->getFirstNonPHIIt());
1393 BBMap[
PHI] = PHICopy;
1395 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")