summaryrefslogtreecommitdiffstats
path: root/polly/lib/CodeGen/PPCGCodeGeneration.cpp
diff options
context:
space:
mode:
authorTobias Grosser <tobias@grosser.es>2016-07-25 09:16:01 +0000
committerTobias Grosser <tobias@grosser.es>2016-07-25 09:16:01 +0000
commitfa7b080218a92aaa2165669410f5ef31f2d9ad11 (patch)
tree75ac82710e42ae45a9bbd65f0fab6a94b50b9090 /polly/lib/CodeGen/PPCGCodeGeneration.cpp
parent8ed5e5999f2b3239212e051c38958d7229b9b9bc (diff)
downloadbcm5719-llvm-fa7b080218a92aaa2165669410f5ef31f2d9ad11.tar.gz
bcm5719-llvm-fa7b080218a92aaa2165669410f5ef31f2d9ad11.zip
GPGPU: initialize GPU context and simplify the corresponding GPURuntime interface.
There is no need to expose the selected device at the moment. We also pass back pointers as return values, as this simplifies the interface. llvm-svn: 276623
Diffstat (limited to 'polly/lib/CodeGen/PPCGCodeGeneration.cpp')
-rw-r--r--polly/lib/CodeGen/PPCGCodeGeneration.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/polly/lib/CodeGen/PPCGCodeGeneration.cpp b/polly/lib/CodeGen/PPCGCodeGeneration.cpp
index 9bc6fdedc91..012ae34d0c9 100644
--- a/polly/lib/CodeGen/PPCGCodeGeneration.cpp
+++ b/polly/lib/CodeGen/PPCGCodeGeneration.cpp
@@ -135,6 +135,12 @@ public:
getExprBuilder().setIDToSAI(&IDToSAI);
}
+ /// Create after-run-time-check initialization code.
+ void initializeAfterRTH();
+
+ /// Finalize the generated scop.
+ virtual void finalize();
+
private:
/// A vector of array base pointers for which a new ScopArrayInfo was created.
///
@@ -142,6 +148,9 @@ private:
/// more.
std::vector<Value *> LocalArrays;
+ /// The current GPU context.
+ Value *GPUContext;
+
/// A module containing GPU code.
///
/// This pointer is only set in case we are currently generating GPU code.
@@ -256,8 +265,113 @@ private:
/// Free the LLVM-IR module corresponding to the kernel and -- if requested --
/// dump its IR to stderr.
void finalizeKernelFunction();
+
+ void allocateDeviceArrays();
+
+ /// Create a call to initialize the GPU context.
+ ///
+ /// @returns A pointer to the newly initialized context.
+ Value *createCallInitContext();
+
+ /// Create a call to free the GPU context.
+ ///
+ /// @param Context A pointer to an initialized GPU context.
+ void createCallFreeContext(Value *Context);
+
+ Value *createCallAllocateMemoryForDevice(Value *Size);
};
+void GPUNodeBuilder::initializeAfterRTH() {
+ GPUContext = createCallInitContext();
+ allocateDeviceArrays();
+}
+
+void GPUNodeBuilder::finalize() {
+ createCallFreeContext(GPUContext);
+ IslNodeBuilder::finalize();
+}
+
+void GPUNodeBuilder::allocateDeviceArrays() {
+ isl_ast_build *Build = isl_ast_build_from_context(S.getContext());
+
+ for (int i = 0; i < Prog->n_array; ++i) {
+ gpu_array_info *Array = &Prog->array[i];
+ std::string DevPtrName("p_devptr_");
+ DevPtrName.append(Array->name);
+
+ Value *ArraySize = ConstantInt::get(Builder.getInt64Ty(), Array->size);
+
+ if (!gpu_array_is_scalar(Array)) {
+ auto OffsetDimZero = isl_pw_aff_copy(Array->bound[0]);
+ isl_ast_expr *Res = isl_ast_build_expr_from_pw_aff(Build, OffsetDimZero);
+
+ for (unsigned int i = 1; i < Array->n_index; i++) {
+ isl_pw_aff *Bound_I = isl_pw_aff_copy(Array->bound[i]);
+ isl_ast_expr *Expr = isl_ast_build_expr_from_pw_aff(Build, Bound_I);
+ Res = isl_ast_expr_mul(Res, Expr);
+ }
+
+ Value *NumElements = ExprBuilder.create(Res);
+ ArraySize = Builder.CreateMul(ArraySize, NumElements);
+ }
+
+ Value *DevPtr = createCallAllocateMemoryForDevice(ArraySize);
+ DevPtr->setName(DevPtrName);
+ }
+
+ isl_ast_build_free(Build);
+}
+
+Value *GPUNodeBuilder::createCallAllocateMemoryForDevice(Value *Size) {
+ const char *Name = "polly_allocateMemoryForDevice";
+ Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+ Function *F = M->getFunction(Name);
+
+ // If F is not available, declare it.
+ if (!F) {
+ GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+ std::vector<Type *> Args;
+ Args.push_back(Builder.getInt64Ty());
+ FunctionType *Ty = FunctionType::get(Builder.getInt8PtrTy(), Args, false);
+ F = Function::Create(Ty, Linkage, Name, M);
+ }
+
+ return Builder.CreateCall(F, {Size});
+}
+
+Value *GPUNodeBuilder::createCallInitContext() {
+ const char *Name = "polly_initContext";
+ Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+ Function *F = M->getFunction(Name);
+
+ // If F is not available, declare it.
+ if (!F) {
+ GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+ std::vector<Type *> Args;
+ FunctionType *Ty = FunctionType::get(Builder.getInt8PtrTy(), Args, false);
+ F = Function::Create(Ty, Linkage, Name, M);
+ }
+
+ return Builder.CreateCall(F, {});
+}
+
+void GPUNodeBuilder::createCallFreeContext(Value *Context) {
+ const char *Name = "polly_freeContext";
+ Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+ Function *F = M->getFunction(Name);
+
+ // If F is not available, declare it.
+ if (!F) {
+ GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+ std::vector<Type *> Args;
+ Args.push_back(Builder.getInt8PtrTy());
+ FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+ F = Function::Create(Ty, Linkage, Name, M);
+ }
+
+ Builder.CreateCall(F, {Context});
+}
+
/// Check if one string is a prefix of another.
///
/// @param String The string in which to look for the prefix.
@@ -1325,6 +1439,8 @@ public:
Builder.SetInsertPoint(SplitBlock->getTerminator());
NodeBuilder.addParameters(S->getContext());
Builder.SetInsertPoint(&*StartBlock->begin());
+
+ NodeBuilder.initializeAfterRTH();
NodeBuilder.create(Root);
NodeBuilder.finalize();
}
OpenPOWER on IntegriCloud