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())
558 auto AccDom = MA->getAccessRelation().domain();
559 assert(!StmtDom.is_subset(AccDom).is_false() &&
560 "Scalar must be loaded in all statement instances");
565 BBMap[MA->getAccessValue()] =
Builder.CreateLoad(
566 MA->getElementType(), Address, Address->getName() +
".reload");
584 isl::ast_build RestrictedBuild = AstBuild.restrict(ScheduledDomain);
588 IsInSetExpr =
Builder.CreateICmpNE(
589 IsInSetExpr, ConstantInt::get(IsInSetExpr->getType(), 0));
596 const std::function<
void()> &GenThenFunc) {
601 bool IsPartialWrite =
604 if (!IsPartialWrite) {
614 if (
auto *Const = dyn_cast<ConstantInt>(Cond))
618 BasicBlock *HeadBlock =
Builder.GetInsertBlock();
619 StringRef BlockName = HeadBlock->getName();
622 DomTreeUpdater DTU(
GenDT, DomTreeUpdater::UpdateStrategy::Eager);
623 SplitBlockAndInsertIfThen(Cond,
Builder.GetInsertPoint(),
false,
nullptr,
625 CondBrInst *Branch = cast<CondBrInst>(HeadBlock->getTerminator());
626 BasicBlock *ThenBlock = Branch->getSuccessor(0);
627 BasicBlock *TailBlock = Branch->getSuccessor(1);
630 if (
auto *CondInst = dyn_cast<Instruction>(Cond))
631 CondInst->setName(
"polly." + Subject +
".cond");
632 ThenBlock->setName(BlockName +
"." + Subject +
".partial");
633 TailBlock->setName(BlockName +
".cont");
637 Builder.SetInsertPoint(ThenBlock, ThenBlock->getFirstInsertionPt());
639 Builder.SetInsertPoint(TailBlock, TailBlock->getFirstInsertionPt());
644 raw_string_ostream OS(Result);
645 Val->printAsOperand(OS,
false);
663 "The stmt must have a valid instance");
670 SmallVector<llvm::Value *, 8> Values;
688 DenseSet<Instruction *> Encountered;
693 for (Instruction *Inst : Stmt.
insts()) {
697 if (isa<PHINode>(Inst)) {
702 Values.push_back(
getNewValue(Stmt, Inst, BBMap, LTS,
703 LI.getLoopFor(Inst->getParent())));
705 for (
Value *Op : Inst->operand_values()) {
708 auto *OpInst = dyn_cast<Instruction>(Op);
711 if (!
S->contains(OpInst))
716 if (Encountered.count(OpInst))
725 Values.push_back(
getNewValue(Stmt, OpInst, BBMap, LTS,
726 LI.getLoopFor(Inst->getParent())));
727 Encountered.insert(OpInst);
731 Encountered.insert(Inst);
748 "Region statements need to use the generateScalarStores() function in "
749 "the RegionGenerator");
752 if (MA->isOriginalArrayKind() || MA->isRead())
755 isl::set AccDom = MA->getAccessRelation().domain();
756 std::string Subject = MA->getId().get_name();
759 Stmt, AccDom, Subject.c_str(), [&,
this, MA]() {
760 Value *Val = MA->getAccessValue();
761 if (MA->isAnyPHIKind()) {
762 assert(MA->getIncoming().size() >= 1 &&
763 "Block statements have exactly one exiting block, or "
765 "with same incoming block and value");
766 assert(std::all_of(MA->getIncoming().begin(),
767 MA->getIncoming().end(),
768 [&](std::pair<BasicBlock *, Value *> p) -> bool {
769 return p.first == Stmt.getBasicBlock();
771 "Incoming block must be statement's block");
772 Val = MA->getIncoming()[0].second;
778 assert((!isa<Instruction>(Val) ||
779 GenDT->dominates(cast<Instruction>(Val)->getParent(),
781 "Domination violation");
782 assert((!isa<Instruction>(Address) ||
783 GenDT->dominates(cast<Instruction>(Address)->getParent(),
785 "Domination violation");
787 Builder.CreateStore(Val, Address);
793 BasicBlock *ExitBB =
S.getExit();
794 BasicBlock *PreEntryBB =
S.getEnteringBlock();
798 for (
auto &
Array :
S.arrays()) {
799 if (
Array->getNumberOfDimensions() != 0)
801 if (
Array->isPHIKind()) {
806 auto PHI = cast<PHINode>(
Array->getBasePtr());
808 for (
auto BI =
PHI->block_begin(), BE =
PHI->block_end(); BI != BE; BI++)
809 if (!
S.contains(*BI) && *BI != PreEntryBB)
810 llvm_unreachable(
"Incoming edges from outside the scop should always "
811 "come from PreEntryBB");
813 int Idx =
PHI->getBasicBlockIndex(PreEntryBB);
817 Value *ScalarValue =
PHI->getIncomingValue(Idx);
823 auto *Inst = dyn_cast<Instruction>(
Array->getBasePtr());
825 if (Inst &&
S.contains(Inst))
832 if (
auto *
PHI = dyn_cast_or_null<PHINode>(Inst))
833 if (!
S.hasSingleExitEdge() &&
PHI->getBasicBlockIndex(ExitBB) >= 0)
842 BasicBlock *ExitBB =
S.getExitingBlock();
844 BasicBlock *MergeBB =
S.getExit();
847 BasicBlock *OptExitBB = *(pred_begin(MergeBB));
848 if (OptExitBB == ExitBB)
849 OptExitBB = *(++pred_begin(MergeBB));
851 Builder.SetInsertPoint(OptExitBB, OptExitBB->getTerminator()->getIterator());
852 for (
const auto &EscapeMapping :
EscapeMap) {
855 Instruction *EscapeInst = EscapeMapping.first;
856 const auto &EscapeMappingValue = EscapeMapping.second;
858 auto *ScalarAddr = cast<AllocaInst>(&*EscapeMappingValue.first);
861 Value *EscapeInstReload =
862 Builder.CreateLoad(ScalarAddr->getAllocatedType(), ScalarAddr,
863 EscapeInst->getName() +
".final_reload");
865 Builder.CreateBitOrPointerCast(EscapeInstReload, EscapeInst->getType());
868 PHINode *MergePHI = PHINode::Create(EscapeInst->getType(), 2,
869 EscapeInst->getName() +
".merge");
870 MergePHI->insertBefore(MergeBB->getFirstInsertionPt());
873 MergePHI->addIncoming(EscapeInstReload, OptExitBB);
874 MergePHI->addIncoming(EscapeInst, ExitBB);
878 if (
SE.isSCEVable(EscapeInst->getType()))
879 SE.forgetValue(EscapeInst);
882 for (Instruction *EUser : EscapeUsers)
883 EUser->replaceUsesOfWith(EscapeInst, MergePHI);
888 for (
auto &
Array :
S.arrays()) {
890 if (
Array->getNumberOfDimensions() != 0)
893 if (
Array->isPHIKind())
896 auto *Inst = dyn_cast<Instruction>(
Array->getBasePtr());
904 if (!
S.contains(Inst))
912 if (
S.hasSingleExitEdge())
915 auto *ExitBB =
S.getExitingBlock();
916 auto *MergeBB =
S.getExit();
917 auto *AfterMergeBB = MergeBB->getSingleSuccessor();
918 BasicBlock *OptExitBB = *(pred_begin(MergeBB));
919 if (OptExitBB == ExitBB)
920 OptExitBB = *(++pred_begin(MergeBB));
922 Builder.SetInsertPoint(OptExitBB, OptExitBB->getTerminator()->getIterator());
924 for (
auto &SAI :
S.arrays()) {
925 auto *Val = SAI->getBasePtr();
931 if (!SAI->isExitPHIKind())
934 PHINode *
PHI = dyn_cast<PHINode>(Val);
938 if (
PHI->getParent() != AfterMergeBB)
941 std::string Name =
PHI->getName().str();
943 Value *Reload =
Builder.CreateLoad(SAI->getElementType(), ScalarAddr,
944 Name +
".ph.final_reload");
945 Reload =
Builder.CreateBitOrPointerCast(Reload,
PHI->getType());
946 Value *OriginalValue =
PHI->getIncomingValueForBlock(MergeBB);
947 assert((!isa<Instruction>(OriginalValue) ||
948 cast<Instruction>(OriginalValue)->getParent() != MergeBB) &&
949 "Original value must no be one we just generated.");
950 auto *MergePHI = PHINode::Create(
PHI->getType(), 2, Name +
".ph.merge");
951 MergePHI->insertBefore(MergeBB->getFirstInsertionPt());
952 MergePHI->addIncoming(Reload, OptExitBB);
953 MergePHI->addIncoming(OriginalValue, ExitBB);
954 int Idx =
PHI->getBasicBlockIndex(MergeBB);
955 PHI->setIncomingValue(Idx, MergePHI);
961 if (Stmt.isCopyStmt())
963 else if (Stmt.isBlockStmt())
964 for (
auto &Inst : *Stmt.getBasicBlock())
965 SE.forgetValue(&Inst);
966 else if (Stmt.isRegionStmt())
967 for (
auto *BB : Stmt.getRegion()->blocks())
968 for (
auto &Inst : *BB)
969 SE.forgetValue(&Inst);
971 llvm_unreachable(
"Unexpected statement type found");
974 for (
const auto &EscapeMapping :
EscapeMap) {
976 for (Instruction *EUser : EscapeUsers) {
977 if (Loop *L =
LI.getLoopFor(EUser->getParent()))
980 L = L->getParentLoop();
995 BasicBlock *BBCopy) {
997 BasicBlock *BBIDom =
DT.getNode(BB)->getIDom()->getBlock();
998 BasicBlock *BBCopyIDom =
EndBlockMap.lookup(BBIDom);
1001 GenDT->changeImmediateDominator(BBCopy, BBCopyIDom);
1016 for (
auto ExitingBB : predecessors(R->getExit())) {
1018 if (!R->contains(ExitingBB))
1021 if (!DT.dominates(BB, ExitingBB))
1031 BasicBlock *Common =
nullptr;
1032 for (
auto ExitingBB : predecessors(R->getExit())) {
1034 if (!R->contains(ExitingBB))
1043 Common = DT.findNearestCommonDominator(Common, ExitingBB);
1046 assert(Common && R->contains(Common));
1053 "Only region statements can be copied by the region generator");
1069 BasicBlock *EntryBB = R->getEntry();
1070 BasicBlock *EntryBBCopy = SplitBlock(
Builder.GetInsertBlock(),
1072 EntryBBCopy->setName(
"polly.stmt." + EntryBB->getName() +
".entry");
1073 Builder.SetInsertPoint(EntryBBCopy, EntryBBCopy->begin());
1079 for (
auto PI = pred_begin(EntryBB), PE = pred_end(EntryBB); PI != PE; ++PI)
1080 if (!R->contains(*PI)) {
1086 std::deque<BasicBlock *> Blocks;
1087 SmallSetVector<BasicBlock *, 8> SeenBlocks;
1088 Blocks.push_back(EntryBB);
1089 SeenBlocks.insert(EntryBB);
1091 while (!Blocks.empty()) {
1092 BasicBlock *BB = Blocks.front();
1096 BasicBlock *BBCopy =
splitBB(BB);
1108 InitBBMap = &EntryBBMap;
1109 auto Inserted =
RegionMaps.insert(std::make_pair(BBCopy, *InitBBMap));
1110 ValueMapT &RegionMap = Inserted.first->second;
1113 Builder.SetInsertPoint(BBCopy, BBCopy->begin());
1114 copyBB(Stmt, BB, BBCopy, RegionMap, LTS, IdToAstExp);
1122 addOperandToPHI(Stmt, PHINodePair.first, PHINodePair.second, BB, LTS);
1126 for (
auto SI = succ_begin(BB),
SE = succ_end(BB); SI !=
SE; SI++)
1127 if (R->contains(*SI) && SeenBlocks.insert(*SI))
1128 Blocks.push_back(*SI);
1132 ValueMap.insert_range(RegionMap);
1136 BasicBlock *ExitBBCopy = SplitBlock(
Builder.GetInsertBlock(),
1138 ExitBBCopy->setName(
"polly.stmt." + R->getExit()->getName() +
".exit");
1144 "Common exit dominator must be within region; at least the entry node "
1146 GenDT->changeImmediateDominator(ExitBBCopy, ExitDomBBCopy);
1150 for (BasicBlock *BB : SeenBlocks) {
1154 Instruction *TI = BB->getTerminator();
1155 if (isa<UnreachableInst>(TI)) {
1156 while (!BBCopyEnd->empty())
1157 BBCopyEnd->begin()->eraseFromParent();
1158 new UnreachableInst(BBCopyEnd->getContext(), BBCopyEnd);
1162 Instruction *BICopy = BBCopyEnd->getTerminator();
1167 Builder.SetInsertPoint(BBCopyEnd, BICopy->getIterator());
1169 BICopy->eraseFromParent();
1174 for (BasicBlock *BB : SeenBlocks) {
1175 Loop *L =
LI.getLoopFor(BB);
1176 if (L ==
nullptr || L->getHeader() != BB || !R->contains(L))
1182 PHINode::Create(
Builder.getInt32Ty(), 2,
"polly.subregion.iv");
1183 Instruction *LoopPHIInc = BinaryOperator::CreateAdd(
1184 LoopPHI,
Builder.getInt32(1),
"polly.subregion.iv.inc");
1185 LoopPHI->insertBefore(BBCopy->begin());
1186 LoopPHIInc->insertBefore(BBCopy->getTerminator()->getIterator());
1188 for (
auto *PredBB : predecessors(BB)) {
1189 if (!R->contains(PredBB))
1191 if (L->contains(PredBB))
1192 LoopPHI->addIncoming(LoopPHIInc,
EndBlockMap[PredBB]);
1194 LoopPHI->addIncoming(NullVal,
EndBlockMap[PredBB]);
1197 for (
auto *PredBBCopy : predecessors(BBCopy))
1198 if (LoopPHI->getBasicBlockIndex(PredBBCopy) < 0)
1199 LoopPHI->addIncoming(NullVal, PredBBCopy);
1201 LTS[L] =
SE.getUnknown(LoopPHI);
1205 Builder.SetInsertPoint(ExitBBCopy, ExitBBCopy->getFirstInsertionPt());
1221 PollyIRBuilder::InsertPointGuard IPGuard(
Builder);
1223 BasicBlock *NewSubregionExit =
Builder.GetInsertBlock();
1227 if (OrigPHI->getParent() != SubR->getExit()) {
1228 BasicBlock *FormerExit = SubR->getExitingBlock();
1233 PHINode *NewPHI = PHINode::Create(OrigPHI->getType(), Incoming.size(),
1234 "polly." + OrigPHI->getName(),
1235 NewSubregionExit->getFirstNonPHIIt());
1238 for (
auto &
Pair : Incoming) {
1239 BasicBlock *OrigIncomingBlock =
Pair.first;
1240 BasicBlock *NewIncomingBlockStart =
StartBlockMap.lookup(OrigIncomingBlock);
1241 BasicBlock *NewIncomingBlockEnd =
EndBlockMap.lookup(OrigIncomingBlock);
1242 Builder.SetInsertPoint(NewIncomingBlockEnd,
1243 NewIncomingBlockEnd->getTerminator()->getIterator());
1249 Value *NewIncomingValue =
1250 getNewValue(*Stmt, OrigIncomingValue, *LocalBBMap, LTS, L);
1251 NewPHI->addIncoming(NewIncomingValue, NewIncomingBlockEnd);
1262 Loop *L =
LI.getLoopFor(Stmt->
getRegion()->getExit());
1266 assert(!Incoming.empty() &&
1267 "PHI WRITEs must have originate from at least one incoming block");
1270 if (Incoming.size() == 1) {
1271 Value *OldVal = Incoming[0].second;
1286 __isl_keep isl_id_to_ast_expr *NewAccesses) {
1288 "Block statements need to use the generateScalarStores() "
1289 "function in the BlockGenerator");
1298 SmallDenseMap<MemoryAccess *, Value *> NewExitScalars;
1300 if (MA->isOriginalArrayKind() || MA->isRead())
1304 NewExitScalars[MA] = NewVal;
1308 if (MA->isOriginalArrayKind() || MA->isRead())
1311 isl::set AccDom = MA->getAccessRelation().domain();
1312 std::string Subject = MA->getId().get_name();
1314 Stmt, AccDom, Subject.c_str(), [&,
this, MA]() {
1315 Value *NewVal = NewExitScalars.lookup(MA);
1316 assert(NewVal &&
"The exit scalar must be determined before");
1317 Value *Address = getImplicitAddress(*MA, getLoopForStmt(Stmt), LTS,
1318 BBMap, NewAccesses);
1319 assert((!isa<Instruction>(NewVal) ||
1320 GenDT->dominates(cast<Instruction>(NewVal)->getParent(),
1321 Builder.GetInsertBlock())) &&
1322 "Domination violation");
1323 assert((!isa<Instruction>(Address) ||
1324 GenDT->dominates(cast<Instruction>(Address)->getParent(),
1325 Builder.GetInsertBlock())) &&
1326 "Domination violation");
1327 Builder.CreateStore(NewVal, Address);
1333 PHINode *PHICopy, BasicBlock *IncomingBB,
1342 "Bad incoming block for PHI in non-affine region");
1348 "Incoming PHI block did not have a BBMap");
1351 Value *OpCopy =
nullptr;
1354 Value *Op =
PHI->getIncomingValueForBlock(IncomingBB);
1358 auto IP =
Builder.GetInsertPoint();
1359 if (IP->getParent() != BBCopyEnd)
1360 Builder.SetInsertPoint(BBCopyEnd,
1361 BBCopyEnd->getTerminator()->getIterator());
1363 if (IP->getParent() != BBCopyEnd)
1370 if (PHICopy->getBasicBlockIndex(BBCopyEnd) >= 0)
1377 assert(OpCopy &&
"Incoming PHI value was not copied properly");
1378 PHICopy->addIncoming(OpCopy, BBCopyEnd);
1384 unsigned NumIncoming =
PHI->getNumIncomingValues();
1386 Builder.CreatePHI(
PHI->getType(), NumIncoming,
"polly." +
PHI->getName());
1387 PHICopy->moveBefore(PHICopy->getParent()->getFirstNonPHIIt());
1388 BBMap[
PHI] = PHICopy;
1390 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")