| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717 |
- // Copyright (c) 2018 Google LLC.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include <string>
- #include "effcee/effcee.h"
- #include "gmock/gmock.h"
- #include "test/opt/pass_fixture.h"
- namespace spvtools {
- namespace opt {
- namespace {
- using FusionPassTest = PassTest<::testing::Test>;
- /*
- Generated from the following GLSL + --eliminate-local-multi-store
- #version 440 core
- void main() {
- int[10] a;
- int[10] b;
- for (int i = 0; i < 10; i++) {
- a[i] = a[i]*2;
- }
- for (int i = 0; i < 10; i++) {
- b[i] = a[i]+2;
- }
- }
- */
- TEST_F(FusionPassTest, SimpleFusion) {
- const std::string text = R"(
- ; CHECK: OpPhi
- ; CHECK: OpLoad
- ; CHECK: OpStore
- ; CHECK-NOT: OpPhi
- ; CHECK: OpLoad
- ; CHECK: OpStore
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 440
- OpName %4 "main"
- OpName %8 "i"
- OpName %23 "a"
- OpName %34 "i"
- OpName %42 "b"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 10
- %17 = OpTypeBool
- %19 = OpTypeInt 32 0
- %20 = OpConstant %19 10
- %21 = OpTypeArray %6 %20
- %22 = OpTypePointer Function %21
- %28 = OpConstant %6 2
- %32 = OpConstant %6 1
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- %23 = OpVariable %22 Function
- %34 = OpVariable %7 Function
- %42 = OpVariable %22 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- %51 = OpPhi %6 %9 %5 %33 %13
- OpLoopMerge %12 %13 None
- OpBranch %14
- %14 = OpLabel
- %18 = OpSLessThan %17 %51 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- %26 = OpAccessChain %7 %23 %51
- %27 = OpLoad %6 %26
- %29 = OpIMul %6 %27 %28
- %30 = OpAccessChain %7 %23 %51
- OpStore %30 %29
- OpBranch %13
- %13 = OpLabel
- %33 = OpIAdd %6 %51 %32
- OpStore %8 %33
- OpBranch %10
- %12 = OpLabel
- OpStore %34 %9
- OpBranch %35
- %35 = OpLabel
- %52 = OpPhi %6 %9 %12 %50 %38
- OpLoopMerge %37 %38 None
- OpBranch %39
- %39 = OpLabel
- %41 = OpSLessThan %17 %52 %16
- OpBranchConditional %41 %36 %37
- %36 = OpLabel
- %45 = OpAccessChain %7 %23 %52
- %46 = OpLoad %6 %45
- %47 = OpIAdd %6 %46 %28
- %48 = OpAccessChain %7 %42 %52
- OpStore %48 %47
- OpBranch %38
- %38 = OpLabel
- %50 = OpIAdd %6 %52 %32
- OpStore %34 %50
- OpBranch %35
- %37 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
- }
- /*
- Generated from the following GLSL + --eliminate-local-multi-store
- #version 440 core
- void main() {
- int[10] a;
- int[10] b;
- int[10] c;
- for (int i = 0; i < 10; i++) {
- a[i] = b[i] + 1;
- }
- for (int i = 0; i < 10; i++) {
- c[i] = a[i] + 2;
- }
- for (int i = 0; i < 10; i++) {
- b[i] = c[i] + 10;
- }
- }
- */
- TEST_F(FusionPassTest, ThreeLoopsFused) {
- const std::string text = R"(
- ; CHECK: OpPhi
- ; CHECK: OpLoad
- ; CHECK: OpStore
- ; CHECK-NOT: OpPhi
- ; CHECK: OpLoad
- ; CHECK: OpStore
- ; CHECK-NOT: OpPhi
- ; CHECK: OpLoad
- ; CHECK: OpStore
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 440
- OpName %4 "main"
- OpName %8 "i"
- OpName %23 "a"
- OpName %25 "b"
- OpName %34 "i"
- OpName %42 "c"
- OpName %52 "i"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 10
- %17 = OpTypeBool
- %19 = OpTypeInt 32 0
- %20 = OpConstant %19 10
- %21 = OpTypeArray %6 %20
- %22 = OpTypePointer Function %21
- %29 = OpConstant %6 1
- %47 = OpConstant %6 2
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- %23 = OpVariable %22 Function
- %25 = OpVariable %22 Function
- %34 = OpVariable %7 Function
- %42 = OpVariable %22 Function
- %52 = OpVariable %7 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- %68 = OpPhi %6 %9 %5 %33 %13
- OpLoopMerge %12 %13 None
- OpBranch %14
- %14 = OpLabel
- %18 = OpSLessThan %17 %68 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- %27 = OpAccessChain %7 %25 %68
- %28 = OpLoad %6 %27
- %30 = OpIAdd %6 %28 %29
- %31 = OpAccessChain %7 %23 %68
- OpStore %31 %30
- OpBranch %13
- %13 = OpLabel
- %33 = OpIAdd %6 %68 %29
- OpStore %8 %33
- OpBranch %10
- %12 = OpLabel
- OpStore %34 %9
- OpBranch %35
- %35 = OpLabel
- %69 = OpPhi %6 %9 %12 %51 %38
- OpLoopMerge %37 %38 None
- OpBranch %39
- %39 = OpLabel
- %41 = OpSLessThan %17 %69 %16
- OpBranchConditional %41 %36 %37
- %36 = OpLabel
- %45 = OpAccessChain %7 %23 %69
- %46 = OpLoad %6 %45
- %48 = OpIAdd %6 %46 %47
- %49 = OpAccessChain %7 %42 %69
- OpStore %49 %48
- OpBranch %38
- %38 = OpLabel
- %51 = OpIAdd %6 %69 %29
- OpStore %34 %51
- OpBranch %35
- %37 = OpLabel
- OpStore %52 %9
- OpBranch %53
- %53 = OpLabel
- %70 = OpPhi %6 %9 %37 %67 %56
- OpLoopMerge %55 %56 None
- OpBranch %57
- %57 = OpLabel
- %59 = OpSLessThan %17 %70 %16
- OpBranchConditional %59 %54 %55
- %54 = OpLabel
- %62 = OpAccessChain %7 %42 %70
- %63 = OpLoad %6 %62
- %64 = OpIAdd %6 %63 %16
- %65 = OpAccessChain %7 %25 %70
- OpStore %65 %64
- OpBranch %56
- %56 = OpLabel
- %67 = OpIAdd %6 %70 %29
- OpStore %52 %67
- OpBranch %53
- %55 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
- }
- /*
- Generated from the following GLSL + --eliminate-local-multi-store
- #version 440 core
- void main() {
- int[10][10] a;
- int[10][10] b;
- int[10][10] c;
- // Legal both
- for (int i = 0; i < 10; i++) {
- for (int j = 0; j < 10; j++) {
- c[i][j] = a[i][j] + 2;
- }
- }
- for (int i = 0; i < 10; i++) {
- for (int j = 0; j < 10; j++) {
- b[i][j] = c[i][j] + 10;
- }
- }
- }
- */
- TEST_F(FusionPassTest, NestedLoopsFused) {
- const std::string text = R"(
- ; CHECK: OpPhi
- ; CHECK: OpPhi
- ; CHECK: OpLoad
- ; CHECK: OpStore
- ; CHECK-NOT: OpPhi
- ; CHECK: OpLoad
- ; CHECK: OpStore
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 440
- OpName %4 "main"
- OpName %8 "i"
- OpName %19 "j"
- OpName %32 "c"
- OpName %35 "a"
- OpName %48 "i"
- OpName %56 "j"
- OpName %64 "b"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 10
- %17 = OpTypeBool
- %27 = OpTypeInt 32 0
- %28 = OpConstant %27 10
- %29 = OpTypeArray %6 %28
- %30 = OpTypeArray %29 %28
- %31 = OpTypePointer Function %30
- %40 = OpConstant %6 2
- %44 = OpConstant %6 1
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- %19 = OpVariable %7 Function
- %32 = OpVariable %31 Function
- %35 = OpVariable %31 Function
- %48 = OpVariable %7 Function
- %56 = OpVariable %7 Function
- %64 = OpVariable %31 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- %77 = OpPhi %6 %9 %5 %47 %13
- OpLoopMerge %12 %13 None
- OpBranch %14
- %14 = OpLabel
- %18 = OpSLessThan %17 %77 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- OpStore %19 %9
- OpBranch %20
- %20 = OpLabel
- %81 = OpPhi %6 %9 %11 %45 %23
- OpLoopMerge %22 %23 None
- OpBranch %24
- %24 = OpLabel
- %26 = OpSLessThan %17 %81 %16
- OpBranchConditional %26 %21 %22
- %21 = OpLabel
- %38 = OpAccessChain %7 %35 %77 %81
- %39 = OpLoad %6 %38
- %41 = OpIAdd %6 %39 %40
- %42 = OpAccessChain %7 %32 %77 %81
- OpStore %42 %41
- OpBranch %23
- %23 = OpLabel
- %45 = OpIAdd %6 %81 %44
- OpStore %19 %45
- OpBranch %20
- %22 = OpLabel
- OpBranch %13
- %13 = OpLabel
- %47 = OpIAdd %6 %77 %44
- OpStore %8 %47
- OpBranch %10
- %12 = OpLabel
- OpStore %48 %9
- OpBranch %49
- %49 = OpLabel
- %78 = OpPhi %6 %9 %12 %76 %52
- OpLoopMerge %51 %52 None
- OpBranch %53
- %53 = OpLabel
- %55 = OpSLessThan %17 %78 %16
- OpBranchConditional %55 %50 %51
- %50 = OpLabel
- OpStore %56 %9
- OpBranch %57
- %57 = OpLabel
- %79 = OpPhi %6 %9 %50 %74 %60
- OpLoopMerge %59 %60 None
- OpBranch %61
- %61 = OpLabel
- %63 = OpSLessThan %17 %79 %16
- OpBranchConditional %63 %58 %59
- %58 = OpLabel
- %69 = OpAccessChain %7 %32 %78 %79
- %70 = OpLoad %6 %69
- %71 = OpIAdd %6 %70 %16
- %72 = OpAccessChain %7 %64 %78 %79
- OpStore %72 %71
- OpBranch %60
- %60 = OpLabel
- %74 = OpIAdd %6 %79 %44
- OpStore %56 %74
- OpBranch %57
- %59 = OpLabel
- OpBranch %52
- %52 = OpLabel
- %76 = OpIAdd %6 %78 %44
- OpStore %48 %76
- OpBranch %49
- %51 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
- }
- /*
- Generated from the following GLSL + --eliminate-local-multi-store
- #version 440 core
- void main() {
- // Can't fuse, different step
- for (int i = 0; i < 10; i++) {}
- for (int j = 0; j < 10; j=j+2) {}
- }
- */
- TEST_F(FusionPassTest, Incompatible) {
- const std::string text = R"(
- ; CHECK: OpPhi
- ; CHECK-NEXT: OpLoopMerge
- ; CHECK: OpPhi
- ; CHECK-NEXT: OpLoopMerge
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 440
- OpName %4 "main"
- OpName %8 "i"
- OpName %22 "j"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 10
- %17 = OpTypeBool
- %20 = OpConstant %6 1
- %31 = OpConstant %6 2
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- %22 = OpVariable %7 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- %33 = OpPhi %6 %9 %5 %21 %13
- OpLoopMerge %12 %13 None
- OpBranch %14
- %14 = OpLabel
- %18 = OpSLessThan %17 %33 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- OpBranch %13
- %13 = OpLabel
- %21 = OpIAdd %6 %33 %20
- OpStore %8 %21
- OpBranch %10
- %12 = OpLabel
- OpStore %22 %9
- OpBranch %23
- %23 = OpLabel
- %34 = OpPhi %6 %9 %12 %32 %26
- OpLoopMerge %25 %26 None
- OpBranch %27
- %27 = OpLabel
- %29 = OpSLessThan %17 %34 %16
- OpBranchConditional %29 %24 %25
- %24 = OpLabel
- OpBranch %26
- %26 = OpLabel
- %32 = OpIAdd %6 %34 %31
- OpStore %22 %32
- OpBranch %23
- %25 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
- }
- /*
- Generated from the following GLSL + --eliminate-local-multi-store
- #version 440 core
- void main() {
- int[10] a;
- int[10] b;
- int[10] c;
- // Illegal, loop-independent dependence will become a
- // backward loop-carried antidependence
- for (int i = 0; i < 10; i++) {
- a[i] = b[i] + 1;
- }
- for (int i = 0; i < 10; i++) {
- c[i] = a[i+1] + 2;
- }
- }
- */
- TEST_F(FusionPassTest, Illegal) {
- std::string text = R"(
- ; CHECK: OpPhi
- ; CHECK-NEXT: OpLoopMerge
- ; CHECK: OpLoad
- ; CHECK: OpStore
- ; CHECK: OpPhi
- ; CHECK-NEXT: OpLoopMerge
- ; CHECK: OpLoad
- ; CHECK: OpStore
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 440
- OpName %4 "main"
- OpName %8 "i"
- OpName %23 "a"
- OpName %25 "b"
- OpName %34 "i"
- OpName %42 "c"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 10
- %17 = OpTypeBool
- %19 = OpTypeInt 32 0
- %20 = OpConstant %19 10
- %21 = OpTypeArray %6 %20
- %22 = OpTypePointer Function %21
- %29 = OpConstant %6 1
- %48 = OpConstant %6 2
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- %23 = OpVariable %22 Function
- %25 = OpVariable %22 Function
- %34 = OpVariable %7 Function
- %42 = OpVariable %22 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- %53 = OpPhi %6 %9 %5 %33 %13
- OpLoopMerge %12 %13 None
- OpBranch %14
- %14 = OpLabel
- %18 = OpSLessThan %17 %53 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- %27 = OpAccessChain %7 %25 %53
- %28 = OpLoad %6 %27
- %30 = OpIAdd %6 %28 %29
- %31 = OpAccessChain %7 %23 %53
- OpStore %31 %30
- OpBranch %13
- %13 = OpLabel
- %33 = OpIAdd %6 %53 %29
- OpStore %8 %33
- OpBranch %10
- %12 = OpLabel
- OpStore %34 %9
- OpBranch %35
- %35 = OpLabel
- %54 = OpPhi %6 %9 %12 %52 %38
- OpLoopMerge %37 %38 None
- OpBranch %39
- %39 = OpLabel
- %41 = OpSLessThan %17 %54 %16
- OpBranchConditional %41 %36 %37
- %36 = OpLabel
- %45 = OpIAdd %6 %54 %29
- %46 = OpAccessChain %7 %23 %45
- %47 = OpLoad %6 %46
- %49 = OpIAdd %6 %47 %48
- %50 = OpAccessChain %7 %42 %54
- OpStore %50 %49
- OpBranch %38
- %38 = OpLabel
- %52 = OpIAdd %6 %54 %29
- OpStore %34 %52
- OpBranch %35
- %37 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
- }
- /*
- Generated from the following GLSL + --eliminate-local-multi-store
- #version 440 core
- void main() {
- int[10] a;
- int[10] b;
- for (int i = 0; i < 10; i++) {
- a[i] = a[i]*2;
- }
- for (int i = 0; i < 10; i++) {
- b[i] = a[i]+2;
- }
- }
- */
- TEST_F(FusionPassTest, TooManyRegisters) {
- const std::string text = R"(
- ; CHECK: OpPhi
- ; CHECK-NEXT: OpLoopMerge
- ; CHECK: OpLoad
- ; CHECK: OpStore
- ; CHECK: OpPhi
- ; CHECK-NEXT: OpLoopMerge
- ; CHECK: OpLoad
- ; CHECK: OpStore
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 440
- OpName %4 "main"
- OpName %8 "i"
- OpName %23 "a"
- OpName %34 "i"
- OpName %42 "b"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 10
- %17 = OpTypeBool
- %19 = OpTypeInt 32 0
- %20 = OpConstant %19 10
- %21 = OpTypeArray %6 %20
- %22 = OpTypePointer Function %21
- %28 = OpConstant %6 2
- %32 = OpConstant %6 1
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- %23 = OpVariable %22 Function
- %34 = OpVariable %7 Function
- %42 = OpVariable %22 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- %51 = OpPhi %6 %9 %5 %33 %13
- OpLoopMerge %12 %13 None
- OpBranch %14
- %14 = OpLabel
- %18 = OpSLessThan %17 %51 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- %26 = OpAccessChain %7 %23 %51
- %27 = OpLoad %6 %26
- %29 = OpIMul %6 %27 %28
- %30 = OpAccessChain %7 %23 %51
- OpStore %30 %29
- OpBranch %13
- %13 = OpLabel
- %33 = OpIAdd %6 %51 %32
- OpStore %8 %33
- OpBranch %10
- %12 = OpLabel
- OpStore %34 %9
- OpBranch %35
- %35 = OpLabel
- %52 = OpPhi %6 %9 %12 %50 %38
- OpLoopMerge %37 %38 None
- OpBranch %39
- %39 = OpLabel
- %41 = OpSLessThan %17 %52 %16
- OpBranchConditional %41 %36 %37
- %36 = OpLabel
- %45 = OpAccessChain %7 %23 %52
- %46 = OpLoad %6 %45
- %47 = OpIAdd %6 %46 %28
- %48 = OpAccessChain %7 %42 %52
- OpStore %48 %47
- OpBranch %38
- %38 = OpLabel
- %50 = OpIAdd %6 %52 %32
- OpStore %34 %50
- OpBranch %35
- %37 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<LoopFusionPass>(text, true, 5);
- }
- } // namespace
- } // namespace opt
- } // namespace spvtools
|