31#include "llvm/ADT/Statistic.h"
32#include "llvm/Analysis/LoopInfo.h"
33#include "llvm/Analysis/RegionInfo.h"
34#include "llvm/IR/BasicBlock.h"
35#include "llvm/IR/Dominators.h"
36#include "llvm/IR/Function.h"
37#include "llvm/IR/Verifier.h"
38#include "llvm/Support/Debug.h"
39#include "llvm/Support/ErrorHandling.h"
40#include "llvm/Support/raw_ostream.h"
41#include "llvm/Transforms/Utils/LoopUtils.h"
49#define DEBUG_TYPE "polly-codegen"
51static cl::opt<bool>
Verify(
"polly-codegen-verify",
52 cl::desc(
"Verify the function generated by Polly"),
57static cl::opt<bool, true>
59 cl::desc(
"Add run-time performance monitoring"), cl::Hidden,
63STATISTIC(ScopsProcessed,
"Number of SCoP processed");
64STATISTIC(CodegenedScops,
"Number of successfully generated SCoPs");
66 "Number of original affine loops in SCoPs that have been generated");
68 "Number of original boxed loops in SCoPs that have been generated");
77 auto OrigTerminator = Block.getTerminator()->getIterator();
78 Builder.SetInsertPoint(&Block, OrigTerminator);
79 Builder.CreateUnreachable();
80 OrigTerminator->eraseFromParent();
85 if (!
Verify || !verifyFunction(F, &errs()))
89 errs() <<
"== ISL Codegen created an invalid function ==\n\n== The "
92 errs() <<
"\n== The isl AST ==\n";
94 errs() <<
"\n== The invalid function ==\n";
98 llvm_unreachable(
"Polly generated function could not be verified. Add "
99 "-polly-codegen-verify=false to disable this assertion.");
105static void fixRegionInfo(Function &F, Region &ParentRegion, RegionInfo &RI) {
106 for (BasicBlock &BB : F) {
107 if (RI.getRegionFor(&BB))
110 RI.setRegionFor(&BB, &ParentRegion);
143 for (
auto *BB : R->blocks()) {
144 auto InstIt = BB->begin();
145 auto InstEnd = BB->end();
147 while (InstIt != InstEnd) {
148 auto NextIt = InstIt;
151 if (
auto *IT = dyn_cast<IntrinsicInst>(&*InstIt)) {
152 switch (IT->getIntrinsicID()) {
153 case Intrinsic::lifetime_start:
154 case Intrinsic::lifetime_end:
155 IT->eraseFromParent();
168 DominatorTree &DT, ScalarEvolution &SE,
185 POLLY_DEBUG(dbgs() <<
"Got an IstAst for a different Scop/isl_ctx\n");
196 auto ScopStats =
S.getStatistics();
199 auto &DL =
S.getFunction().getDataLayout();
200 Region *R = &
S.getRegion();
201 assert(!R->isTopLevelRegion() &&
"Top level regions are not supported");
207 BasicBlock *EnteringBB =
S.getEnteringBlock();
209 PollyIRBuilder Builder(EnteringBB->getContext(), ConstantFolder(),
211 Builder.SetInsertPoint(EnteringBB,
212 EnteringBB->getTerminator()->getIterator());
222 BasicBlock *StartBlock = std::get<0>(StartExitBlocks);
223 BasicBlock *ExitBlock = std::get<1>(StartExitBlocks);
226 auto *SplitBlock = StartBlock->getSinglePredecessor();
228 IslNodeBuilder NodeBuilder(Builder, Annotator, DL, LI, SE, DT,
S, StartBlock);
240 BasicBlock *MergeBlock = ExitBlock->getUniqueSuccessor();
249 Builder.SetInsertPoint(SplitBlock,
250 SplitBlock->getTerminator()->getIterator());
254 auto *FalseI1 = Builder.getFalse();
255 auto *SplitBBTerm = Builder.GetInsertBlock()->getTerminator();
256 SplitBBTerm->setOperand(0, FalseI1);
260 auto *ExitingBlock = StartBlock->getUniqueSuccessor();
262 auto *MergeBlock = ExitingBlock->getUniqueSuccessor();
266 auto *ExitingBB =
S.getExitingBlock();
268 DT.changeImmediateDominator(MergeBlock, ExitingBB);
269 DT.eraseNode(ExitingBlock);
274 Builder.GetInsertBlock()->getTerminator()->setOperand(0, RTC);
276 auto *CI = dyn_cast<ConstantInt>(RTC);
284 if (!(CI && CI->isZero())) {
285 for (Loop *L : LI.getLoopsInPreorder()) {
287 addStringMetadataToLoop(L,
"llvm.loop.vectorize.enable", 0);
297 Builder.SetInsertPoint(StartBlock,
298 StartBlock->getTerminator()->getIterator());
302 fixRegionInfo(*EnteringBB->getParent(), *R->getParent(), RI);
305 CodegenedAffineLoops += ScopStats.NumAffineLoops;
306 CodegenedBoxedLoops += ScopStats.NumBoxedLoops;
309 Function *F = EnteringBB->getParent();
316 F->addFnAttr(
"polly-optimized");
static bool generateCode(Scop &S, IslAstInfo &AI, LoopInfo &LI, DominatorTree &DT, ScalarEvolution &SE, RegionInfo &RI)
STATISTIC(ScopsProcessed, "Number of SCoP processed")
static cl::opt< bool, true > XPerfMonitoring("polly-codegen-perf-monitoring", cl::desc("Add run-time performance monitoring"), cl::Hidden, cl::location(polly::PerfMonitoring), cl::cat(PollyCategory))
static void verifyGeneratedFunction(Scop &S, Function &F, IslAstInfo &AI)
static void fixRegionInfo(Function &F, Region &ParentRegion, RegionInfo &RI)
static cl::opt< bool > Verify("polly-codegen-verify", cl::desc("Verify the function generated by Polly"), cl::Hidden, cl::cat(PollyCategory))
static void removeLifetimeMarkers(Region *R)
Remove all lifetime markers (llvm.lifetime.start, llvm.lifetime.end) from @R.
llvm::cl::OptionCategory PollyCategory
__isl_give isl_ast_expr * release()
__isl_give isl_ast_node * release()
Add Polly specifics when running IRBuilder.
isl::ast_expr getRunCondition()
Get the run condition.
void print(raw_ostream &O)
IslAst & getIslAst()
Return the isl AST computed by this IslAstInfo.
const std::shared_ptr< isl_ctx > getSharedIslCtx() const
void addParameters(__isl_take isl_set *Context)
void create(__isl_take isl_ast_node *Node)
virtual void finalize()
Finalize code generation.
bool preloadInvariantLoads()
Preload all memory loads that are invariant.
void allocateNewArrays(BBPair StartExitBlocks)
Allocate memory for all new arrays created by Polly.
ArrayRef< Function * > getParallelSubfunctions() const
Return the parallel subfunctions that have been created.
Value * createRTC(isl_ast_expr *Condition)
Generate code that evaluates Condition at run-time.
void initialize()
Initialize the performance monitor.
void insertRegionEnd(llvm::Instruction *InsertBefore)
Mark the end of a timing region.
void insertRegionStart(llvm::Instruction *InsertBefore)
Mark the beginning of a timing region.
Helper class to annotate newly generated SCoPs with metadata.
void buildAliasScopes(Scop &S)
Build all alias scopes for the given SCoP.
void markBlockUnreachable(BasicBlock &Block, PollyIRBuilder &Builder)
Mark a basic block unreachable.
@ Value
MemoryKind::Value: Models an llvm::Value.
std::pair< BBPair, llvm::BranchInst * > executeScopConditionally(Scop &S, llvm::Value *RTC, llvm::DominatorTree &DT, llvm::RegionInfo &RI, llvm::LoopInfo &LI)
Execute a Scop conditionally wrt RTC.
llvm::IRBuilder< llvm::ConstantFolder, IRInserter > PollyIRBuilder
bool runCodeGeneration(Scop &S, llvm::RegionInfo &RI, IslAstInfo &AI)
void simplifyRegion(llvm::Region *R, llvm::DominatorTree *DT, llvm::LoopInfo *LI, llvm::RegionInfo *RI)
Simplify the region to have a single unconditional entry edge and a single exit edge.
std::pair< llvm::BasicBlock *, llvm::BasicBlock * > BBPair
Type to hold region delimiters (entry & exit block).