Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 1 | //===------ CodeGeneration.cpp - Code generate the Scops using ISL. ----======// |
Sebastian Pop | 082cea8 | 2012-05-07 16:20:07 +0000 | [diff] [blame] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 10 | // The CodeGeneration pass takes a Scop created by ScopInfo and translates it |
Sebastian Pop | 082cea8 | 2012-05-07 16:20:07 +0000 | [diff] [blame] | 11 | // back to LLVM-IR using the ISL code generator. |
| 12 | // |
| 13 | // The Scop describes the high level memory behaviour of a control flow region. |
| 14 | // Transformation passes can update the schedule (execution order) of statements |
| 15 | // in the Scop. ISL is used to generate an abstract syntax tree that reflects |
| 16 | // the updated execution order. This clast is used to create new LLVM-IR that is |
| 17 | // computationally equivalent to the original control flow region, but executes |
Tobias Grosser | 5483931 | 2015-04-21 11:37:25 +0000 | [diff] [blame] | 18 | // its code in the new execution order defined by the changed schedule. |
Sebastian Pop | 082cea8 | 2012-05-07 16:20:07 +0000 | [diff] [blame] | 19 | // |
| 20 | //===----------------------------------------------------------------------===// |
Tobias Grosser | f3ba5b5 | 2015-04-27 12:17:22 +0000 | [diff] [blame] | 21 | |
Tobias Grosser | 8362818 | 2013-05-07 08:11:54 +0000 | [diff] [blame] | 22 | #include "polly/CodeGen/IslAst.h" |
Tobias Grosser | 5624d3c | 2015-12-21 12:38:56 +0000 | [diff] [blame] | 23 | #include "polly/CodeGen/IslNodeBuilder.h" |
Tobias Grosser | 8362818 | 2013-05-07 08:11:54 +0000 | [diff] [blame] | 24 | #include "polly/CodeGen/Utils.h" |
Johannes Doerfert | f6557f9 | 2015-03-04 22:43:40 +0000 | [diff] [blame] | 25 | #include "polly/DependenceInfo.h" |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 26 | #include "polly/LinkAllPasses.h" |
Tobias Grosser | 58e5854 | 2016-02-19 11:07:12 +0000 | [diff] [blame] | 27 | #include "polly/Options.h" |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 28 | #include "polly/ScopInfo.h" |
Tobias Grosser | 0ee50f6 | 2013-04-10 06:55:31 +0000 | [diff] [blame] | 29 | #include "polly/Support/ScopHelper.h" |
Chandler Carruth | 66ef16b | 2015-09-09 22:13:56 +0000 | [diff] [blame] | 30 | #include "llvm/Analysis/AliasAnalysis.h" |
| 31 | #include "llvm/Analysis/BasicAliasAnalysis.h" |
| 32 | #include "llvm/Analysis/GlobalsModRef.h" |
Michael Kruse | 82a1c7d | 2015-08-14 20:10:27 +0000 | [diff] [blame] | 33 | #include "llvm/Analysis/PostDominators.h" |
Chandler Carruth | 66ef16b | 2015-09-09 22:13:56 +0000 | [diff] [blame] | 34 | #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" |
Tobias Grosser | c2bb0cb | 2015-09-25 09:49:19 +0000 | [diff] [blame] | 35 | #include "llvm/IR/Module.h" |
| 36 | #include "llvm/IR/Verifier.h" |
| 37 | #include "llvm/Support/Debug.h" |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 38 | |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 39 | using namespace polly; |
| 40 | using namespace llvm; |
| 41 | |
Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 42 | #define DEBUG_TYPE "polly-codegen" |
Chandler Carruth | 95fef94 | 2014-04-22 03:30:19 +0000 | [diff] [blame] | 43 | |
Tobias Grosser | 58e5854 | 2016-02-19 11:07:12 +0000 | [diff] [blame] | 44 | static cl::opt<bool> Verify("polly-codegen-verify", |
| 45 | cl::desc("Verify the function generated by Polly"), |
| 46 | cl::Hidden, cl::init(true), cl::ZeroOrMore, |
| 47 | cl::cat(PollyCategory)); |
| 48 | |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 49 | namespace { |
Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 50 | class CodeGeneration : public ScopPass { |
Tobias Grosser | 1bb59b0 | 2012-12-29 23:47:38 +0000 | [diff] [blame] | 51 | public: |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 52 | static char ID; |
| 53 | |
Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 54 | CodeGeneration() : ScopPass(ID) {} |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 55 | |
Tobias Grosser | e3c0558 | 2014-11-15 21:32:53 +0000 | [diff] [blame] | 56 | /// @brief The datalayout used |
| 57 | const DataLayout *DL; |
| 58 | |
Johannes Doerfert | 3826224 | 2014-09-10 14:50:23 +0000 | [diff] [blame] | 59 | /// @name The analysis passes we need to generate code. |
| 60 | /// |
| 61 | ///{ |
| 62 | LoopInfo *LI; |
| 63 | IslAstInfo *AI; |
| 64 | DominatorTree *DT; |
| 65 | ScalarEvolution *SE; |
Michael Kruse | 2237088 | 2015-08-11 14:39:21 +0000 | [diff] [blame] | 66 | RegionInfo *RI; |
Johannes Doerfert | 3826224 | 2014-09-10 14:50:23 +0000 | [diff] [blame] | 67 | ///} |
| 68 | |
Tobias Grosser | 58e5854 | 2016-02-19 11:07:12 +0000 | [diff] [blame] | 69 | void verifyGeneratedFunction(Scop &S, Function &F) { |
| 70 | if (!verifyFunction(F, &errs()) || !Verify) |
| 71 | return; |
Johannes Doerfert | 0b169c0 | 2015-02-27 17:37:05 +0000 | [diff] [blame] | 72 | |
| 73 | DEBUG({ |
| 74 | errs() << "== ISL Codegen created an invalid function ==\n\n== The " |
| 75 | "SCoP ==\n"; |
| 76 | S.print(errs()); |
| 77 | errs() << "\n== The isl AST ==\n"; |
Johannes Doerfert | 3fe584d | 2015-03-01 18:40:25 +0000 | [diff] [blame] | 78 | AI->printScop(errs(), S); |
Johannes Doerfert | 0b169c0 | 2015-02-27 17:37:05 +0000 | [diff] [blame] | 79 | errs() << "\n== The invalid function ==\n"; |
| 80 | F.print(errs()); |
Johannes Doerfert | 0b169c0 | 2015-02-27 17:37:05 +0000 | [diff] [blame] | 81 | }); |
| 82 | |
Tobias Grosser | 58e5854 | 2016-02-19 11:07:12 +0000 | [diff] [blame] | 83 | llvm_unreachable("Polly generated function could not be verified. Add " |
| 84 | "-polly-codegen-verify=false to disable this assertion."); |
Johannes Doerfert | 0b169c0 | 2015-02-27 17:37:05 +0000 | [diff] [blame] | 85 | } |
| 86 | |
Michael Kruse | 9c483c5 | 2015-08-11 14:47:37 +0000 | [diff] [blame] | 87 | // CodeGeneration adds a lot of BBs without updating the RegionInfo |
| 88 | // We make all created BBs belong to the scop's parent region without any |
| 89 | // nested structure to keep the RegionInfo verifier happy. |
| 90 | void fixRegionInfo(Function *F, Region *ParentRegion) { |
| 91 | for (BasicBlock &BB : *F) { |
| 92 | if (RI->getRegionFor(&BB)) |
| 93 | continue; |
| 94 | |
| 95 | RI->setRegionFor(&BB, ParentRegion); |
| 96 | } |
| 97 | } |
| 98 | |
Tobias Grosser | bfb6a96 | 2016-03-23 06:57:51 +0000 | [diff] [blame] | 99 | /// @brief Mark a basic block unreachable. |
| 100 | /// |
| 101 | /// Marks the basic block @p Block unreachable by equipping it with an |
| 102 | /// UnreachableInst. |
| 103 | void markBlockUnreachable(BasicBlock &Block, PollyIRBuilder &Builder) { |
| 104 | auto *OrigTerminator = Block.getTerminator(); |
| 105 | Builder.SetInsertPoint(OrigTerminator); |
| 106 | Builder.CreateUnreachable(); |
| 107 | OrigTerminator->eraseFromParent(); |
| 108 | } |
| 109 | |
Johannes Doerfert | 45be644 | 2015-09-27 15:43:29 +0000 | [diff] [blame] | 110 | /// @brief Generate LLVM-IR for the SCoP @p S. |
Johannes Doerfert | 909a3bf | 2015-03-01 18:42:08 +0000 | [diff] [blame] | 111 | bool runOnScop(Scop &S) override { |
Johannes Doerfert | 3826224 | 2014-09-10 14:50:23 +0000 | [diff] [blame] | 112 | AI = &getAnalysis<IslAstInfo>(); |
Johannes Doerfert | 7ceb040 | 2015-02-11 17:25:09 +0000 | [diff] [blame] | 113 | |
| 114 | // Check if we created an isl_ast root node, otherwise exit. |
| 115 | isl_ast_node *AstRoot = AI->getAst(); |
| 116 | if (!AstRoot) |
| 117 | return false; |
| 118 | |
| 119 | LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); |
Johannes Doerfert | 3826224 | 2014-09-10 14:50:23 +0000 | [diff] [blame] | 120 | DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); |
Tobias Grosser | c5bcf24 | 2015-08-17 10:57:08 +0000 | [diff] [blame] | 121 | SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); |
Johannes Doerfert | 3f52e35 | 2016-05-23 12:38:05 +0000 | [diff] [blame] | 122 | DL = &S.getFunction().getParent()->getDataLayout(); |
Michael Kruse | 2237088 | 2015-08-11 14:39:21 +0000 | [diff] [blame] | 123 | RI = &getAnalysis<RegionInfoPass>().getRegionInfo(); |
| 124 | Region *R = &S.getRegion(); |
| 125 | assert(!R->isTopLevelRegion() && "Top level regions are not supported"); |
Tobias Grosser | 0ee50f6 | 2013-04-10 06:55:31 +0000 | [diff] [blame] | 126 | |
Tobias Grosser | d78616f | 2015-10-04 11:19:13 +0000 | [diff] [blame] | 127 | ScopAnnotator Annotator; |
Tobias Grosser | 6325cd2 | 2015-04-27 10:43:10 +0000 | [diff] [blame] | 128 | Annotator.buildAliasScopes(S); |
Johannes Doerfert | ecdf263 | 2014-10-02 15:31:24 +0000 | [diff] [blame] | 129 | |
Michael Kruse | 2237088 | 2015-08-11 14:39:21 +0000 | [diff] [blame] | 130 | simplifyRegion(R, DT, LI, RI); |
| 131 | assert(R->isSimple()); |
Johannes Doerfert | ef74443 | 2016-05-23 12:42:38 +0000 | [diff] [blame] | 132 | BasicBlock *EnteringBB = S.getEnteringBlock(); |
Michael Kruse | 2237088 | 2015-08-11 14:39:21 +0000 | [diff] [blame] | 133 | assert(EnteringBB); |
Johannes Doerfert | 3826224 | 2014-09-10 14:50:23 +0000 | [diff] [blame] | 134 | PollyIRBuilder Builder = createPollyIRBuilder(EnteringBB, Annotator); |
Johannes Doerfert | 9744c4a | 2014-08-12 18:35:54 +0000 | [diff] [blame] | 135 | |
Tobias Grosser | e3c0558 | 2014-11-15 21:32:53 +0000 | [diff] [blame] | 136 | IslNodeBuilder NodeBuilder(Builder, Annotator, this, *DL, *LI, *SE, *DT, S); |
Johannes Doerfert | 3826224 | 2014-09-10 14:50:23 +0000 | [diff] [blame] | 137 | |
Tobias Grosser | 6794238 | 2015-03-28 09:34:40 +0000 | [diff] [blame] | 138 | // Only build the run-time condition and parameters _after_ having |
| 139 | // introduced the conditional branch. This is important as the conditional |
| 140 | // branch will guard the original scop from new induction variables that |
| 141 | // the SCEVExpander may introduce while code generating the parameters and |
| 142 | // which may introduce scalar dependences that prevent us from correctly |
| 143 | // code generating this scop. |
| 144 | BasicBlock *StartBlock = |
| 145 | executeScopConditionally(S, this, Builder.getTrue()); |
Tobias Grosser | bfb6a96 | 2016-03-23 06:57:51 +0000 | [diff] [blame] | 146 | auto *SplitBlock = StartBlock->getSinglePredecessor(); |
Johannes Doerfert | 09e3697 | 2015-10-07 20:17:36 +0000 | [diff] [blame] | 147 | |
| 148 | // First generate code for the hoisted invariant loads and transitively the |
| 149 | // parameters they reference. Afterwards, for the remaining parameters that |
| 150 | // might reference the hoisted loads. Finally, build the runtime check |
| 151 | // that might reference both hoisted loads as well as parameters. |
Johannes Doerfert | c489850 | 2015-11-07 19:46:04 +0000 | [diff] [blame] | 152 | // If the hoisting fails we have to bail and execute the original code. |
Tobias Grosser | 6794238 | 2015-03-28 09:34:40 +0000 | [diff] [blame] | 153 | Builder.SetInsertPoint(SplitBlock->getTerminator()); |
Johannes Doerfert | c489850 | 2015-11-07 19:46:04 +0000 | [diff] [blame] | 154 | if (!NodeBuilder.preloadInvariantLoads()) { |
Johannes Doerfert | 1dd6e37 | 2015-11-08 16:34:17 +0000 | [diff] [blame] | 155 | |
Tobias Grosser | bfb6a96 | 2016-03-23 06:57:51 +0000 | [diff] [blame] | 156 | // Patch the introduced branch condition to ensure that we always execute |
| 157 | // the original SCoP. |
Johannes Doerfert | c489850 | 2015-11-07 19:46:04 +0000 | [diff] [blame] | 158 | auto *FalseI1 = Builder.getFalse(); |
Johannes Doerfert | 3797707 | 2015-11-08 17:57:41 +0000 | [diff] [blame] | 159 | auto *SplitBBTerm = Builder.GetInsertBlock()->getTerminator(); |
| 160 | SplitBBTerm->setOperand(0, FalseI1); |
Johannes Doerfert | 1dd6e37 | 2015-11-08 16:34:17 +0000 | [diff] [blame] | 161 | |
Tobias Grosser | bfb6a96 | 2016-03-23 06:57:51 +0000 | [diff] [blame] | 162 | // Since the other branch is hence ignored we mark it as unreachable and |
| 163 | // adjust the dominator tree accordingly. |
| 164 | auto *ExitingBlock = StartBlock->getUniqueSuccessor(); |
| 165 | assert(ExitingBlock); |
| 166 | auto *MergeBlock = ExitingBlock->getUniqueSuccessor(); |
| 167 | assert(MergeBlock); |
| 168 | markBlockUnreachable(*StartBlock, Builder); |
| 169 | markBlockUnreachable(*ExitingBlock, Builder); |
Johannes Doerfert | ef74443 | 2016-05-23 12:42:38 +0000 | [diff] [blame] | 170 | auto *ExitingBB = S.getExitingBlock(); |
Tobias Grosser | bfb6a96 | 2016-03-23 06:57:51 +0000 | [diff] [blame] | 171 | assert(ExitingBB); |
| 172 | DT->changeImmediateDominator(MergeBlock, ExitingBB); |
| 173 | DT->eraseNode(ExitingBlock); |
| 174 | |
| 175 | isl_ast_node_free(AstRoot); |
Johannes Doerfert | 1dd6e37 | 2015-11-08 16:34:17 +0000 | [diff] [blame] | 176 | } else { |
Roman Gareev | d7754a1 | 2016-07-30 09:25:51 +0000 | [diff] [blame] | 177 | NodeBuilder.allocateNewArrays(); |
Johannes Doerfert | 1dd6e37 | 2015-11-08 16:34:17 +0000 | [diff] [blame] | 178 | NodeBuilder.addParameters(S.getContext()); |
Tobias Grosser | 0aa2953 | 2016-08-08 15:41:52 +0000 | [diff] [blame] | 179 | Value *RTC = NodeBuilder.createRTC(AI->getRunCondition()); |
Johannes Doerfert | 404a0f8 | 2016-05-12 15:12:43 +0000 | [diff] [blame] | 180 | |
Tobias Grosser | 3717aa5 | 2016-06-11 19:17:15 +0000 | [diff] [blame] | 181 | Builder.GetInsertBlock()->getTerminator()->setOperand(0, RTC); |
| 182 | Builder.SetInsertPoint(&StartBlock->front()); |
| 183 | |
| 184 | NodeBuilder.create(AstRoot); |
Tobias Grosser | 8ed5e59 | 2016-07-25 09:15:57 +0000 | [diff] [blame] | 185 | NodeBuilder.finalize(); |
Johannes Doerfert | 1dd6e37 | 2015-11-08 16:34:17 +0000 | [diff] [blame] | 186 | fixRegionInfo(EnteringBB->getParent(), R->getParent()); |
Johannes Doerfert | c489850 | 2015-11-07 19:46:04 +0000 | [diff] [blame] | 187 | } |
| 188 | |
Johannes Doerfert | 6a6a671 | 2016-06-06 12:13:24 +0000 | [diff] [blame] | 189 | Function *F = EnteringBB->getParent(); |
| 190 | verifyGeneratedFunction(S, *F); |
Johannes Doerfert | a9dc529 | 2016-04-08 18:16:02 +0000 | [diff] [blame] | 191 | for (auto *SubF : NodeBuilder.getParallelSubfunctions()) |
| 192 | verifyGeneratedFunction(S, *SubF); |
Tobias Grosser | 652f780 | 2016-02-14 20:56:49 +0000 | [diff] [blame] | 193 | |
Michael Kruse | 4c86a1d | 2015-11-26 12:36:25 +0000 | [diff] [blame] | 194 | // Mark the function such that we run additional cleanup passes on this |
| 195 | // function (e.g. mem2reg to rediscover phi nodes). |
Michael Kruse | 4c86a1d | 2015-11-26 12:36:25 +0000 | [diff] [blame] | 196 | F->addFnAttr("polly-optimized"); |
| 197 | |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 198 | return true; |
| 199 | } |
| 200 | |
Johannes Doerfert | 45be644 | 2015-09-27 15:43:29 +0000 | [diff] [blame] | 201 | /// @brief Register all analyses and transformation required. |
Johannes Doerfert | 909a3bf | 2015-03-01 18:42:08 +0000 | [diff] [blame] | 202 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
Tobias Grosser | 42aff30 | 2014-01-13 22:29:56 +0000 | [diff] [blame] | 203 | AU.addRequired<DominatorTreeWrapperPass>(); |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 204 | AU.addRequired<IslAstInfo>(); |
Matt Arsenault | 8ca3681 | 2014-07-19 18:40:17 +0000 | [diff] [blame] | 205 | AU.addRequired<RegionInfoPass>(); |
Tobias Grosser | c5bcf24 | 2015-08-17 10:57:08 +0000 | [diff] [blame] | 206 | AU.addRequired<ScalarEvolutionWrapperPass>(); |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 207 | AU.addRequired<ScopDetection>(); |
Johannes Doerfert | 99191c7 | 2016-05-31 09:41:04 +0000 | [diff] [blame] | 208 | AU.addRequired<ScopInfoRegionPass>(); |
Chandler Carruth | f557987 | 2015-01-17 14:16:56 +0000 | [diff] [blame] | 209 | AU.addRequired<LoopInfoWrapperPass>(); |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 210 | |
Johannes Doerfert | f6557f9 | 2015-03-04 22:43:40 +0000 | [diff] [blame] | 211 | AU.addPreserved<DependenceInfo>(); |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 212 | |
Chandler Carruth | 66ef16b | 2015-09-09 22:13:56 +0000 | [diff] [blame] | 213 | AU.addPreserved<AAResultsWrapperPass>(); |
| 214 | AU.addPreserved<BasicAAWrapperPass>(); |
Chandler Carruth | f557987 | 2015-01-17 14:16:56 +0000 | [diff] [blame] | 215 | AU.addPreserved<LoopInfoWrapperPass>(); |
Tobias Grosser | 42aff30 | 2014-01-13 22:29:56 +0000 | [diff] [blame] | 216 | AU.addPreserved<DominatorTreeWrapperPass>(); |
Chandler Carruth | 66ef16b | 2015-09-09 22:13:56 +0000 | [diff] [blame] | 217 | AU.addPreserved<GlobalsAAWrapperPass>(); |
Hongbin Zheng | defd098 | 2016-02-25 17:54:42 +0000 | [diff] [blame] | 218 | AU.addPreserved<PostDominatorTreeWrapperPass>(); |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 219 | AU.addPreserved<IslAstInfo>(); |
| 220 | AU.addPreserved<ScopDetection>(); |
Tobias Grosser | c5bcf24 | 2015-08-17 10:57:08 +0000 | [diff] [blame] | 221 | AU.addPreserved<ScalarEvolutionWrapperPass>(); |
Chandler Carruth | 66ef16b | 2015-09-09 22:13:56 +0000 | [diff] [blame] | 222 | AU.addPreserved<SCEVAAWrapperPass>(); |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 223 | |
| 224 | // FIXME: We do not yet add regions for the newly generated code to the |
| 225 | // region tree. |
Matt Arsenault | 8ca3681 | 2014-07-19 18:40:17 +0000 | [diff] [blame] | 226 | AU.addPreserved<RegionInfoPass>(); |
Johannes Doerfert | 99191c7 | 2016-05-31 09:41:04 +0000 | [diff] [blame] | 227 | AU.addPreserved<ScopInfoRegionPass>(); |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 228 | } |
| 229 | }; |
Tobias Grosser | 522478d | 2016-06-23 22:17:27 +0000 | [diff] [blame] | 230 | } // namespace |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 231 | |
Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 232 | char CodeGeneration::ID = 1; |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 233 | |
Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 234 | Pass *polly::createCodeGenerationPass() { return new CodeGeneration(); } |
Tobias Grosser | 8a5bc6e | 2012-10-02 19:50:43 +0000 | [diff] [blame] | 235 | |
Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 236 | INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen", |
Tobias Grosser | 7242ad9 | 2013-02-22 08:07:06 +0000 | [diff] [blame] | 237 | "Polly - Create LLVM-IR from SCoPs", false, false); |
Johannes Doerfert | f6557f9 | 2015-03-04 22:43:40 +0000 | [diff] [blame] | 238 | INITIALIZE_PASS_DEPENDENCY(DependenceInfo); |
Tobias Grosser | 42aff30 | 2014-01-13 22:29:56 +0000 | [diff] [blame] | 239 | INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); |
Chandler Carruth | f557987 | 2015-01-17 14:16:56 +0000 | [diff] [blame] | 240 | INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); |
Matt Arsenault | 8ca3681 | 2014-07-19 18:40:17 +0000 | [diff] [blame] | 241 | INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); |
Tobias Grosser | c5bcf24 | 2015-08-17 10:57:08 +0000 | [diff] [blame] | 242 | INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass); |
Tobias Grosser | 7242ad9 | 2013-02-22 08:07:06 +0000 | [diff] [blame] | 243 | INITIALIZE_PASS_DEPENDENCY(ScopDetection); |
Tobias Grosser | 09d3069 | 2015-05-12 07:45:52 +0000 | [diff] [blame] | 244 | INITIALIZE_PASS_END(CodeGeneration, "polly-codegen", |
Tobias Grosser | 7242ad9 | 2013-02-22 08:07:06 +0000 | [diff] [blame] | 245 | "Polly - Create LLVM-IR from SCoPs", false, false) |