common_dominators.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright (c) 2018 Google LLC
  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. #include <memory>
  15. #include "gtest/gtest.h"
  16. #include "source/opt/build_module.h"
  17. #include "source/opt/ir_context.h"
  18. namespace spvtools {
  19. namespace opt {
  20. namespace {
  21. using CommonDominatorsTest = ::testing::Test;
  22. const std::string text = R"(
  23. OpCapability Shader
  24. OpMemoryModel Logical GLSL450
  25. OpEntryPoint Fragment %func "func"
  26. %void = OpTypeVoid
  27. %bool = OpTypeBool
  28. %true = OpConstantTrue %bool
  29. %functy = OpTypeFunction %void
  30. %func = OpFunction %void None %functy
  31. %1 = OpLabel
  32. OpBranch %2
  33. %2 = OpLabel
  34. OpLoopMerge %3 %4 None
  35. OpBranch %5
  36. %5 = OpLabel
  37. OpBranchConditional %true %3 %4
  38. %4 = OpLabel
  39. OpBranch %2
  40. %3 = OpLabel
  41. OpSelectionMerge %6 None
  42. OpBranchConditional %true %7 %8
  43. %7 = OpLabel
  44. OpBranch %6
  45. %8 = OpLabel
  46. OpBranch %9
  47. %9 = OpLabel
  48. OpBranch %6
  49. %6 = OpLabel
  50. OpBranch %10
  51. %11 = OpLabel
  52. OpBranch %10
  53. %10 = OpLabel
  54. OpReturn
  55. OpFunctionEnd
  56. )";
  57. BasicBlock* GetBlock(uint32_t id, std::unique_ptr<IRContext>& context) {
  58. return context->get_instr_block(context->get_def_use_mgr()->GetDef(id));
  59. }
  60. TEST(CommonDominatorsTest, SameBlock) {
  61. std::unique_ptr<IRContext> context =
  62. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
  63. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  64. EXPECT_NE(nullptr, context);
  65. DominatorAnalysis* analysis =
  66. context->GetDominatorAnalysis(&*context->module()->begin());
  67. for (auto& block : *context->module()->begin()) {
  68. EXPECT_EQ(&block, analysis->CommonDominator(&block, &block));
  69. }
  70. }
  71. TEST(CommonDominatorsTest, ParentAndChild) {
  72. std::unique_ptr<IRContext> context =
  73. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
  74. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  75. EXPECT_NE(nullptr, context);
  76. DominatorAnalysis* analysis =
  77. context->GetDominatorAnalysis(&*context->module()->begin());
  78. EXPECT_EQ(
  79. GetBlock(1u, context),
  80. analysis->CommonDominator(GetBlock(1u, context), GetBlock(2u, context)));
  81. EXPECT_EQ(
  82. GetBlock(2u, context),
  83. analysis->CommonDominator(GetBlock(2u, context), GetBlock(5u, context)));
  84. EXPECT_EQ(
  85. GetBlock(1u, context),
  86. analysis->CommonDominator(GetBlock(1u, context), GetBlock(5u, context)));
  87. }
  88. TEST(CommonDominatorsTest, BranchSplit) {
  89. std::unique_ptr<IRContext> context =
  90. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
  91. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  92. EXPECT_NE(nullptr, context);
  93. DominatorAnalysis* analysis =
  94. context->GetDominatorAnalysis(&*context->module()->begin());
  95. EXPECT_EQ(
  96. GetBlock(3u, context),
  97. analysis->CommonDominator(GetBlock(7u, context), GetBlock(8u, context)));
  98. EXPECT_EQ(
  99. GetBlock(3u, context),
  100. analysis->CommonDominator(GetBlock(7u, context), GetBlock(9u, context)));
  101. }
  102. TEST(CommonDominatorsTest, LoopContinueAndMerge) {
  103. std::unique_ptr<IRContext> context =
  104. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
  105. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  106. EXPECT_NE(nullptr, context);
  107. DominatorAnalysis* analysis =
  108. context->GetDominatorAnalysis(&*context->module()->begin());
  109. EXPECT_EQ(
  110. GetBlock(5u, context),
  111. analysis->CommonDominator(GetBlock(3u, context), GetBlock(4u, context)));
  112. }
  113. TEST(CommonDominatorsTest, NoCommonDominator) {
  114. std::unique_ptr<IRContext> context =
  115. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
  116. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  117. EXPECT_NE(nullptr, context);
  118. DominatorAnalysis* analysis =
  119. context->GetDominatorAnalysis(&*context->module()->begin());
  120. EXPECT_EQ(nullptr, analysis->CommonDominator(GetBlock(10u, context),
  121. GetBlock(11u, context)));
  122. EXPECT_EQ(nullptr, analysis->CommonDominator(GetBlock(11u, context),
  123. GetBlock(6u, context)));
  124. }
  125. } // namespace
  126. } // namespace opt
  127. } // namespace spvtools