[clang] [HLSL] Constant buffers codegen (PR #124886)

Helena Kotas via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 20 10:23:17 PST 2025


================
@@ -0,0 +1,201 @@
+//===- HLSLTargetInto.cpp--------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "HLSLTargetInfo.h"
+#include "CGHLSLRuntime.h"
+#include "TargetInfo.h"
+#include "clang/AST/DeclCXX.h"
+
+//===----------------------------------------------------------------------===//
+// Target codegen info implementation common between DirectX and SPIR/SPIR-V.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+// Creates a new array type with the same dimentions
+// but with the new element type.
+static llvm::Type *
+createArrayWithNewElementType(CodeGenModule &CGM,
+                              const ConstantArrayType *ArrayType,
+                              llvm::Type *NewElemType) {
+  const clang::Type *ArrayElemType = ArrayType->getArrayElementTypeNoTypeQual();
+  if (ArrayElemType->isConstantArrayType())
+    NewElemType = createArrayWithNewElementType(
+        CGM, cast<const ConstantArrayType>(ArrayElemType), NewElemType);
+  return llvm::ArrayType::get(NewElemType, ArrayType->getSExtSize());
+}
+
+// Returns the size of a scalar or vector in bytes/
+static unsigned getScalarOrVectorSize(llvm::Type *Ty) {
+  assert(Ty->isVectorTy() || Ty->isIntegerTy() || Ty->isFloatingPointTy());
+  if (Ty->isVectorTy()) {
+    llvm::FixedVectorType *FVT = cast<llvm::FixedVectorType>(Ty);
+    return FVT->getNumElements() *
+           (FVT->getElementType()->getScalarSizeInBits() / 8);
+  }
+  return Ty->getScalarSizeInBits() / 8;
+}
+
+} // namespace
+
+// Creates a layout type for given struct with HLSL constant buffer layout
+// taking into account Packoffsets, if provided.
+// Previously created layout types are cached in CGHLSLRuntime because
+// TargetCodeGenInto info is cannot store any data
+// (CGM.getTargetCodeGenInfo() returns a const reference to TargetCondegenInfo).
+//
+// The function iterates over all fields of the StructType (including base
+// classes), converts each field to its corresponding LLVM type and calculated
+// it's HLSL constant bufffer layout (offset and size). Any embedded struct (or
+// arrays of structs) are converted to target layout types as well.
+llvm::Type *CommonHLSLTargetCodeGenInfo::createHLSLBufferLayoutType(
+    CodeGenModule &CGM, const RecordType *StructType,
+    const SmallVector<unsigned> *Packoffsets) const {
+
+  // check if we already have the layout type for this struct
+  if (llvm::Type *Ty = CGM.getHLSLRuntime().getHLSLBufferLayoutType(StructType))
+    return Ty;
+
+  SmallVector<unsigned> Layout;
+  SmallVector<llvm::Type *> LayoutElements;
+  unsigned Index = 0; // packoffset index
+  unsigned EndOffset = 0;
+
+  // reserve first spot in the layout vector for buffer size
+  Layout.push_back(0);
+
+  // iterate over all fields of the record, including fields on base classes
+  llvm::SmallVector<const RecordType *> RecordTypes;
+  RecordTypes.push_back(StructType);
+  while (RecordTypes.back()->getAsCXXRecordDecl()->getNumBases()) {
+    CXXRecordDecl *D = RecordTypes.back()->getAsCXXRecordDecl();
+    assert(D->getNumBases() == 1 &&
----------------
hekota wrote:

I'd like to keep this assert in. I believe the other asserts you've seen are in SemaHLSL.

https://github.com/llvm/llvm-project/pull/124886


More information about the cfe-commits mailing list