struct_packing_pass.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright (c) 2024 Epic Games, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #ifndef SOURCE_OPT_STRUCT_PACKING_PASS_
  15. #define SOURCE_OPT_STRUCT_PACKING_PASS_
  16. #include <unordered_map>
  17. #include "source/opt/ir_context.h"
  18. #include "source/opt/module.h"
  19. #include "source/opt/pass.h"
  20. namespace spvtools {
  21. namespace opt {
  22. // This pass re-assigns all field offsets under the specified packing rules.
  23. class StructPackingPass final : public Pass {
  24. public:
  25. enum class PackingRules {
  26. Undefined,
  27. Std140,
  28. Std140EnhancedLayout,
  29. Std430,
  30. Std430EnhancedLayout,
  31. HlslCbuffer,
  32. HlslCbufferPackOffset,
  33. Scalar,
  34. ScalarEnhancedLayout,
  35. };
  36. static PackingRules ParsePackingRuleFromString(const std::string& s);
  37. StructPackingPass(const char* structToPack, PackingRules rules);
  38. const char* name() const override { return "struct-packing"; }
  39. Status Process() override;
  40. IRContext::Analysis GetPreservedAnalyses() override {
  41. return IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG |
  42. IRContext::kAnalysisDominatorAnalysis |
  43. IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap |
  44. IRContext::kAnalysisScalarEvolution |
  45. IRContext::kAnalysisStructuredCFG | IRContext::kAnalysisConstants |
  46. IRContext::kAnalysisDebugInfo | IRContext::kAnalysisLiveness;
  47. }
  48. private:
  49. void buildConstantsMap();
  50. uint32_t findStructIdByName(const char* structName) const;
  51. std::vector<const analysis::Type*> findStructMemberTypes(
  52. const Instruction& structDef) const;
  53. Status assignStructMemberOffsets(
  54. uint32_t structIdToPack,
  55. const std::vector<const analysis::Type*>& structMemberTypes);
  56. uint32_t getPackedAlignment(const analysis::Type& type) const;
  57. uint32_t getPackedSize(const analysis::Type& type) const;
  58. uint32_t getPackedArrayStride(const analysis::Array& arrayType) const;
  59. uint32_t getArrayLength(const analysis::Array& arrayType) const;
  60. uint32_t getConstantInt(spv::Id id) const;
  61. private:
  62. std::string structToPack_;
  63. PackingRules packingRules_ = PackingRules::Undefined;
  64. std::unordered_map<spv::Id, Instruction*> constantsMap_;
  65. };
  66. } // namespace opt
  67. } // namespace spvtools
  68. #endif // SOURCE_OPT_STRUCT_PACKING_PASS_