common_dominators.cpp 4.4 KB

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