Home | History | Annotate | Download | only in dominator_tree
      1 // Copyright (c) 2017 Google 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 
     15 #include <memory>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "gmock/gmock.h"
     20 #include "source/opt/dominator_analysis.h"
     21 #include "source/opt/pass.h"
     22 #include "test/opt/assembly_builder.h"
     23 #include "test/opt/function_utils.h"
     24 #include "test/opt/pass_fixture.h"
     25 #include "test/opt/pass_utils.h"
     26 
     27 namespace spvtools {
     28 namespace opt {
     29 namespace {
     30 
     31 using ::testing::UnorderedElementsAre;
     32 using PassClassTest = PassTest<::testing::Test>;
     33 
     34 /*
     35   Generated from the following GLSL
     36 #version 440 core
     37 layout(location = 0) out vec4 c;
     38 layout(location = 1)in vec4 in_val;
     39 void main(){
     40   if ( in_val.x < 10) {
     41     int z = 0;
     42     int i = 0;
     43     for (i = 0; i < in_val.y; ++i) {
     44         z += i;
     45     }
     46     c = vec4(i,i,i,i);
     47   } else {
     48         c = vec4(1,1,1,1);
     49   }
     50 }
     51 */
     52 TEST_F(PassClassTest, BasicVisitFromEntryPoint) {
     53   const std::string text = R"(
     54                OpCapability Shader
     55           %1 = OpExtInstImport "GLSL.std.450"
     56                OpMemoryModel Logical GLSL450
     57                OpEntryPoint Fragment %4 "main" %9 %43
     58                OpExecutionMode %4 OriginUpperLeft
     59                OpSource GLSL 440
     60                OpName %4 "main"
     61                OpName %9 "in_val"
     62                OpName %22 "z"
     63                OpName %24 "i"
     64                OpName %43 "c"
     65                OpDecorate %9 Location 1
     66                OpDecorate %43 Location 0
     67           %2 = OpTypeVoid
     68           %3 = OpTypeFunction %2
     69           %6 = OpTypeFloat 32
     70           %7 = OpTypeVector %6 4
     71           %8 = OpTypePointer Input %7
     72           %9 = OpVariable %8 Input
     73          %10 = OpTypeInt 32 0
     74          %11 = OpConstant %10 0
     75          %12 = OpTypePointer Input %6
     76          %15 = OpConstant %6 10
     77          %16 = OpTypeBool
     78          %20 = OpTypeInt 32 1
     79          %21 = OpTypePointer Function %20
     80          %23 = OpConstant %20 0
     81          %32 = OpConstant %10 1
     82          %40 = OpConstant %20 1
     83          %42 = OpTypePointer Output %7
     84          %43 = OpVariable %42 Output
     85          %54 = OpConstant %6 1
     86          %55 = OpConstantComposite %7 %54 %54 %54 %54
     87           %4 = OpFunction %2 None %3
     88           %5 = OpLabel
     89          %22 = OpVariable %21 Function
     90          %24 = OpVariable %21 Function
     91          %13 = OpAccessChain %12 %9 %11
     92          %14 = OpLoad %6 %13
     93          %17 = OpFOrdLessThan %16 %14 %15
     94                OpSelectionMerge %19 None
     95                OpBranchConditional %17 %18 %53
     96          %18 = OpLabel
     97                OpStore %22 %23
     98                OpStore %24 %23
     99                OpStore %24 %23
    100                OpBranch %25
    101          %25 = OpLabel
    102                OpLoopMerge %27 %28 None
    103                OpBranch %29
    104          %29 = OpLabel
    105          %30 = OpLoad %20 %24
    106          %31 = OpConvertSToF %6 %30
    107          %33 = OpAccessChain %12 %9 %32
    108          %34 = OpLoad %6 %33
    109          %35 = OpFOrdLessThan %16 %31 %34
    110                OpBranchConditional %35 %26 %27
    111          %26 = OpLabel
    112          %36 = OpLoad %20 %24
    113          %37 = OpLoad %20 %22
    114          %38 = OpIAdd %20 %37 %36
    115                OpStore %22 %38
    116                OpBranch %28
    117          %28 = OpLabel
    118          %39 = OpLoad %20 %24
    119          %41 = OpIAdd %20 %39 %40
    120                OpStore %24 %41
    121                OpBranch %25
    122          %27 = OpLabel
    123          %44 = OpLoad %20 %24
    124          %45 = OpConvertSToF %6 %44
    125          %46 = OpLoad %20 %24
    126          %47 = OpConvertSToF %6 %46
    127          %48 = OpLoad %20 %24
    128          %49 = OpConvertSToF %6 %48
    129          %50 = OpLoad %20 %24
    130          %51 = OpConvertSToF %6 %50
    131          %52 = OpCompositeConstruct %7 %45 %47 %49 %51
    132                OpStore %43 %52
    133                OpBranch %19
    134          %53 = OpLabel
    135                OpStore %43 %55
    136                OpBranch %19
    137          %19 = OpLabel
    138                OpReturn
    139                OpFunctionEnd
    140 )";
    141   // clang-format on
    142   std::unique_ptr<IRContext> context =
    143       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
    144                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
    145   Module* module = context->module();
    146   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
    147                              << text << std::endl;
    148 
    149   const Function* f = spvtest::GetFunction(module, 4);
    150   CFG cfg(module);
    151   PostDominatorAnalysis* analysis = context->GetPostDominatorAnalysis(f);
    152 
    153   EXPECT_TRUE(analysis->Dominates(19, 18));
    154   EXPECT_TRUE(analysis->Dominates(19, 5));
    155   EXPECT_TRUE(analysis->Dominates(19, 53));
    156   EXPECT_TRUE(analysis->Dominates(19, 19));
    157   EXPECT_TRUE(analysis->Dominates(19, 25));
    158   EXPECT_TRUE(analysis->Dominates(19, 29));
    159   EXPECT_TRUE(analysis->Dominates(19, 27));
    160   EXPECT_TRUE(analysis->Dominates(19, 26));
    161   EXPECT_TRUE(analysis->Dominates(19, 28));
    162 
    163   EXPECT_TRUE(analysis->Dominates(27, 18));
    164   EXPECT_TRUE(analysis->Dominates(27, 25));
    165   EXPECT_TRUE(analysis->Dominates(27, 29));
    166   EXPECT_TRUE(analysis->Dominates(27, 27));
    167   EXPECT_TRUE(analysis->Dominates(27, 26));
    168   EXPECT_TRUE(analysis->Dominates(27, 28));
    169 
    170   EXPECT_FALSE(analysis->Dominates(27, 19));
    171   EXPECT_FALSE(analysis->Dominates(27, 5));
    172   EXPECT_FALSE(analysis->Dominates(27, 53));
    173 
    174   EXPECT_FALSE(analysis->StrictlyDominates(19, 19));
    175 
    176   EXPECT_TRUE(analysis->StrictlyDominates(19, 18));
    177   EXPECT_TRUE(analysis->StrictlyDominates(19, 5));
    178   EXPECT_TRUE(analysis->StrictlyDominates(19, 53));
    179   EXPECT_TRUE(analysis->StrictlyDominates(19, 25));
    180   EXPECT_TRUE(analysis->StrictlyDominates(19, 29));
    181   EXPECT_TRUE(analysis->StrictlyDominates(19, 27));
    182   EXPECT_TRUE(analysis->StrictlyDominates(19, 26));
    183   EXPECT_TRUE(analysis->StrictlyDominates(19, 28));
    184 
    185   // These would be expected true for a normal, non post, dominator tree
    186   EXPECT_FALSE(analysis->Dominates(5, 18));
    187   EXPECT_FALSE(analysis->Dominates(5, 53));
    188   EXPECT_FALSE(analysis->Dominates(5, 19));
    189   EXPECT_FALSE(analysis->Dominates(5, 25));
    190   EXPECT_FALSE(analysis->Dominates(5, 29));
    191   EXPECT_FALSE(analysis->Dominates(5, 27));
    192   EXPECT_FALSE(analysis->Dominates(5, 26));
    193   EXPECT_FALSE(analysis->Dominates(5, 28));
    194 
    195   EXPECT_FALSE(analysis->StrictlyDominates(5, 18));
    196   EXPECT_FALSE(analysis->StrictlyDominates(5, 53));
    197   EXPECT_FALSE(analysis->StrictlyDominates(5, 19));
    198   EXPECT_FALSE(analysis->StrictlyDominates(5, 25));
    199   EXPECT_FALSE(analysis->StrictlyDominates(5, 29));
    200   EXPECT_FALSE(analysis->StrictlyDominates(5, 27));
    201   EXPECT_FALSE(analysis->StrictlyDominates(5, 26));
    202   EXPECT_FALSE(analysis->StrictlyDominates(5, 28));
    203 }
    204 
    205 }  // namespace
    206 }  // namespace opt
    207 }  // namespace spvtools
    208