llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-spir-v

Author: Helena Kotas (hekota)

<details>
<summary>Changes</summary>

Changes line endings in files related to HLSL to LF (`\n`).

---

Patch is 550.08 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/156930.diff


92 Files Affected:

- (modified) clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp (+273-273) 
- (modified) clang/lib/CodeGen/HLSLBufferLayoutBuilder.h (+47-47) 
- (modified) 
clang/test/AST/HLSL/is_structured_resource_element_compatible_concept.hlsl 
(+15-15) 
- (modified) 
clang/test/AST/HLSL/is_typed_resource_element_compatible_concept.hlsl (+9-9) 
- (modified) clang/test/CodeGenHLSL/builtins/asint16.hlsl (+60-60) 
- (modified) clang/test/CodeGenHLSL/builtins/asuint16.hlsl (+60-60) 
- (modified) clang/test/CodeGenHLSL/builtins/atan2-overloads.hlsl (+123-123) 
- (modified) clang/test/CodeGenHLSL/builtins/atan2.hlsl (+59-59) 
- (modified) clang/test/CodeGenHLSL/builtins/cross.hlsl (+37-37) 
- (modified) clang/test/CodeGenHLSL/builtins/dot2add.hlsl (+175-175) 
- (modified) clang/test/CodeGenHLSL/builtins/dst.hlsl (+51-51) 
- (modified) clang/test/CodeGenHLSL/builtins/normalize-overloads.hlsl 
(+156-156) 
- (modified) clang/test/CodeGenHLSL/builtins/normalize.hlsl (+85-85) 
- (modified) clang/test/CodeGenHLSL/builtins/or.hlsl (+80-80) 
- (modified) clang/test/CodeGenHLSL/builtins/step-overloads.hlsl (+153-153) 
- (modified) clang/test/CodeGenHLSL/builtins/step.hlsl (+84-84) 
- (modified) 
clang/test/CodeGenHLSL/resources/AppendStructuredBuffer-elementtype.hlsl 
(+54-54) 
- (modified) 
clang/test/CodeGenHLSL/resources/ConsumeStructuredBuffer-elementtype.hlsl 
(+54-54) 
- (modified) 
clang/test/CodeGenHLSL/resources/RWStructuredBuffer-elementtype.hlsl (+61-61) 
- (modified) 
clang/test/CodeGenHLSL/resources/RasterizerOrderedStructuredBuffer-elementtype.hlsl
 (+60-60) 
