[clang] 66eabeb - [HLSL] Add RWBuffer default constructor
Chris Bieneman via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 28 12:08:34 PDT 2022
Author: Chris Bieneman
Date: 2022-07-28T14:07:40-05:00
New Revision: 66eabeb65dc9dc53fa791e444fa228a406bd304e
URL: https://github.com/llvm/llvm-project/commit/66eabeb65dc9dc53fa791e444fa228a406bd304e
DIFF: https://github.com/llvm/llvm-project/commit/66eabeb65dc9dc53fa791e444fa228a406bd304e.diff
LOG: [HLSL] Add RWBuffer default constructor
This fills out the default constructor for RWBuffer to assign the
handle with the result of __builtin_hlsl_create_handle which we can
then treat as a pointer to the resource data through the mid-level of
the compiler.
Depends on D130016
Differential Revision: https://reviews.llvm.org/D130017
Added:
clang/include/clang/Basic/HLSLRuntime.h
clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl
Modified:
clang/lib/Sema/HLSLExternalSemaSource.cpp
clang/test/AST/HLSL/RWBuffer-AST.hlsl
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/HLSLRuntime.h b/clang/include/clang/Basic/HLSLRuntime.h
new file mode 100644
index 0000000000000..bc3a064f9b69e
--- /dev/null
+++ b/clang/include/clang/Basic/HLSLRuntime.h
@@ -0,0 +1,34 @@
+//===- HLSLRuntime.h - HLSL Runtime -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines the clang::IdentifierInfo, clang::IdentifierTable, and
+/// clang::Selector interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_HLSLRUNTIME_H
+#define CLANG_BASIC_HLSLRUNTIME_H
+
+#include <cstdint>
+
+namespace clang {
+namespace hlsl {
+
+enum class ResourceClass : uint8_t {
+ SRV = 0,
+ UAV,
+ CBuffer,
+ Sampler,
+ NumClasses
+};
+
+} // namespace hlsl
+} // namespace clang
+
+#endif // CLANG_BASIC_HLSLRUNTIME_H
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index d4ea0344adc4a..79f61c43ded43 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -11,13 +11,17 @@
#include "clang/Sema/HLSLExternalSemaSource.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Basic/AttrKinds.h"
+#include "clang/Basic/HLSLRuntime.h"
+#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
#include <functional>
using namespace clang;
+using namespace hlsl;
namespace {
@@ -27,6 +31,7 @@ struct BuiltinTypeDeclBuilder {
CXXRecordDecl *Record = nullptr;
ClassTemplateDecl *Template = nullptr;
NamespaceDecl *HLSLNamespace = nullptr;
+ llvm::StringMap<FieldDecl *> Fields;
BuiltinTypeDeclBuilder(CXXRecordDecl *R) : Record(R) {
Record->startDefinition();
@@ -93,6 +98,7 @@ struct BuiltinTypeDeclBuilder {
Field->setAccess(Access);
Field->setImplicit(true);
Record->addDecl(Field);
+ Fields[Name] = Field;
return *this;
}
@@ -101,6 +107,71 @@ struct BuiltinTypeDeclBuilder {
return addMemberVariable("h", Record->getASTContext().VoidPtrTy, Access);
}
+ static DeclRefExpr *lookupBuiltinFunction(ASTContext &AST, Sema &S,
+ StringRef Name) {
+ CXXScopeSpec SS;
+ IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier);
+ DeclarationNameInfo NameInfo =
+ DeclarationNameInfo(DeclarationName(&II), SourceLocation());
+ LookupResult R(S, NameInfo, Sema::LookupOrdinaryName);
+ S.LookupParsedName(R, S.getCurScope(), &SS, false);
+ assert(R.isSingleResult() &&
+ "Since this is a builtin it should always resolve!");
+ auto *VD = cast<ValueDecl>(R.getFoundDecl());
+ QualType Ty = VD->getType();
+ return DeclRefExpr::Create(AST, NestedNameSpecifierLoc(), SourceLocation(),
+ VD, false, NameInfo, Ty, VK_PRValue);
+ }
+
+ static Expr *emitResourceClassExpr(ASTContext &AST, ResourceClass RC) {
+ return IntegerLiteral::Create(
+ AST,
+ llvm::APInt(AST.getIntWidth(AST.UnsignedCharTy),
+ static_cast<uint8_t>(RC)),
+ AST.UnsignedCharTy, SourceLocation());
+ }
+
+ BuiltinTypeDeclBuilder &addDefaultHandleConstructor(Sema &S,
+ ResourceClass RC) {
+ ASTContext &AST = Record->getASTContext();
+
+ QualType ConstructorType =
+ AST.getFunctionType(AST.VoidTy, {}, FunctionProtoType::ExtProtoInfo());
+
+ CanQualType CanTy = Record->getTypeForDecl()->getCanonicalTypeUnqualified();
+ DeclarationName Name = AST.DeclarationNames.getCXXConstructorName(CanTy);
+ CXXConstructorDecl *Constructor = CXXConstructorDecl::Create(
+ AST, Record, SourceLocation(),
+ DeclarationNameInfo(Name, SourceLocation()), ConstructorType,
+ AST.getTrivialTypeSourceInfo(ConstructorType, SourceLocation()),
+ ExplicitSpecifier(), false, true, false,
+ ConstexprSpecKind::Unspecified);
+
+ DeclRefExpr *Fn =
+ lookupBuiltinFunction(AST, S, "__builtin_hlsl_create_handle");
+
+ Expr *RCExpr = emitResourceClassExpr(AST, RC);
+ CallExpr *Call =
+ CallExpr::Create(AST, Fn, {RCExpr}, AST.VoidPtrTy, VK_PRValue,
+ SourceLocation(), FPOptionsOverride());
+
+ CXXThisExpr *This = new (AST)
+ CXXThisExpr(SourceLocation(), Constructor->getThisType(), true);
+ MemberExpr *Handle = MemberExpr::CreateImplicit(
+ AST, This, true, Fields["h"], Fields["h"]->getType(), VK_LValue,
+ OK_Ordinary);
+ BinaryOperator *Assign = BinaryOperator::Create(
+ AST, Handle, Call, BO_Assign, Handle->getType(), VK_LValue, OK_Ordinary,
+ SourceLocation(), FPOptionsOverride());
+
+ Constructor->setBody(
+ CompoundStmt::Create(AST, {Assign}, FPOptionsOverride(),
+ SourceLocation(), SourceLocation()));
+ Constructor->setAccess(AccessSpecifier::AS_public);
+ Record->addDecl(Constructor);
+ return *this;
+ }
+
BuiltinTypeDeclBuilder &startDefinition() {
Record->startDefinition();
return *this;
@@ -287,5 +358,8 @@ void HLSLExternalSemaSource::CompleteType(TagDecl *Tag) {
}
void HLSLExternalSemaSource::completeBufferType(CXXRecordDecl *Record) {
- BuiltinTypeDeclBuilder(Record).addHandleMember().completeDefinition();
+ BuiltinTypeDeclBuilder(Record)
+ .addHandleMember()
+ .addDefaultHandleConstructor(*SemaPtr, ResourceClass::UAV)
+ .completeDefinition();
}
diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl
index c913809265c26..9d4fff346f795 100644
--- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl
+++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl
@@ -44,4 +44,4 @@ RWBuffer<float> Buffer;
// CHECK: TemplateArgument type 'float'
// CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float'
// CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
-// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit h 'void *'
+// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'void *'
diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl
new file mode 100644
index 0000000000000..2b9c66d8fc17a
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+
+RWBuffer<float> Buf;
+
+// CHECK: define linkonce_odr noundef ptr @"??0?$RWBuffer at M@hlsl@@QAA at XZ"
+// CHECK-NEXT: entry:
+
+// CHECK: %[[HandleRes:[0-9]+]] = call ptr @llvm.dx.create.handle(i8 1)
+// CHECK: store ptr %[[HandleRes]], ptr %h, align 4
More information about the cfe-commits
mailing list