[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