diff options
author | Yaxun (Sam) Liu <yaxun.liu@amd.com> | 2020-01-29 14:11:37 -0500 |
---|---|---|
committer | Yaxun (Sam) Liu <yaxun.liu@amd.com> | 2020-02-16 20:41:00 -0500 |
commit | fb44b9db95a333efdfa9a33ddc1778f97428f5f5 (patch) | |
tree | cb74d1729604e8248e0f389cb047d83bdd5a03b9 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 20c5968e0953d978be4d9d1062801e8758c393b5 (diff) | |
download | llvm-fb44b9db95a333efdfa9a33ddc1778f97428f5f5.zip llvm-fb44b9db95a333efdfa9a33ddc1778f97428f5f5.tar.gz llvm-fb44b9db95a333efdfa9a33ddc1778f97428f5f5.tar.bz2 |
[OpenCL][CUDA][HIP][SYCL] Add norecurse
norecurse function attr indicates the function is not called recursively
directly or indirectly.
Add norecurse to OpenCL functions, SYCL functions in device compilation
and CUDA/HIP kernels.
Although there is LLVM pass adding norecurse to functions, it only works
for whole-program compilation. Also FE adding norecurse can make that
pass run faster since functions with norecurse do not need to be checked
again.
Differential Revision: https://reviews.llvm.org/D73651
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index bcd9366..d6c2afc 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -918,10 +918,20 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // If we're in C++ mode and the function name is "main", it is guaranteed // to be norecurse by the standard (3.6.1.3 "The function main shall not be // used within a program"). - if (getLangOpts().CPlusPlus) - if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) - if (FD->isMain()) - Fn->addFnAttr(llvm::Attribute::NoRecurse); + // + // OpenCL C 2.0 v2.2-11 s6.9.i: + // Recursion is not supported. + // + // SYCL v1.2.1 s3.10: + // kernels cannot include RTTI information, exception classes, + // recursive code, virtual functions or make use of C++ libraries that + // are not compiled for the device. + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { + if ((getLangOpts().CPlusPlus && FD->isMain()) || getLangOpts().OpenCL || + getLangOpts().SYCLIsDevice || + (getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>())) + Fn->addFnAttr(llvm::Attribute::NoRecurse); + } if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) if (FD->usesFPIntrin()) |