AlignmentSizeCalculator.h 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. //===--- AlignmentSizeCalculator.h - Alignment And Size Calc -----*- C++ -*-==//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef LLVM_CLANG_LIB_SPIRV_ALIGNMENTSIZECALCULATOR_H
  10. #define LLVM_CLANG_LIB_SPIRV_ALIGNMENTSIZECALCULATOR_H
  11. #include "dxc/Support/SPIRVOptions.h"
  12. #include "clang/AST/ASTContext.h"
  13. #include "clang/SPIRV/AstTypeProbe.h"
  14. namespace clang {
  15. namespace spirv {
  16. /// The class responsible to translate Clang frontend types into SPIR-V types.
  17. class AlignmentSizeCalculator {
  18. public:
  19. AlignmentSizeCalculator(ASTContext &astCtx, const SpirvCodeGenOptions &opts)
  20. : astContext(astCtx), spvOptions(opts) {}
  21. /// \brief Returns the alignment and size in bytes for the given type
  22. /// according to the given LayoutRule. If the caller has information about
  23. /// whether the type is a row-major matrix, that should also be passed in. If
  24. /// this information is not provided, the function tries to find any majorness
  25. /// attributes on the given type and use it.
  26. ///
  27. /// If the type is an array/matrix type, writes the array/matrix stride to
  28. /// stride.
  29. ///
  30. /// Note that the size returned is not exactly how many bytes the type
  31. /// will occupy in memory; rather it is used in conjunction with alignment
  32. /// to get the next available location (alignment + size), which means
  33. /// size contains post-paddings required by the given type.
  34. std::pair<uint32_t, uint32_t>
  35. getAlignmentAndSize(QualType type, SpirvLayoutRule rule,
  36. llvm::Optional<bool> isRowMajor, uint32_t *stride);
  37. /// \brief Aligns currentOffset properly to allow packing vectors in the HLSL
  38. /// way: using the element type's alignment as the vector alignment, as long
  39. /// as there is no improper straddle.
  40. /// fieldSize and fieldAlignment are the original size and alignment
  41. /// calculated without considering the HLSL vector relaxed rule.
  42. void alignUsingHLSLRelaxedLayout(QualType fieldType, uint32_t fieldSize,
  43. uint32_t fieldAlignment,
  44. uint32_t *currentOffset);
  45. /// \brief Returns true if we use row-major matrix for type. Otherwise,
  46. /// returns false.
  47. bool useRowMajor(llvm::Optional<bool> isRowMajor, clang::QualType type) {
  48. return isRowMajor.hasValue() ? isRowMajor.getValue()
  49. : isRowMajorMatrix(spvOptions, type);
  50. }
  51. private:
  52. /// Emits error to the diagnostic engine associated with this visitor.
  53. template <unsigned N>
  54. DiagnosticBuilder emitError(const char (&message)[N],
  55. SourceLocation srcLoc = {}) {
  56. const auto diagId = astContext.getDiagnostics().getCustomDiagID(
  57. clang::DiagnosticsEngine::Error, message);
  58. return astContext.getDiagnostics().Report(srcLoc, diagId);
  59. }
  60. private:
  61. ASTContext &astContext; /// AST context
  62. const SpirvCodeGenOptions &spvOptions; /// SPIR-V options
  63. };
  64. } // end namespace spirv
  65. } // end namespace clang
  66. #endif // LLVM_CLANG_LIB_SPIRV_ALIGNMENTSIZECALCULATOR_H