diff options
| author | Tobias Grosser <tobias@grosser.es> | 2016-07-25 09:16:01 +0000 |
|---|---|---|
| committer | Tobias Grosser <tobias@grosser.es> | 2016-07-25 09:16:01 +0000 |
| commit | fa7b080218a92aaa2165669410f5ef31f2d9ad11 (patch) | |
| tree | 75ac82710e42ae45a9bbd65f0fab6a94b50b9090 /polly/lib/CodeGen/PPCGCodeGeneration.cpp | |
| parent | 8ed5e5999f2b3239212e051c38958d7229b9b9bc (diff) | |
| download | bcm5719-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.cpp | 116 |
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(); } |

