Skip to content

Commit adcef73

Browse files
elizabethandrewsFznamznon
authored andcommitted
Add constant evaluation support for builtins
1 parent bef0981 commit adcef73

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

clang/include/clang/Basic/Builtins.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ enum LanguageID : uint16_t {
4545
ALL_OCL_LANGUAGES = 0x800, // builtin for OCL languages.
4646
HLSL_LANG = 0x1000, // builtin requires HLSL.
4747
C23_LANG = 0x2000, // builtin requires C23 or later.
48-
SYCL_LANG = 0x2000, // builtin requires SYCL.
48+
SYCL_LANG = 0x4000, // builtin requires SYCL.
4949
ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
5050
ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode.
5151
ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode.

clang/lib/AST/ExprConstant.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "clang/Basic/Builtins.h"
5353
#include "clang/Basic/DiagnosticSema.h"
5454
#include "clang/Basic/TargetBuiltins.h"
55+
#include "clang/Basic/IdentifierTable.h"
5556
#include "clang/Basic/TargetInfo.h"
5657
#include "llvm/ADT/APFixedPoint.h"
5758
#include "llvm/ADT/Sequence.h"
@@ -9918,6 +9919,26 @@ static bool isOneByteCharacterType(QualType T) {
99189919
return T->isCharType() || T->isChar8Type();
99199920
}
99209921

9922+
static const SYCLKernelInfo *GetSYCLKernelInfo(ASTContext &Ctx,
9923+
const CallExpr *E) {
9924+
// Argument to the builtin is a type trait which is used to retrieve the
9925+
// kernel name type.
9926+
// FIXME: Improve the comment.
9927+
const Expr *NameExpr = E->getArg(0);
9928+
// FIXME: Implement diagnostic instead of assert.
9929+
assert(NameExpr->isEvaluatable(Ctx) &&
9930+
"KernelNameType should be evaluatable");
9931+
RecordDecl *RD = NameExpr->getType()->castAs<RecordType>()->getDecl();
9932+
IdentifierTable &IdentTable = Ctx.Idents;
9933+
auto Name = DeclarationName(&(IdentTable.get("type")));
9934+
NamedDecl *ND = (RD->lookup(Name)).front();
9935+
TypedefNameDecl *TD = cast<TypedefNameDecl>(ND);
9936+
CanQualType KernelNameType = Ctx.getCanonicalType(TD->getUnderlyingType());
9937+
9938+
// Retrieve KernelInfo using the kernel name.
9939+
return Ctx.findSYCLKernelInfo(KernelNameType);
9940+
}
9941+
99219942
bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
99229943
unsigned BuiltinOp) {
99239944
if (IsOpaqueConstantCall(E))
@@ -10273,6 +10294,23 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1027310294
return false;
1027410295
}
1027510296
}
10297+
case Builtin::BI__builtin_sycl_kernel_name: {
10298+
const SYCLKernelInfo *KernelInfo = GetSYCLKernelInfo(Info.Ctx, E);
10299+
assert(KernelInfo && "Type does not correspond to a SYCL kernel name.");
10300+
// Retrieve the mangled name corresponding to kernel name type.
10301+
std::string ResultStr = KernelInfo->GetKernelName();
10302+
APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
10303+
ResultStr.size() + 1);
10304+
QualType StrTy =
10305+
Info.Ctx.getConstantArrayType(Info.Ctx.CharTy.withConst(), Size,
10306+
nullptr, ArraySizeModifier::Normal, 0);
10307+
StringLiteral *SL =
10308+
StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10309+
/*Pascal*/ false, StrTy, SourceLocation());
10310+
evaluateLValue(SL, Result);
10311+
Result.addArray(Info, E, cast<ConstantArrayType>(StrTy));
10312+
return true;
10313+
}
1027610314

1027710315
default:
1027810316
return false;

clang/test/CodeGenSYCL/builtin-sycl-kernel-name.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class kernel_name_3;
1010
class kernel_name_4;
1111
typedef kernel_name_4 kernel_name_TD2;
1212

13+
struct constexpr_kernel_name;
14+
1315
template<typename KN>
1416
struct kernel_id_t {
1517
using type = KN;
@@ -36,25 +38,30 @@ void test() {
3638
kernel_single_task<kernel_name_TD>(Obj);
3739
kernel_single_task<kernel_name_3>(Obj);
3840
kernel_single_task<kernel_name_TD2>(Obj);
41+
kernel_single_task<constexpr_kernel_name>(Obj);
3942
const char* test1 = __builtin_sycl_kernel_name(kernel_id_t<kernel_name_1>());
4043
const char* test2 = __builtin_sycl_kernel_name(kernel_id_t<kernel_name_TD>());
4144
const char* test3 = __builtin_sycl_kernel_name(kernel_id_nt());
4245
const char* test4 = __builtin_sycl_kernel_name(kernel_id_t<kernel_name_4>());
46+
constexpr const char* test5 = __builtin_sycl_kernel_name(kernel_id_t<constexpr_kernel_name>());
4347
}
4448

4549
// Kernel names retrieved from KernelInfo map
4650
// CHECK: @0 = private unnamed_addr constant [44 x i8] c"_Z20__sycl_kernel_callerI13kernel_name_1Evv\00", align 1
4751
// CHECK: @1 = private unnamed_addr constant [44 x i8] c"_Z20__sycl_kernel_callerI13kernel_name_2Evv\00", align 1
4852
// CHECK: @2 = private unnamed_addr constant [44 x i8] c"_Z20__sycl_kernel_callerI13kernel_name_3Evv\00", align 1
4953
// CHECK: @3 = private unnamed_addr constant [44 x i8] c"_Z20__sycl_kernel_callerI13kernel_name_4Evv\00", align 1
54+
// CHECK: @.str = private unnamed_addr constant [52 x i8] c"_Z20__sycl_kernel_callerI21constexpr_kernel_nameEvv\00", align 1
5055

5156
// CHECK: define dso_local void @_Z4testv()
5257
// CHECK: %test1 = alloca ptr, align 8
5358
// CHECK: %test2 = alloca ptr, align 8
5459
// CHECK: %test3 = alloca ptr, align 8
5560
// CHECK: %test4 = alloca ptr, align 8
61+
// CHECK: %test5 = alloca ptr, align 8
5662
// CHECK: store ptr @0, ptr %test1, align 8
5763
// CHECK: store ptr @1, ptr %test2, align 8
5864
// CHECK: store ptr @2, ptr %test3, align 8
5965
// CHECK: store ptr @3, ptr %test4, align 8
66+
// CHECK: store ptr @.str, ptr %test5, align 8
6067

0 commit comments

Comments
 (0)