diff options
author | Siddharth Bhat <siddu.druid@gmail.com> | 2017-06-12 11:41:09 +0000 |
---|---|---|
committer | Siddharth Bhat <siddu.druid@gmail.com> | 2017-06-12 11:41:09 +0000 |
commit | bccaea57c00d5227830e3c296636d2b54c080a92 (patch) | |
tree | bb1bac7449f699c944b2dd92d2fc2d336c66af56 /polly/lib/CodeGen/PPCGCodeGeneration.cpp | |
parent | b079c8b35b40eeb41141d14e0f497d3fe5dcf9e9 (diff) | |
download | bcm5719-llvm-bccaea57c00d5227830e3c296636d2b54c080a92.tar.gz bcm5719-llvm-bccaea57c00d5227830e3c296636d2b54c080a92.zip |
[Polly] [PPCGCodeGeneration] Skip Scops which contain function pointers.
In `PPCGCodeGeneration`, we try to take the references of every `Value`
that is used within a Scop to offload to the kernel. This occurs in
`GPUNodeBuilder::createLaunchParameters`.
This breaks if one of the values is a function pointer, since one of
these cases will trigger:
1. We try to to take the references of an intrinsic function, and this
breaks at `verifyModule`, since it is illegal to take the reference of
an intrinsic.
2. We manage to take the reference to a function, but this fails at
`verifyModule` since the function will not be present in the module that
is created in the kernel.
3. Even if `verifyModule` succeeds (which should not occur), we would
then try to call a *host function* from the *device*, which is
illegal runtime behaviour.
So, we disable this entire range of possibilities by simply not allowing
function references within a `Scop` which corresponds to a kernel.
However, note that this is too conservative. We *can* allow intrinsics
within kernels if the backend can lower the intrinsic correctly. For
example, an intrinsic like `llvm.powi.*` can actually be lowered by the `NVPTX`
backend.
We will now gradually whitelist intrinsics which are known to be safe.
Differential Revision: https://reviews.llvm.org/D33414
llvm-svn: 305185
Diffstat (limited to 'polly/lib/CodeGen/PPCGCodeGeneration.cpp')
-rw-r--r-- | polly/lib/CodeGen/PPCGCodeGeneration.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/polly/lib/CodeGen/PPCGCodeGeneration.cpp b/polly/lib/CodeGen/PPCGCodeGeneration.cpp index 37f7dae586d..d8d735006d3 100644 --- a/polly/lib/CodeGen/PPCGCodeGeneration.cpp +++ b/polly/lib/CodeGen/PPCGCodeGeneration.cpp @@ -2611,6 +2611,36 @@ public: return isl_ast_expr_ge(Iterations, MinComputeExpr); } + /// Check whether the Block contains any Function value. + bool ContainsFnPtrValInBlock(const BasicBlock *BB) { + for (const Instruction &Inst : *BB) + for (Value *SrcVal : Inst.operands()) { + PointerType *p = dyn_cast<PointerType>(SrcVal->getType()); + if (!p) + continue; + if (isa<FunctionType>(p->getElementType())) + return true; + } + return false; + } + + /// Return whether the Scop S has functions. + bool ContainsFnPtr(const Scop &S) { + for (auto &Stmt : S) { + if (Stmt.isBlockStmt()) { + if (ContainsFnPtrValInBlock(Stmt.getBasicBlock())) + return true; + } else { + assert(Stmt.isRegionStmt() && + "Stmt was neither block nor region statement"); + for (const BasicBlock *BB : Stmt.getRegion()->blocks()) + if (ContainsFnPtrValInBlock(BB)) + return true; + } + } + return false; + } + /// Generate code for a given GPU AST described by @p Root. /// /// @param Root An isl_ast_node pointing to the root of the GPU AST. @@ -2681,6 +2711,14 @@ public: if (S->hasInvariantAccesses()) return false; + // We currently do not support functions inside kernels, as code + // generation will need to offload function calls to the kernel. + // This may lead to a kernel trying to call a function on the host. + // This also allows us to prevent codegen from trying to take the + // address of an intrinsic function to send to the kernel. + if (ContainsFnPtr(CurrentScop)) + return false; + auto PPCGScop = createPPCGScop(); auto PPCGProg = createPPCGProg(PPCGScop); auto PPCGGen = generateGPU(PPCGScop, PPCGProg); |