summaryrefslogtreecommitdiff
path: root/polly/lib/CodeGen/PPCGCodeGeneration.cpp
diff options
context:
space:
mode:
authorTobias Grosser <tobias@grosser.es>2016-07-18 11:56:39 +0000
committerTobias Grosser <tobias@grosser.es>2016-07-18 11:56:39 +0000
commit38fc0aed08853fbad0aa55764dd01def682550b6 (patch)
tree90c54f8b0a6f7c469d3180a8e39075431413c99c /polly/lib/CodeGen/PPCGCodeGeneration.cpp
parent52bd8012bd0f440e21ddec0c1d6ed89605adbb3b (diff)
GPGPU: Create host control flow
Create LLVM-IR for all host-side control flow of a given GPU AST. We implement this by introducing a new GPUNodeBuilder class derived from IslNodeBuilder. The IslNodeBuilder will take care of generating all general-purpose ast nodes, but we provide our own createUser implementation to handle the different GPU specific user statements. For now, we just skip any user statement and only generate a host-code sceleton, but in subsequent commits we will add handling of normal ScopStmt's performing computations, kernel calls, as well as host-device data transfers. We will also introduce run-time check generation and LICM in subsequent commits. llvm-svn: 275783
Diffstat (limited to 'polly/lib/CodeGen/PPCGCodeGeneration.cpp')
-rw-r--r--polly/lib/CodeGen/PPCGCodeGeneration.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/polly/lib/CodeGen/PPCGCodeGeneration.cpp b/polly/lib/CodeGen/PPCGCodeGeneration.cpp
index 72de3be94632..e28088e803fc 100644
--- a/polly/lib/CodeGen/PPCGCodeGeneration.cpp
+++ b/polly/lib/CodeGen/PPCGCodeGeneration.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "polly/CodeGen/IslNodeBuilder.h"
+#include "polly/CodeGen/Utils.h"
#include "polly/DependenceInfo.h"
#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
@@ -68,6 +69,35 @@ static __isl_give isl_id_to_ast_expr *pollyBuildAstExprForStmt(
return nullptr;
}
+/// Generate code for a GPU specific isl AST.
+///
+/// The GPUNodeBuilder augments the general existing IslNodeBuilder, which
+/// generates code for general-prupose AST nodes, with special functionality
+/// for generating GPU specific user nodes.
+///
+/// @see GPUNodeBuilder::createUser
+class GPUNodeBuilder : public IslNodeBuilder {
+public:
+ GPUNodeBuilder(PollyIRBuilder &Builder, ScopAnnotator &Annotator, Pass *P,
+ const DataLayout &DL, LoopInfo &LI, ScalarEvolution &SE,
+ DominatorTree &DT, Scop &S)
+ : IslNodeBuilder(Builder, Annotator, P, DL, LI, SE, DT, S) {}
+
+private:
+ /// Create code for user-defined AST nodes.
+ ///
+ /// These AST nodes can be of type:
+ ///
+ /// - ScopStmt: A computational statement (TODO)
+ /// - Kernel: A GPU kernel call (TODO)
+ /// - Data-Transfer: A GPU <-> CPU data-transfer (TODO)
+ ///
+ virtual void createUser(__isl_take isl_ast_node *User) {
+ isl_ast_node_free(User);
+ return;
+ }
+};
+
namespace {
class PPCGCodeGeneration : public ScopPass {
public:
@@ -76,6 +106,12 @@ public:
/// The scop that is currently processed.
Scop *S;
+ LoopInfo *LI;
+ DominatorTree *DT;
+ ScalarEvolution *SE;
+ const DataLayout *DL;
+ RegionInfo *RI;
+
PPCGCodeGeneration() : ScopPass(ID) {}
/// Construct compilation options for PPCG.
@@ -650,12 +686,58 @@ public:
PPCGScop->options = nullptr;
}
+ /// Generate code for a given GPU AST described by @p Root.
+ ///
+ /// @param An isl_ast_node pointing to the root of the GPU AST.
+ void generateCode(__isl_take isl_ast_node *Root) {
+ ScopAnnotator Annotator;
+ Annotator.buildAliasScopes(*S);
+
+ Region *R = &S->getRegion();
+
+ simplifyRegion(R, DT, LI, RI);
+
+ BasicBlock *EnteringBB = R->getEnteringBlock();
+
+ PollyIRBuilder Builder = createPollyIRBuilder(EnteringBB, Annotator);
+
+ GPUNodeBuilder NodeBuilder(Builder, Annotator, this, *DL, *LI, *SE, *DT,
+ *S);
+
+ // Only build the run-time condition and parameters _after_ having
+ // introduced the conditional branch. This is important as the conditional
+ // branch will guard the original scop from new induction variables that
+ // the SCEVExpander may introduce while code generating the parameters and
+ // which may introduce scalar dependences that prevent us from correctly
+ // code generating this scop.
+ BasicBlock *StartBlock =
+ executeScopConditionally(*S, this, Builder.getTrue());
+
+ // TODO: Handle LICM
+ // TODO: Verify run-time checks
+ auto SplitBlock = StartBlock->getSinglePredecessor();
+ Builder.SetInsertPoint(SplitBlock->getTerminator());
+ NodeBuilder.addParameters(S->getContext());
+ Builder.SetInsertPoint(&*StartBlock->begin());
+ NodeBuilder.create(Root);
+ NodeBuilder.finalizeSCoP(*S);
+ }
+
bool runOnScop(Scop &CurrentScop) override {
S = &CurrentScop;
+ LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ DL = &S->getRegion().getEntry()->getParent()->getParent()->getDataLayout();
+ RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
auto PPCGScop = createPPCGScop();
auto PPCGProg = createPPCGProg(PPCGScop);
auto PPCGGen = generateGPU(PPCGScop, PPCGProg);
+
+ if (PPCGGen->tree)
+ generateCode(isl_ast_node_copy(PPCGGen->tree));
+
freeOptions(PPCGScop);
freePPCGGen(PPCGGen);
gpu_prog_free(PPCGProg);