1# Copyright (C) 2018 The Android Open Source Project
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.class public LPeelUnroll;
16
17.super Ljava/lang/Object;
18
19## CHECK-START: void PeelUnroll.unrollingWhile(int[]) loop_optimization (before)
20## CHECK-DAG: <<Array:l\d+>>    ParameterValue                            loop:none
21## CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
22## CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
23## CHECK-DAG: <<Const2:i\d+>>   IntConstant 2                             loop:none
24## CHECK-DAG: <<Const128:i\d+>> IntConstant 128                           loop:none
25## CHECK-DAG: <<Limit:i\d+>>    IntConstant 4094                          loop:none
26## CHECK-DAG: <<PhiI:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
27## CHECK-DAG: <<PhiS:i\d+>>     Phi [<<Const128>>,{{i\d+}}]               loop:<<Loop>>      outer_loop:none
28## CHECK-DAG: <<AddI:i\d+>>     Add [<<PhiI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
29## CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<PhiI>>,<<Limit>>]   loop:<<Loop>>      outer_loop:none
30## CHECK-DAG: <<If:v\d+>>       If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
31## CHECK-DAG: <<Rem:i\d+>>      Rem [<<AddI>>,<<Const2>>]                 loop:<<Loop>>      outer_loop:none
32## CHECK-DAG: <<NE:z\d+>>       NotEqual [<<Rem>>,<<Const0>>]             loop:<<Loop>>      outer_loop:none
33## CHECK-DAG:                   If [<<NE>>]                               loop:<<Loop>>      outer_loop:none
34## CHECK-DAG: <<AddS:i\d+>>     Add [<<PhiS>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
35## CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
36## CHECK-DAG:                   Phi [<<PhiS>>,<<AddS>>]                   loop:<<Loop>>      outer_loop:none
37
38## CHECK-NOT:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
39## CHECK-NOT:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
40
41## CHECK-START: void PeelUnroll.unrollingWhile(int[]) loop_optimization (after)
42## CHECK-DAG: <<Array:l\d+>>    ParameterValue                            loop:none
43## CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
44## CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
45## CHECK-DAG: <<Const2:i\d+>>   IntConstant 2                             loop:none
46## CHECK-DAG: <<Const128:i\d+>> IntConstant 128                           loop:none
47## CHECK-DAG: <<Limit:i\d+>>    IntConstant 4094                          loop:none
48## CHECK-DAG: <<PhiI:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
49## CHECK-DAG: <<PhiS:i\d+>>     Phi [<<Const128>>,{{i\d+}}]               loop:<<Loop>>      outer_loop:none
50## CHECK-DAG: <<AddI:i\d+>>     Add [<<PhiI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
51## CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<PhiI>>,<<Limit>>]   loop:<<Loop>>      outer_loop:none
52## CHECK-DAG: <<If:v\d+>>       If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
53## CHECK-DAG: <<Rem:i\d+>>      Rem [<<AddI>>,<<Const2>>]                 loop:<<Loop>>      outer_loop:none
54## CHECK-DAG: <<NE:z\d+>>       NotEqual [<<Rem>>,<<Const0>>]             loop:<<Loop>>      outer_loop:none
55## CHECK-DAG:                   If [<<NE>>]                               loop:<<Loop>>      outer_loop:none
56## CHECK-DAG: <<AddS:i\d+>>     Add [<<PhiS>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
57## CHECK-DAG:                   ArraySet [{{l\d+}},{{i\d+}},<<PhiS>>]     loop:<<Loop>>      outer_loop:none
58## CHECK-DAG: <<PhiSM:i\d+>>    Phi [<<PhiS>>,<<AddS>>]                   loop:<<Loop>>      outer_loop:none
59
60## CHECK-DAG: <<AddIA:i\d+>>    Add [<<AddI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
61## CHECK-DAG: <<CheckA:z\d+>>   GreaterThanOrEqual [<<AddI>>,<<Limit>>]   loop:<<Loop>>      outer_loop:none
62## CHECK-DAG: <<IfA:v\d+>>      If [<<Const0>>]                           loop:<<Loop>>      outer_loop:none
63## CHECK-DAG: <<RemA:i\d+>>     Rem [<<AddIA>>,<<Const2>>]                loop:<<Loop>>      outer_loop:none
64## CHECK-DAG: <<NEA:z\d+>>      NotEqual [<<RemA>>,<<Const0>>]            loop:<<Loop>>      outer_loop:none
65## CHECK-DAG:                   If [<<NEA>>]                              loop:<<Loop>>      outer_loop:none
66## CHECK-DAG: <<AddSA:i\d+>>    Add [<<PhiSM>>,<<Const1>>]                loop:<<Loop>>      outer_loop:none
67## CHECK-DAG:                   ArraySet [{{l\d+}},{{i\d+}},<<PhiSM>>]    loop:<<Loop>>      outer_loop:none
68## CHECK-DAG:                   Phi [<<AddSA>>,<<PhiSM>>]                 loop:<<Loop>>      outer_loop:none
69
70## CHECK-NOT:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
71## CHECK-NOT:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
72.method public static final unrollingWhile([I)V
73    .registers 5
74    .param p0, "a"    # [I
75
76    .line 167
77    const/4 v0, 0x0
78
79    .line 168
80    .local v0, "i":I
81    const/16 v1, 0x80
82
83    .line 169
84    .local v1, "s":I
85    :goto_3
86    add-int/lit8 v2, v0, 0x1
87
88    .end local v0    # "i":I
89    .local v2, "i":I
90    const/16 v3, 0xffe
91
92    if-ge v0, v3, :cond_14
93
94    .line 170
95    rem-int/lit8 v0, v2, 0x2
96
97    if-nez v0, :cond_12
98
99    .line 171
100    add-int/lit8 v0, v1, 0x1
101
102    .end local v1    # "s":I
103    .local v0, "s":I
104    aput v1, p0, v2
105
106    .line 169
107    move v1, v0
108
109    .end local v2    # "i":I
110    .local v0, "i":I
111    .restart local v1    # "s":I
112    :cond_12
113    move v0, v2
114
115    goto :goto_3
116
117    .line 174
118    .end local v0    # "i":I
119    .restart local v2    # "i":I
120    :cond_14
121    return-void
122.end method
123
124
125## CHECK-START: int PeelUnroll.unrollingWhileLiveOuts(int[]) loop_optimization (before)
126## CHECK-DAG: <<Array:l\d+>>    ParameterValue                            loop:none
127## CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
128## CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
129## CHECK-DAG: <<Const2:i\d+>>   IntConstant 2                             loop:none
130## CHECK-DAG: <<Const128:i\d+>> IntConstant 128                           loop:none
131## CHECK-DAG: <<Limit:i\d+>>    IntConstant 4094                          loop:none
132## CHECK-DAG: <<PhiI:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
133## CHECK-DAG: <<PhiS:i\d+>>     Phi [<<Const128>>,{{i\d+}}]               loop:<<Loop>>      outer_loop:none
134## CHECK-DAG: <<AddI:i\d+>>     Add [<<PhiI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
135## CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<PhiI>>,<<Limit>>]   loop:<<Loop>>      outer_loop:none
136## CHECK-DAG: <<If:v\d+>>       If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
137## CHECK-DAG: <<Rem:i\d+>>      Rem [<<AddI>>,<<Const2>>]                 loop:<<Loop>>      outer_loop:none
138## CHECK-DAG: <<NE:z\d+>>       NotEqual [<<Rem>>,<<Const0>>]             loop:<<Loop>>      outer_loop:none
139## CHECK-DAG:                   If [<<NE>>]                               loop:<<Loop>>      outer_loop:none
140## CHECK-DAG: <<AddS:i\d+>>     Add [<<PhiS>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
141## CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
142## CHECK-DAG:                   Phi [<<PhiS>>,<<AddS>>]                   loop:<<Loop>>      outer_loop:none
143
144## CHECK-NOT:                   ArrayGet
145## CHECK-NOT:                   ArraySet
146
147## CHECK-START: int PeelUnroll.unrollingWhileLiveOuts(int[]) loop_optimization (after)
148## CHECK-DAG: <<Array:l\d+>>    ParameterValue                            loop:none
149## CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
150## CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
151## CHECK-DAG: <<Const2:i\d+>>   IntConstant 2                             loop:none
152## CHECK-DAG: <<Const128:i\d+>> IntConstant 128                           loop:none
153## CHECK-DAG: <<Limit:i\d+>>    IntConstant 4094                          loop:none
154## CHECK-DAG: <<PhiI:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
155## CHECK-DAG: <<PhiS:i\d+>>     Phi [<<Const128>>,{{i\d+}}]               loop:<<Loop>>      outer_loop:none
156## CHECK-DAG: <<AddI:i\d+>>     Add [<<PhiI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
157## CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<PhiI>>,<<Limit>>]   loop:<<Loop>>      outer_loop:none
158## CHECK-DAG: <<If:v\d+>>       If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
159## CHECK-DAG: <<Rem:i\d+>>      Rem [<<AddI>>,<<Const2>>]                 loop:<<Loop>>      outer_loop:none
160## CHECK-DAG: <<NE:z\d+>>       NotEqual [<<Rem>>,<<Const0>>]             loop:<<Loop>>      outer_loop:none
161## CHECK-DAG:                   If [<<NE>>]                               loop:<<Loop>>      outer_loop:none
162## CHECK-DAG: <<AddS:i\d+>>     Add [<<PhiS>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
163## CHECK-DAG:                   ArraySet [{{l\d+}},{{i\d+}},<<PhiS>>]     loop:<<Loop>>      outer_loop:none
164## CHECK-DAG: <<PhiSM:i\d+>>    Phi [<<PhiS>>,<<AddS>>]                   loop:<<Loop>>      outer_loop:none
165
166## CHECK-DAG: <<AddIA:i\d+>>    Add [<<AddI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
167## CHECK-DAG: <<CheckA:z\d+>>   GreaterThanOrEqual [<<AddI>>,<<Limit>>]   loop:<<Loop>>      outer_loop:none
168## CHECK-DAG: <<IfA:v\d+>>      If [<<Const0>>]                           loop:<<Loop>>      outer_loop:none
169## CHECK-DAG: <<RemA:i\d+>>     Rem [<<AddIA>>,<<Const2>>]                loop:<<Loop>>      outer_loop:none
170## CHECK-DAG: <<NEA:z\d+>>      NotEqual [<<RemA>>,<<Const0>>]            loop:<<Loop>>      outer_loop:none
171## CHECK-DAG:                   If [<<NEA>>]                              loop:<<Loop>>      outer_loop:none
172## CHECK-DAG: <<AddSA:i\d+>>    Add [<<PhiSM>>,<<Const1>>]                loop:<<Loop>>      outer_loop:none
173## CHECK-DAG:                   ArraySet [{{l\d+}},{{i\d+}},<<PhiSM>>]    loop:<<Loop>>      outer_loop:none
174## CHECK-DAG:                   Phi [<<AddSA>>,<<PhiSM>>]                 loop:<<Loop>>      outer_loop:none
175
176## CHECK-DAG: <<RetPhi:i\d+>>   Phi [<<PhiS>>,<<PhiSM>>]                  loop:none
177## CHECK-DAG:                   Return [<<RetPhi>>]                       loop:none
178
179## CHECK-NOT:                   ArrayGet
180## CHECK-NOT:                   ArraySet
181.method public static final unrollingWhileLiveOuts([I)I
182    .registers 5
183    .param p0, "a"    # [I
184
185    .line 598
186    const/4 v0, 0x0
187
188    .line 599
189    .local v0, "i":I
190    const/16 v1, 0x80
191
192    .line 600
193    .local v1, "s":I
194    :goto_3
195    add-int/lit8 v2, v0, 0x1
196
197    .end local v0    # "i":I
198    .local v2, "i":I
199    const/16 v3, 0xffe
200
201    if-ge v0, v3, :cond_14
202
203    .line 601
204    rem-int/lit8 v0, v2, 0x2
205
206    if-nez v0, :cond_12
207
208    .line 602
209    add-int/lit8 v0, v1, 0x1
210
211    .end local v1    # "s":I
212    .local v0, "s":I
213    aput v1, p0, v2
214
215    .line 600
216    move v1, v0
217
218    .end local v2    # "i":I
219    .local v0, "i":I
220    .restart local v1    # "s":I
221    :cond_12
222    move v0, v2
223
224    goto :goto_3
225
226    .line 605
227    .end local v0    # "i":I
228    .restart local v2    # "i":I
229    :cond_14
230    return v1
231.end method
232
233