- (modified) clang/test/CodeGenHLSL/resources/StructuredBuffer-elementtype.hlsl 
(+61-61) 
- (modified) clang/test/CodeGenHLSL/resources/StructuredBuffers-subscripts.hlsl 
(+51-51) 
- (modified) clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl 
(+54-54) 
- (modified) 
clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl 
(+29-29) 
- (modified) clang/test/CodeGenHLSL/resources/res-array-global-dyn-index.hlsl 
(+29-29) 
- (modified) clang/test/CodeGenHLSL/resources/res-array-global-multi-dim.hlsl 
(+46-46) 
- (modified) 
clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl (+109-109) 
- (modified) 
clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl (+62-62) 
- (modified) clang/test/CodeGenHLSL/resources/res-array-global.hlsl (+75-75) 
- (modified) clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl 
(+49-49) 
- (modified) clang/test/CodeGenHLSL/resources/res-array-local1.hlsl (+64-64) 
- (modified) clang/test/CodeGenHLSL/resources/res-array-local2.hlsl (+37-37) 
- (modified) clang/test/CodeGenHLSL/resources/res-array-local3.hlsl (+62-62) 
- (modified) clang/test/Options/Gis.hlsl (+13-13) 
- (modified) clang/test/ParserHLSL/bitfields.hlsl (+31-31) 
- (modified) clang/test/ParserHLSL/hlsl_annotations_on_struct_members.hlsl 
(+21-21) 
- (modified) clang/test/ParserHLSL/hlsl_contained_type_attr.hlsl (+25-25) 
- (modified) clang/test/ParserHLSL/hlsl_contained_type_attr_error.hlsl (+28-28) 
- (modified) clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl (+22-22) 
- (modified) clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl (+20-20) 
- (modified) clang/test/ParserHLSL/hlsl_raw_buffer_attr.hlsl (+22-22) 
- (modified) clang/test/ParserHLSL/hlsl_raw_buffer_attr_error.hlsl (+17-17) 
- (modified) clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl (+37-37) 
- (modified) clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl (+22-22) 
- (modified) clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl (+19-19) 
- (modified) clang/test/SemaHLSL/Availability/avail-diag-default-compute.hlsl 
(+119-119) 
- (modified) clang/test/SemaHLSL/Availability/avail-diag-default-lib.hlsl 
(+180-180) 
- (modified) clang/test/SemaHLSL/Availability/avail-diag-relaxed-compute.hlsl 
(+119-119) 
- (modified) clang/test/SemaHLSL/Availability/avail-diag-relaxed-lib.hlsl 
(+162-162) 
- (modified) clang/test/SemaHLSL/Availability/avail-diag-strict-compute.hlsl 
(+129-129) 
- (modified) clang/test/SemaHLSL/Availability/avail-diag-strict-lib.hlsl 
(+192-192) 
- (modified) clang/test/SemaHLSL/Availability/avail-lib-multiple-stages.hlsl 
(+57-57) 
- (modified) clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl (+31-31) 
- (modified) clang/test/SemaHLSL/BuiltIns/asint16-errors.hlsl (+43-43) 
- (modified) clang/test/SemaHLSL/BuiltIns/asuint16-errors.hlsl (+52-52) 
- (modified) clang/test/SemaHLSL/BuiltIns/cross-errors.hlsl (+61-61) 
- (modified) clang/test/SemaHLSL/BuiltIns/dot2add-errors.hlsl (+13-13) 
- (modified) clang/test/SemaHLSL/BuiltIns/half-float-only-errors2.hlsl (+13-13) 
- (modified) clang/test/SemaHLSL/BuiltIns/length-errors.hlsl (+81-81) 
- (modified) clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl (+33-33) 
- (modified) clang/test/SemaHLSL/BuiltIns/normalize-errors.hlsl (+31-31) 
- (modified) clang/test/SemaHLSL/BuiltIns/step-errors.hlsl (+31-31) 
- (modified) clang/test/SemaHLSL/Types/Traits/IsIntangibleType.hlsl (+81-81) 
- (modified) clang/test/SemaHLSL/Types/Traits/IsIntangibleTypeErrors.hlsl 
(+12-12) 
- (modified) 
clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl (+58-58) 
- (modified) clang/test/SemaHLSL/resource_binding_attr_error_basic.hlsl 
(+42-42) 
- (modified) clang/test/SemaHLSL/resource_binding_attr_error_other.hlsl (+9-9) 
- (modified) clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl 
(+49-49) 
- (modified) clang/test/SemaHLSL/resource_binding_attr_error_silence_diags.hlsl 
(+27-27) 
- (modified) clang/test/SemaHLSL/resource_binding_attr_error_space.hlsl 
(+62-62) 
- (modified) clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl 
(+135-135) 
- (modified) llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll (+79-79) 
- (modified) llvm/test/CodeGen/DirectX/atan2.ll (+87-87) 
- (modified) llvm/test/CodeGen/DirectX/atan2_error.ll (+11-11) 
- (modified) llvm/test/CodeGen/DirectX/cross.ll (+56-56) 
- (modified) llvm/test/CodeGen/DirectX/dot2add.ll (+13-13) 
- (modified) llvm/test/CodeGen/DirectX/dot2add_error.ll (+15-15) 
- (modified) llvm/test/CodeGen/DirectX/legalize-fneg.ll (+23-23) 
- (modified) llvm/test/CodeGen/DirectX/legalize-load-store-array-alloca.ll 
(+41-41) 
- (modified) llvm/test/CodeGen/DirectX/metadata-stripping.ll (+32-32) 
- (modified) llvm/test/CodeGen/DirectX/noop_bitcast_global_array_type.ll 
(+53-53) 
- (modified) llvm/test/CodeGen/DirectX/normalize.ll (+112-112) 
- (modified) llvm/test/CodeGen/DirectX/normalize_error.ll (+10-10) 
- (modified) llvm/test/CodeGen/DirectX/step.ll (+78-78) 
- (modified) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan2.ll (+49-49) 
- (modified) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/cross.ll (+33-33) 
- (modified) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/faceforward.ll (+62-62) 
- (modified) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/length.ll (+31-31) 
- (modified) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/normalize.ll (+31-31) 
- (modified) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/reflect.ll (+33-33) 
- (modified) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/smoothstep.ll (+68-68) 
- (modified) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/step.ll (+33-33) 


``````````diff
diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp 
b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
index a21feaa1120c6..838903cdcd1ee 100644
--- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
@@ -1,273 +1,273 @@
-//===- HLSLBufferLayoutBuilder.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 "HLSLBufferLayoutBuilder.h"
-#include "CGHLSLRuntime.h"
-#include "CodeGenModule.h"
-#include "clang/AST/Type.h"
-#include <climits>
-
-//===----------------------------------------------------------------------===//
-// Implementation of constant buffer layout common between DirectX and
-// SPIR/SPIR-V.
-//===----------------------------------------------------------------------===//
-
-using namespace clang;
-using namespace clang::CodeGen;
-using llvm::hlsl::CBufferRowSizeInBytes;
-
-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 getScalarOrVectorSizeInBytes(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
-
-namespace clang {
-namespace CodeGen {
-
-// Creates a layout type for given struct or class with HLSL constant buffer
-// layout taking into account PackOffsets, if provided.
-// Previously created layout types are cached by CGHLSLRuntime.
-//
-// The function iterates over all fields of the record type (including base
-// classes) and calls layoutField to converts each field to its corresponding
-// LLVM type and to calculate its HLSL constant buffer layout. Any embedded
-// structs (or arrays of structs) are converted to target layout types as well.
-//
-// When PackOffsets are specified the elements will be placed based on the
-// user-specified offsets. Not all elements must have a packoffset/register(c#)
-// annotation though. For those that don't, the PackOffsets array will contain
-// -1 value instead. These elements must be placed at the end of the layout
-// after all of the elements with specific offset.
-llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType(
-    const RecordType *RT, const llvm::SmallVector<int32_t> *PackOffsets) {
-
-  // check if we already have the layout type for this struct
-  if (llvm::TargetExtType *Ty =
-          CGM.getHLSLRuntime().getHLSLBufferLayoutType(RT))
-    return Ty;
-
-  SmallVector<unsigned> Layout;
-  SmallVector<llvm::Type *> LayoutElements;
-  unsigned Index = 0; // packoffset index
-  unsigned EndOffset = 0;
-
-  SmallVector<std::pair<const FieldDecl *, unsigned>> DelayLayoutFields;
-
-  // 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<CXXRecordDecl *> RecordDecls;
-  RecordDecls.push_back(RT->castAsCXXRecordDecl());
-  while (RecordDecls.back()->getNumBases()) {
-    CXXRecordDecl *D = RecordDecls.back();
-    assert(D->getNumBases() == 1 &&
-           "HLSL doesn't support multiple inheritance");
-    RecordDecls.push_back(D->bases_begin()->getType()->castAsCXXRecordDecl());
-  }
-
-  unsigned FieldOffset;
-  llvm::Type *FieldType;
-
-  while (!RecordDecls.empty()) {
-    const CXXRecordDecl *RD = RecordDecls.pop_back_val();
-
-    for (const auto *FD : RD->fields()) {
-      assert((!PackOffsets || Index < PackOffsets->size()) &&
-             "number of elements in layout struct does not match number of "
-             "packoffset annotations");
-
-      // No PackOffset info at all, or have a valid packoffset/register(c#)
-      // annotations value -> layout the field.
-      const int PO = PackOffsets ? (*PackOffsets)[Index++] : -1;
-      if (!PackOffsets || PO != -1) {
-        if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO))
-          return nullptr;
-        Layout.push_back(FieldOffset);
-        LayoutElements.push_back(FieldType);
-        continue;
-      }
-      // Have PackOffset info, but there is no packoffset/register(cX)
-      // annotation on this field. Delay the layout until after all of the
-      // other elements with packoffsets/register(cX) are processed.
-      DelayLayoutFields.emplace_back(FD, LayoutElements.size());
-      // reserve space for this field in the layout vector and elements list
-      Layout.push_back(UINT_MAX);
-      LayoutElements.push_back(nullptr);
-    }
-  }
-
-  // process delayed layouts
-  for (auto I : DelayLayoutFields) {
-    const FieldDecl *FD = I.first;
-    const unsigned IndexInLayoutElements = I.second;
-    // the first item in layout vector is size, so we need to offset the index
-    // by 1
-    const unsigned IndexInLayout = IndexInLayoutElements + 1;
-    assert(Layout[IndexInLayout] == UINT_MAX &&
-           LayoutElements[IndexInLayoutElements] == nullptr);
-
-    if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
-      return nullptr;
-    Layout[IndexInLayout] = FieldOffset;
-    LayoutElements[IndexInLayoutElements] = FieldType;
-  }
-
-  // set the size of the buffer
-  Layout[0] = EndOffset;
-
-  // create the layout struct type; anonymous struct have empty name but
-  // non-empty qualified name
-  const auto *Decl = RT->castAsCXXRecordDecl();
-  std::string Name =
-      Decl->getName().empty() ? "anon" : Decl->getQualifiedNameAsString();
-  llvm::StructType *StructTy =
-      llvm::StructType::create(LayoutElements, Name, true);
-
-  // create target layout type
-  llvm::TargetExtType *NewLayoutTy = llvm::TargetExtType::get(
-      CGM.getLLVMContext(), LayoutTypeName, {StructTy}, Layout);
-  if (NewLayoutTy)
-    CGM.getHLSLRuntime().addHLSLBufferLayoutType(RT, NewLayoutTy);
-  return NewLayoutTy;
-}
-
-// The function converts a single field of HLSL Buffer to its corresponding
-// LLVM type and calculates it's layout. Any embedded structs (or
-// arrays of structs) are converted to target layout types as well.
-// The converted type is set to the FieldType parameter, the element
-// offset is set to the FieldOffset parameter. The EndOffset (=size of the
-// buffer) is also updated accordingly to the offset just after the placed
-// element, unless the incoming EndOffset already larger (may happen in case
-// of unsorted packoffset annotations).
-// Returns true if the conversion was successful.
-// The packoffset parameter contains the field's layout offset provided by the
-// user or -1 if there was no packoffset (or register(cX)) annotation.
-bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD,
-                                          unsigned &EndOffset,
-                                          unsigned &FieldOffset,
-                                          llvm::Type *&FieldType,
-                                          int Packoffset) {
-
-  // Size of element; for arrays this is a size of a single element in the
-  // array. Total array size of calculated as (ArrayCount-1) * ArrayStride +
-  // ElemSize.
-  unsigned ElemSize = 0;
-  unsigned ElemOffset = 0;
-  unsigned ArrayCount = 1;
-  unsigned ArrayStride = 0;
-
-  unsigned NextRowOffset = llvm::alignTo(EndOffset, CBufferRowSizeInBytes);
-
-  llvm::Type *ElemLayoutTy = nullptr;
-  QualType FieldTy = FD->getType();
-
-  if (FieldTy->isConstantArrayType()) {
-    // Unwrap array to find the element type and get combined array size.
-    QualType Ty = FieldTy;
-    while (Ty->isConstantArrayType()) {
-      auto *ArrayTy = CGM.getContext().getAsConstantArrayType(Ty);
-      ArrayCount *= ArrayTy->getSExtSize();
-      Ty = ArrayTy->getElementType();
-    }
-    // For array of structures, create a new array with a layout type
-    // instead of the structure type.
-    if (Ty->isStructureOrClassType()) {
-      llvm::Type *NewTy = cast<llvm::TargetExtType>(
-          createLayoutType(Ty->getAsCanonical<RecordType>()));
-      if (!NewTy)
-        return false;
-      assert(isa<llvm::TargetExtType>(NewTy) && "expected target type");
-      ElemSize = cast<llvm::TargetExtType>(NewTy)->getIntParameter(0);
-      ElemLayoutTy = createArrayWithNewElementType(
-          CGM, cast<ConstantArrayType>(FieldTy.getTypePtr()), NewTy);
-    } else {
-      // Array of vectors or scalars
-      ElemSize =
-          getScalarOrVectorSizeInBytes(CGM.getTypes().ConvertTypeForMem(Ty));
-      ElemLayoutTy = CGM.getTypes().ConvertTypeForMem(FieldTy);
-    }
-    ArrayStride = llvm::alignTo(ElemSize, CBufferRowSizeInBytes);
-    ElemOffset = (Packoffset != -1) ? Packoffset : NextRowOffset;
-
-  } else if (FieldTy->isStructureOrClassType()) {
-    // Create a layout type for the structure
-    ElemLayoutTy = createLayoutType(
-        cast<RecordType>(FieldTy->getAsCanonical<RecordType>()));
-    if (!ElemLayoutTy)
-      return false;
-    assert(isa<llvm::TargetExtType>(ElemLayoutTy) && "expected target type");
-    ElemSize = cast<llvm::TargetExtType>(ElemLayoutTy)->getIntParameter(0);
-    ElemOffset = (Packoffset != -1) ? Packoffset : NextRowOffset;
-
-  } else {
-    // scalar or vector - find element size and alignment
-    unsigned Align = 0;
-    ElemLayoutTy = CGM.getTypes().ConvertTypeForMem(FieldTy);
-    if (ElemLayoutTy->isVectorTy()) {
-      // align vectors by sub element size
-      const llvm::FixedVectorType *FVT =
-          cast<llvm::FixedVectorType>(ElemLayoutTy);
-      unsigned SubElemSize = FVT->getElementType()->getScalarSizeInBits() / 8;
-      ElemSize = FVT->getNumElements() * SubElemSize;
-      Align = SubElemSize;
-    } else {
-      assert(ElemLayoutTy->isIntegerTy() || ElemLayoutTy->isFloatingPointTy());
-      ElemSize = ElemLayoutTy->getScalarSizeInBits() / 8;
-      Align = ElemSize;
-    }
-
-    // calculate or get element offset for the vector or scalar
-    if (Packoffset != -1) {
-      ElemOffset = Packoffset;
-    } else {
-      ElemOffset = llvm::alignTo(EndOffset, Align);
-      // if the element does not fit, move it to the next row
-      if (ElemOffset + ElemSize > NextRowOffset)
-        ElemOffset = NextRowOffset;
-    }
-  }
-
-  // Update end offset of the layout; do not update it if the EndOffset
-  // is already bigger than the new value (which may happen with unordered
-  // packoffset annotations)
-  unsigned NewEndOffset =
-      ElemOffset + (ArrayCount - 1) * ArrayStride + ElemSize;
-  EndOffset = std::max<unsigned>(EndOffset, NewEndOffset);
-
-  // add the layout element and offset to the lists
-  FieldOffset = ElemOffset;
-  FieldType = ElemLayoutTy;
-  return true;
-}
-
-} // namespace CodeGen
-} // namespace clang
+//===- HLSLBufferLayoutBuilder.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 "HLSLBufferLayoutBuilder.h"
+#include "CGHLSLRuntime.h"
+#include "CodeGenModule.h"
+#include "clang/AST/Type.h"
+#include <climits>
+
+//===----------------------------------------------------------------------===//
+// Implementation of constant buffer layout common between DirectX and
+// SPIR/SPIR-V.
+//===----------------------------------------------------------------------===//
+
+using namespace clang;
+using namespace clang::CodeGen;
+using llvm::hlsl::CBufferRowSizeInBytes;
+
+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 getScalarOrVectorSizeInBytes(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
+
+namespace clang {
+namespace CodeGen {
+
+// Creates a layout type for given struct or class with HLSL constant buffer
+// layout taking into account PackOffsets, if provided.
+// Previously created layout types are cached by CGHLSLRuntime.
+//
+// The function iterates over all fields of the record type (including base
+// classes) and calls layoutField to converts each field to its corresponding
+// LLVM type and to calculate its HLSL constant buffer layout. Any embedded
+// structs (or arrays of structs) are converted to target layout types as well.
+//
+// When PackOffsets are specified the elements will be placed based on the
+// user-specified offsets. Not all elements must have a packoffset/register(c#)
+// annotation though. For those that don't, the PackOffsets array will contain
+// -1 value instead. These elements must be placed at the end of the layout
+// after all of the elements with specific offset.
+llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType(
+    const RecordType *RT, const llvm::SmallVector<int32_t> *PackOffsets) {
+
+  // check if we already have the layout type for this struct
+  if (llvm::TargetExtType *Ty =
+          CGM.getHLSLRuntime().getHLSLBufferLayoutType(RT))
+    return Ty;
+
+  SmallVector<unsigned> Layout;
+  SmallVector<llvm::Type *> LayoutElements;
+  unsigned Index = 0; // packoffset index
+  unsigned EndOffset = 0;
+
+  SmallVector<std::pair<const FieldDecl *, unsigned>> DelayLayoutFields;
+
+  // 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<CXXRecordDecl *> RecordDecls;
+  RecordDecls.push_back(RT->castAsCXXRecordDecl());
+  while (RecordDecls.back()->getNumBases()) {
+    CXXRecordDecl *D = RecordDecls.back();
+    assert(D->getNumBases() == 1 &&
+           "HLSL doesn't support multiple inheritance");
+    RecordDecls.push_back(D->bases_begin()->getType()->castAsCXXRecordDecl());
+  }
+
+  unsigned FieldOffset;
+  llvm::Type *FieldType;
+
+  while (!RecordDecls.empty()) {
+    const CXXRecordDecl *RD = RecordDecls.pop_back_val();
+
+    for (const auto *FD : RD->fields()) {
+      assert((!PackOffsets || Index < PackOffsets->size()) &&
+             "number of elements in layout struct does not match number of "
+             "packoffset annotations");
+
+      // No PackOffset info at all, or have a valid packoffset/register(c#)
+      // annotations value -> layout the field.
+      const int PO = PackOffsets ? (*PackOffsets)[Index++] : -1;
+      if (!PackOffsets || PO != -1) {
+        if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO))
+          return nullptr;
+        Layout.push_back(FieldOffset);
+        LayoutElements.push_back(FieldType);
+        continue;
+      }
+      // Have PackOffset info, but there is no packoffset/register(cX)
+      // annotation on this field. Delay the layout until after all of the
+      // other elements with packoffsets/register(cX) are processed.
+      DelayLayoutFields.emplace_back(FD, LayoutElements.size());
+      // reserve space for this field in the layout vector and elements list
+      Layout.push_back(UINT_MAX);
+      LayoutElements.push_back(nullptr);
+    }
+  }
+
+  // process delayed layouts
+  for (auto I : DelayLayoutFields) {
+    const FieldDecl *FD = I.first;
+    const unsigned IndexInLayoutElements = I.second;
+    // the first item in layout vector is size, so we need to offset the index
+    // by 1
+    const unsigned IndexInLayout = IndexInLayoutElements + 1;
+    assert(Layout[IndexInLayout] == UINT_MAX &&
+           LayoutElements[IndexInLayoutElements] == nullptr);
+
+    if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
+      return nullptr;
+    Layout[IndexInLayout] = FieldOffset;
+    LayoutElements[IndexInLayoutElements] = FieldType;
+  }
+
+  // set the size of the buffer
+  Layout[0] = EndOffset;
+
+  // create the layout struct type; anonymous struct have empty name but
+  // non-empty qualified name
+  const auto *Decl = RT->castAsCXXRecordDecl();
+  std::string Name =
+      Decl->getName().empty() ? "anon" : Decl->getQualifiedNameAsString();
+  llvm::StructType *StructTy =
+      llvm::StructType::create(LayoutElements, Name, true);
+
+  // create target layout type
+  llvm::TargetExtType *NewLayoutTy = llvm::TargetExtType::get(
+      CGM.getLLVMContext(), LayoutTypeName, {StructTy}, Layout);
+  if (NewLayoutTy)
+    CGM.getHLSLRuntime().addHLSLBufferLayoutType(RT, NewLayoutTy);
+  return NewLayoutTy;
+}
+
+// The function converts a single field of HLSL Buffer to its corresponding
+// LLVM type and calculates it's layout. Any embedded structs (or
+// arrays of structs) are converted to target layout types as well.
+// The converted type is set to the FieldType parameter, the element
+// offset is set to the FieldOffset parameter. The EndOffset (=size of the
+// buffer) is also updated accordingly to the offset just after the placed
+// element, unless the incoming EndOffset already larger (may happen in case
+// of unsorted packoffset annotations).
+// Returns true if the conversion was successful.
+// The packoffset parameter contains the field's layout offset provided by the
+// user or -1 if there was no packoffset (or register(cX)) annotation.
+bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD,
+                                          unsigned &EndOffset,
+                                          unsigned &FieldOffset,
+                                          llvm::Type *&FieldType,
+                                          int Packoffset) {
+
+  // Size of element; for arrays this is a size of a single element in the
+  // array. Total array size of calculated as (ArrayCount-1) * ArrayStride +
+  // ElemSize.
+  unsigned ElemSize = 0;
+  unsigned ElemOffset = 0;
+  unsigned ArrayCount = 1;
+  unsigned ArrayStride = 0;
+
+  unsigned NextRowOffset = llvm::alignTo(EndOffset, CBufferRowSizeInBytes);
+
+  llvm::Type *ElemLayoutTy = nullptr;
+  QualType FieldTy = FD->getType();
+
+  if (FieldTy->isConstantArrayType()) {
+    // Unwrap array to find the element type and get combined array size.
+    QualType Ty = FieldTy;
+    while (Ty->isConstantArrayType()) {
+      auto *ArrayTy = CGM.getContext().getAsConstantArrayType(Ty);
+      ArrayCount *= ArrayTy->getSExtSize();
+      Ty = ArrayTy->getElementType();
+    }
+    // For array of structures, create a new array with a layout type
+    // instead of the structure type.
+    if (Ty->isStruc...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/156930
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to