xref: /aosp_15_r20/art/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2015 The Android Open Source Project
2*795d594fSAndroid Build Coastguard Worker#
3*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*795d594fSAndroid Build Coastguard Worker#
7*795d594fSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
8*795d594fSAndroid Build Coastguard Worker#
9*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*795d594fSAndroid Build Coastguard Worker# limitations under the License.
14*795d594fSAndroid Build Coastguard Worker
15*795d594fSAndroid Build Coastguard Worker.class public LIrreducibleLoop;
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker.super Ljava/lang/Object;
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker# Back-edges in the ascii-art graphs are represented with dash '-'.
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker# Test that we support a simple irreducible loop.
22*795d594fSAndroid Build Coastguard Worker#
23*795d594fSAndroid Build Coastguard Worker#        entry
24*795d594fSAndroid Build Coastguard Worker#       /    \
25*795d594fSAndroid Build Coastguard Worker#      /      \
26*795d594fSAndroid Build Coastguard Worker# loop_entry   \
27*795d594fSAndroid Build Coastguard Worker#    /    \-    \
28*795d594fSAndroid Build Coastguard Worker#  exit    \-    \
29*795d594fSAndroid Build Coastguard Worker#           other_loop_entry
30*795d594fSAndroid Build Coastguard Worker#
31*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.simpleLoop(int) dead_code_elimination$initial (before)
32*795d594fSAndroid Build Coastguard Worker## CHECK: irreducible:true
33*795d594fSAndroid Build Coastguard Worker.method public static simpleLoop(I)I
34*795d594fSAndroid Build Coastguard Worker   .registers 2
35*795d594fSAndroid Build Coastguard Worker   const/16 v0, 42
36*795d594fSAndroid Build Coastguard Worker   if-eq v1, v0, :other_loop_entry
37*795d594fSAndroid Build Coastguard Worker   :loop_entry
38*795d594fSAndroid Build Coastguard Worker   if-ne v1, v0, :exit
39*795d594fSAndroid Build Coastguard Worker   add-int v0, v0, v0
40*795d594fSAndroid Build Coastguard Worker   :other_loop_entry
41*795d594fSAndroid Build Coastguard Worker   add-int v0, v0, v0
42*795d594fSAndroid Build Coastguard Worker   goto :loop_entry
43*795d594fSAndroid Build Coastguard Worker   :exit
44*795d594fSAndroid Build Coastguard Worker   return v0
45*795d594fSAndroid Build Coastguard Worker.end method
46*795d594fSAndroid Build Coastguard Worker
47*795d594fSAndroid Build Coastguard Worker# Test that lse does not wrongly optimize loads in irreducible loops. At the
48*795d594fSAndroid Build Coastguard Worker# SSA level, since we create redundant phis for irreducible loop headers, lse
49*795d594fSAndroid Build Coastguard Worker# does not see the relation between the dex register and the phi.
50*795d594fSAndroid Build Coastguard Worker#
51*795d594fSAndroid Build Coastguard Worker#               entry
52*795d594fSAndroid Build Coastguard Worker#                p1
53*795d594fSAndroid Build Coastguard Worker#             /     \
54*795d594fSAndroid Build Coastguard Worker#            /       \
55*795d594fSAndroid Build Coastguard Worker#           /         \
56*795d594fSAndroid Build Coastguard Worker#          /           \
57*795d594fSAndroid Build Coastguard Worker#   loop_pre_entry      \
58*795d594fSAndroid Build Coastguard Worker# set 42 in p1:myField   \
59*795d594fSAndroid Build Coastguard Worker#        /                \
60*795d594fSAndroid Build Coastguard Worker#   loop_entry             \
61*795d594fSAndroid Build Coastguard Worker#  get p1.myField           \
62*795d594fSAndroid Build Coastguard Worker#    /         \-            \
63*795d594fSAndroid Build Coastguard Worker#  exit         \-            \
64*795d594fSAndroid Build Coastguard Worker#                \-            \
65*795d594fSAndroid Build Coastguard Worker#                other_loop_entry
66*795d594fSAndroid Build Coastguard Worker#              set 30 in p1:myField
67*795d594fSAndroid Build Coastguard Worker#
68*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.lse(int, Main) dead_code_elimination$initial (after)
69*795d594fSAndroid Build Coastguard Worker## CHECK: irreducible:true
70*795d594fSAndroid Build Coastguard Worker#
71*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.lse(int, Main) load_store_elimination (after)
72*795d594fSAndroid Build Coastguard Worker## CHECK: InstanceFieldGet
73*795d594fSAndroid Build Coastguard Worker.method public static lse(ILMain;)I
74*795d594fSAndroid Build Coastguard Worker   .registers 4
75*795d594fSAndroid Build Coastguard Worker   const/16 v0, 42
76*795d594fSAndroid Build Coastguard Worker   const/16 v1, 30
77*795d594fSAndroid Build Coastguard Worker   if-eq p0, v0, :other_loop_pre_entry
78*795d594fSAndroid Build Coastguard Worker   goto: loop_pre_entry
79*795d594fSAndroid Build Coastguard Worker   :loop_pre_entry
80*795d594fSAndroid Build Coastguard Worker   iput v0, p1, LMain;->myField:I
81*795d594fSAndroid Build Coastguard Worker   :loop_entry
82*795d594fSAndroid Build Coastguard Worker   if-ne v1, v0, :exit
83*795d594fSAndroid Build Coastguard Worker   :other_loop_entry
84*795d594fSAndroid Build Coastguard Worker   iget v0, p1, LMain;->myField:I
85*795d594fSAndroid Build Coastguard Worker   if-eq v1, v0, :exit
86*795d594fSAndroid Build Coastguard Worker   goto :loop_entry
87*795d594fSAndroid Build Coastguard Worker   :exit
88*795d594fSAndroid Build Coastguard Worker   return v0
89*795d594fSAndroid Build Coastguard Worker   :other_loop_pre_entry
90*795d594fSAndroid Build Coastguard Worker   iput v1, p1, LMain;->myField:I
91*795d594fSAndroid Build Coastguard Worker   goto :other_loop_entry
92*795d594fSAndroid Build Coastguard Worker.end method
93*795d594fSAndroid Build Coastguard Worker
94*795d594fSAndroid Build Coastguard Worker# Check that dce does not apply for irreducible loops.
95*795d594fSAndroid Build Coastguard Worker#
96*795d594fSAndroid Build Coastguard Worker#        entry
97*795d594fSAndroid Build Coastguard Worker#       /    \
98*795d594fSAndroid Build Coastguard Worker#      /      \
99*795d594fSAndroid Build Coastguard Worker# loop_entry   \
100*795d594fSAndroid Build Coastguard Worker#    /    \-    \
101*795d594fSAndroid Build Coastguard Worker#  exit    \-    \
102*795d594fSAndroid Build Coastguard Worker#           other_loop_entry
103*795d594fSAndroid Build Coastguard Worker#
104*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.dce(int) dead_code_elimination$initial (before)
105*795d594fSAndroid Build Coastguard Worker## CHECK: irreducible:true
106*795d594fSAndroid Build Coastguard Worker
107*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.dce(int) dead_code_elimination$initial (after)
108*795d594fSAndroid Build Coastguard Worker## CHECK: irreducible:true
109*795d594fSAndroid Build Coastguard Worker.method public static dce(I)I
110*795d594fSAndroid Build Coastguard Worker   .registers 3
111*795d594fSAndroid Build Coastguard Worker   const/16 v0, 42
112*795d594fSAndroid Build Coastguard Worker   const/16 v1, 168
113*795d594fSAndroid Build Coastguard Worker   if-ne v0, v0, :other_loop_pre_entry
114*795d594fSAndroid Build Coastguard Worker   :loop_entry
115*795d594fSAndroid Build Coastguard Worker   if-ne v0, v0, :exit
116*795d594fSAndroid Build Coastguard Worker   add-int v0, v0, v0
117*795d594fSAndroid Build Coastguard Worker   :other_loop_entry
118*795d594fSAndroid Build Coastguard Worker   add-int v0, v0, v0
119*795d594fSAndroid Build Coastguard Worker   if-eq v0, v1, :exit
120*795d594fSAndroid Build Coastguard Worker   goto :loop_entry
121*795d594fSAndroid Build Coastguard Worker   :exit
122*795d594fSAndroid Build Coastguard Worker   return v0
123*795d594fSAndroid Build Coastguard Worker   :other_loop_pre_entry
124*795d594fSAndroid Build Coastguard Worker   add-int v0, v0, v0
125*795d594fSAndroid Build Coastguard Worker   goto :other_loop_entry
126*795d594fSAndroid Build Coastguard Worker.end method
127*795d594fSAndroid Build Coastguard Worker
128*795d594fSAndroid Build Coastguard Worker# Check that a dex register only used in the loop header remains live thanks
129*795d594fSAndroid Build Coastguard Worker# to the (redundant) Phi created at the loop header for it.
130*795d594fSAndroid Build Coastguard Worker#
131*795d594fSAndroid Build Coastguard Worker#           entry
132*795d594fSAndroid Build Coastguard Worker#            p0
133*795d594fSAndroid Build Coastguard Worker#          /   \
134*795d594fSAndroid Build Coastguard Worker#         /     \
135*795d594fSAndroid Build Coastguard Worker#        /       \
136*795d594fSAndroid Build Coastguard Worker#   loop_entry    \
137*795d594fSAndroid Build Coastguard Worker# i0 = phi(p0,i1)  \
138*795d594fSAndroid Build Coastguard Worker#    /    \-        \
139*795d594fSAndroid Build Coastguard Worker#  exit    \-        \
140*795d594fSAndroid Build Coastguard Worker#        other_loop_entry
141*795d594fSAndroid Build Coastguard Worker#        i1 = phi(p0, i0)
142*795d594fSAndroid Build Coastguard Worker#
143*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.liveness(int, int) liveness (after)
144*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<Arg:i\d+>>      ParameterValue liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopPhiUse:\d+>>)}
145*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<LoopPhi:i\d+>>  Phi [<<Arg>>,<<PhiInLoop:i\d+>>] liveness:<<ArgLoopPhiUse>> ranges:{[<<ArgLoopPhiUse>>,<<PhiInLoopUse:\d+>>)}
146*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<PhiInLoop>>     Phi [<<Arg>>,<<LoopPhi>>] liveness:<<PhiInLoopUse>> ranges:{[<<PhiInLoopUse>>,<<BackEdgeLifetimeEnd:\d+>>)}
147*795d594fSAndroid Build Coastguard Worker## CHECK:                       Return liveness:<<ReturnLiveness:\d+>>
148*795d594fSAndroid Build Coastguard Worker## CHECK-EVAL:    <<ReturnLiveness>> == <<BackEdgeLifetimeEnd>> + 2
149*795d594fSAndroid Build Coastguard Worker.method public static liveness(II)I
150*795d594fSAndroid Build Coastguard Worker   .registers 2
151*795d594fSAndroid Build Coastguard Worker   if-eq p0, p1, :other_loop_entry
152*795d594fSAndroid Build Coastguard Worker   :loop_entry
153*795d594fSAndroid Build Coastguard Worker   add-int p1, p1, p0
154*795d594fSAndroid Build Coastguard Worker   if-ne v0, p1, :exit
155*795d594fSAndroid Build Coastguard Worker   :other_loop_entry
156*795d594fSAndroid Build Coastguard Worker   add-int p1, p1, p1
157*795d594fSAndroid Build Coastguard Worker   goto :loop_entry
158*795d594fSAndroid Build Coastguard Worker   :exit
159*795d594fSAndroid Build Coastguard Worker   return p1
160*795d594fSAndroid Build Coastguard Worker.end method
161*795d594fSAndroid Build Coastguard Worker
162*795d594fSAndroid Build Coastguard Worker# Check that we don't GVN across irreducible loops:
163*795d594fSAndroid Build Coastguard Worker# "const-class 1" in loop_entry should not be GVN with
164*795d594fSAndroid Build Coastguard Worker# "const-class 1" in entry.
165*795d594fSAndroid Build Coastguard Worker#
166*795d594fSAndroid Build Coastguard Worker#        entry
167*795d594fSAndroid Build Coastguard Worker#     const-class 1
168*795d594fSAndroid Build Coastguard Worker#       /    \
169*795d594fSAndroid Build Coastguard Worker#      /      \
170*795d594fSAndroid Build Coastguard Worker# loop_entry   \
171*795d594fSAndroid Build Coastguard Worker# const-class 1 \
172*795d594fSAndroid Build Coastguard Worker#    /    \-     \
173*795d594fSAndroid Build Coastguard Worker#  exit    \-     \
174*795d594fSAndroid Build Coastguard Worker#           other_loop_entry
175*795d594fSAndroid Build Coastguard Worker#             const-class 2
176*795d594fSAndroid Build Coastguard Worker#
177*795d594fSAndroid Build Coastguard Worker## CHECK-START: java.lang.Class IrreducibleLoop.gvn() GVN (before)
178*795d594fSAndroid Build Coastguard Worker## CHECK: LoadClass
179*795d594fSAndroid Build Coastguard Worker## CHECK: LoadClass
180*795d594fSAndroid Build Coastguard Worker## CHECK: LoadClass
181*795d594fSAndroid Build Coastguard Worker## CHECK-NOT: LoadClass
182*795d594fSAndroid Build Coastguard Worker
183*795d594fSAndroid Build Coastguard Worker## CHECK-START: java.lang.Class IrreducibleLoop.gvn() GVN (after)
184*795d594fSAndroid Build Coastguard Worker## CHECK: LoadClass
185*795d594fSAndroid Build Coastguard Worker## CHECK: LoadClass
186*795d594fSAndroid Build Coastguard Worker## CHECK: LoadClass
187*795d594fSAndroid Build Coastguard Worker## CHECK-NOT: LoadClass
188*795d594fSAndroid Build Coastguard Worker
189*795d594fSAndroid Build Coastguard Worker.method public static gvn()Ljava/lang/Class;
190*795d594fSAndroid Build Coastguard Worker  .registers 3
191*795d594fSAndroid Build Coastguard Worker  const/4 v2, 0
192*795d594fSAndroid Build Coastguard Worker  const-class v0, LMain;
193*795d594fSAndroid Build Coastguard Worker  if-ne v0, v2, :other_loop_entry
194*795d594fSAndroid Build Coastguard Worker  :loop_entry
195*795d594fSAndroid Build Coastguard Worker  const-class v0, LMain;
196*795d594fSAndroid Build Coastguard Worker  if-ne v0, v2, :exit
197*795d594fSAndroid Build Coastguard Worker  :other_loop_entry
198*795d594fSAndroid Build Coastguard Worker  const-class v1, LOther;  # LoadClass that can throw
199*795d594fSAndroid Build Coastguard Worker  goto :loop_entry
200*795d594fSAndroid Build Coastguard Worker  :exit
201*795d594fSAndroid Build Coastguard Worker  return-object v0
202*795d594fSAndroid Build Coastguard Worker.end method
203*795d594fSAndroid Build Coastguard Worker
204*795d594fSAndroid Build Coastguard Worker# Check that we don't LICM across irreducible loops:
205*795d594fSAndroid Build Coastguard Worker# "add" in loop_entry should not be LICMed.
206*795d594fSAndroid Build Coastguard Worker#
207*795d594fSAndroid Build Coastguard Worker#        entry
208*795d594fSAndroid Build Coastguard Worker#        /   \
209*795d594fSAndroid Build Coastguard Worker#       /     \
210*795d594fSAndroid Build Coastguard Worker#  loop_entry  \
211*795d594fSAndroid Build Coastguard Worker#      add      \
212*795d594fSAndroid Build Coastguard Worker#    /    \-     \
213*795d594fSAndroid Build Coastguard Worker#  exit    \-     \
214*795d594fSAndroid Build Coastguard Worker#           other_loop_entry
215*795d594fSAndroid Build Coastguard Worker#
216*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.licm1(int) licm (after)
217*795d594fSAndroid Build Coastguard Worker## CHECK: Add irreducible:true
218*795d594fSAndroid Build Coastguard Worker.method public static licm1(I)I
219*795d594fSAndroid Build Coastguard Worker  .registers 3
220*795d594fSAndroid Build Coastguard Worker  const/4 v0, 0
221*795d594fSAndroid Build Coastguard Worker  if-ne p0, v0, :other_loop_entry
222*795d594fSAndroid Build Coastguard Worker  :loop_entry
223*795d594fSAndroid Build Coastguard Worker  add-int v0, p0, p0
224*795d594fSAndroid Build Coastguard Worker  if-ne v0, p0, :exit
225*795d594fSAndroid Build Coastguard Worker  :other_loop_entry
226*795d594fSAndroid Build Coastguard Worker  sub-int v1, p0, p0
227*795d594fSAndroid Build Coastguard Worker  goto :loop_entry
228*795d594fSAndroid Build Coastguard Worker  :exit
229*795d594fSAndroid Build Coastguard Worker  sub-int v0, v0, p0
230*795d594fSAndroid Build Coastguard Worker  return v0
231*795d594fSAndroid Build Coastguard Worker.end method
232*795d594fSAndroid Build Coastguard Worker
233*795d594fSAndroid Build Coastguard Worker# Check that we don't LICM across irreducible loops:
234*795d594fSAndroid Build Coastguard Worker# "const-class" in loop_entry should not be LICMed.
235*795d594fSAndroid Build Coastguard Worker#
236*795d594fSAndroid Build Coastguard Worker#        entry
237*795d594fSAndroid Build Coastguard Worker#        /   \
238*795d594fSAndroid Build Coastguard Worker#       /     \
239*795d594fSAndroid Build Coastguard Worker#  loop_entry  \
240*795d594fSAndroid Build Coastguard Worker#  const-class  \
241*795d594fSAndroid Build Coastguard Worker#    /    \-     \
242*795d594fSAndroid Build Coastguard Worker#  exit    \-     \
243*795d594fSAndroid Build Coastguard Worker#           other_loop_entry
244*795d594fSAndroid Build Coastguard Worker#
245*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.licm2(int) licm (after)
246*795d594fSAndroid Build Coastguard Worker## CHECK: LoadClass irreducible:true
247*795d594fSAndroid Build Coastguard Worker.method public static licm2(I)I
248*795d594fSAndroid Build Coastguard Worker  .registers 3
249*795d594fSAndroid Build Coastguard Worker  const/4 v0, 0
250*795d594fSAndroid Build Coastguard Worker  if-ne p0, v0, :other_loop_entry
251*795d594fSAndroid Build Coastguard Worker  :loop_entry
252*795d594fSAndroid Build Coastguard Worker  const-class v1, LOther;  # LoadClass that can throw
253*795d594fSAndroid Build Coastguard Worker  if-ne v0, p0, :exit
254*795d594fSAndroid Build Coastguard Worker  :other_loop_entry
255*795d594fSAndroid Build Coastguard Worker  sub-int v1, p0, p0
256*795d594fSAndroid Build Coastguard Worker  goto :loop_entry
257*795d594fSAndroid Build Coastguard Worker  :exit
258*795d594fSAndroid Build Coastguard Worker  sub-int v0, v0, p0
259*795d594fSAndroid Build Coastguard Worker  return v0
260*795d594fSAndroid Build Coastguard Worker.end method
261*795d594fSAndroid Build Coastguard Worker
262*795d594fSAndroid Build Coastguard Worker# Check that we don't LICM in a natural loop that contains an irreducible loop:
263*795d594fSAndroid Build Coastguard Worker# "const-class" should not be LICMed.
264*795d594fSAndroid Build Coastguard Worker#
265*795d594fSAndroid Build Coastguard Worker#        entry
266*795d594fSAndroid Build Coastguard Worker#          |
267*795d594fSAndroid Build Coastguard Worker#       loop_entry
268*795d594fSAndroid Build Coastguard Worker#       const-class -------------------
269*795d594fSAndroid Build Coastguard Worker#        /        \                   -
270*795d594fSAndroid Build Coastguard Worker#       /          \                  -
271*795d594fSAndroid Build Coastguard Worker#     exit         loop_body          -
272*795d594fSAndroid Build Coastguard Worker#                  /       \          -
273*795d594fSAndroid Build Coastguard Worker#                 /         \         -
274*795d594fSAndroid Build Coastguard Worker#   irreducible_loop_entry   \        -
275*795d594fSAndroid Build Coastguard Worker#        -      \             \       -
276*795d594fSAndroid Build Coastguard Worker#        -       \             \      -
277*795d594fSAndroid Build Coastguard Worker#        -      irreducible_loop_other_entry
278*795d594fSAndroid Build Coastguard Worker#        -                  |
279*795d594fSAndroid Build Coastguard Worker#        -                  |
280*795d594fSAndroid Build Coastguard Worker#        ------ irreducible_loop_back_edge
281*795d594fSAndroid Build Coastguard Worker#
282*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.licm3(int, int, int) licm (after)
283*795d594fSAndroid Build Coastguard Worker## CHECK: LoadClass loop:<<OuterLoop:B\d+>>  irreducible:false
284*795d594fSAndroid Build Coastguard Worker## CHECK: Goto outer_loop:<<OuterLoop>>  irreducible:true
285*795d594fSAndroid Build Coastguard Worker.method public static licm3(III)I
286*795d594fSAndroid Build Coastguard Worker  .registers 4
287*795d594fSAndroid Build Coastguard Worker  :loop_entry
288*795d594fSAndroid Build Coastguard Worker  const-class v0, LOther;  # LoadClass that can throw
289*795d594fSAndroid Build Coastguard Worker  if-ne p1, p2, :exit
290*795d594fSAndroid Build Coastguard Worker  goto :loop_body
291*795d594fSAndroid Build Coastguard Worker
292*795d594fSAndroid Build Coastguard Worker  :loop_body
293*795d594fSAndroid Build Coastguard Worker  if-eq p0, p1, :irreducible_loop_entry
294*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_other_entry
295*795d594fSAndroid Build Coastguard Worker
296*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_entry
297*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_other_entry
298*795d594fSAndroid Build Coastguard Worker
299*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_other_entry
300*795d594fSAndroid Build Coastguard Worker  if-eq p0, p2, :loop_entry
301*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_back_edge
302*795d594fSAndroid Build Coastguard Worker
303*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_back_edge
304*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_entry
305*795d594fSAndroid Build Coastguard Worker  :exit
306*795d594fSAndroid Build Coastguard Worker  return p0
307*795d594fSAndroid Build Coastguard Worker.end method
308*795d594fSAndroid Build Coastguard Worker
309*795d594fSAndroid Build Coastguard Worker# Check a loop within an irreducible loop
310*795d594fSAndroid Build Coastguard Worker#
311*795d594fSAndroid Build Coastguard Worker#                      entry
312*795d594fSAndroid Build Coastguard Worker#                    /       \
313*795d594fSAndroid Build Coastguard Worker#                   /         \
314*795d594fSAndroid Build Coastguard Worker# irreducible_loop_entry       \
315*795d594fSAndroid Build Coastguard Worker#    / -       \         irreducible_loop_pre_other_entry
316*795d594fSAndroid Build Coastguard Worker# exit -        \              /
317*795d594fSAndroid Build Coastguard Worker#      -    irreducible_loop_body
318*795d594fSAndroid Build Coastguard Worker#      -              |
319*795d594fSAndroid Build Coastguard Worker#      -              |
320*795d594fSAndroid Build Coastguard Worker#      -      loop_within_header
321*795d594fSAndroid Build Coastguard Worker#      -        /               \-
322*795d594fSAndroid Build Coastguard Worker#      -       /                 \-
323*795d594fSAndroid Build Coastguard Worker# irreducible_loop_back_edge    loop_within_back_edge
324*795d594fSAndroid Build Coastguard Worker#
325*795d594fSAndroid Build Coastguard Worker## CHECK-START: void IrreducibleLoop.analyze1(int) builder (after)
326*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto loop:<<OuterLoop:B\d+>> outer_loop:none irreducible:true
327*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto outer_loop:<<OuterLoop>> irreducible:false
328*795d594fSAndroid Build Coastguard Worker.method public static analyze1(I)V
329*795d594fSAndroid Build Coastguard Worker  .registers 1
330*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :irreducible_loop_entry
331*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_pre_other_entry
332*795d594fSAndroid Build Coastguard Worker
333*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_entry
334*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :exit
335*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_body
336*795d594fSAndroid Build Coastguard Worker
337*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_body
338*795d594fSAndroid Build Coastguard Worker  :loop_within_header
339*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :irreducible_loop_back_edge
340*795d594fSAndroid Build Coastguard Worker  goto :loop_within_back_edge
341*795d594fSAndroid Build Coastguard Worker
342*795d594fSAndroid Build Coastguard Worker  :loop_within_back_edge
343*795d594fSAndroid Build Coastguard Worker  goto :loop_within_header
344*795d594fSAndroid Build Coastguard Worker
345*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_back_edge
346*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_entry
347*795d594fSAndroid Build Coastguard Worker
348*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_pre_other_entry
349*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_body
350*795d594fSAndroid Build Coastguard Worker
351*795d594fSAndroid Build Coastguard Worker  :exit
352*795d594fSAndroid Build Coastguard Worker  return-void
353*795d594fSAndroid Build Coastguard Worker.end method
354*795d594fSAndroid Build Coastguard Worker
355*795d594fSAndroid Build Coastguard Worker# Check than a loop before an irreducible loop is not part of the
356*795d594fSAndroid Build Coastguard Worker# irreducible loop.
357*795d594fSAndroid Build Coastguard Worker#
358*795d594fSAndroid Build Coastguard Worker#                      entry
359*795d594fSAndroid Build Coastguard Worker#                        |
360*795d594fSAndroid Build Coastguard Worker#                        |
361*795d594fSAndroid Build Coastguard Worker#                   loop_header
362*795d594fSAndroid Build Coastguard Worker#                    /        \-
363*795d594fSAndroid Build Coastguard Worker#                   /          \-
364*795d594fSAndroid Build Coastguard Worker# irreducible_loop_pre_entry  loop_body
365*795d594fSAndroid Build Coastguard Worker#           /             \
366*795d594fSAndroid Build Coastguard Worker#          /               \
367*795d594fSAndroid Build Coastguard Worker#  irreducible_loop_entry   \
368*795d594fSAndroid Build Coastguard Worker#    /        \-       irreducible_loop_other_pre_entry
369*795d594fSAndroid Build Coastguard Worker#   /          \-           /
370*795d594fSAndroid Build Coastguard Worker# exit          \-         /
371*795d594fSAndroid Build Coastguard Worker#          irreducible_loop_body
372*795d594fSAndroid Build Coastguard Worker#
373*795d594fSAndroid Build Coastguard Worker## CHECK-START: void IrreducibleLoop.analyze2(int) builder (after)
374*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto outer_loop:none irreducible:false
375*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto outer_loop:none irreducible:true
376*795d594fSAndroid Build Coastguard Worker.method public static analyze2(I)V
377*795d594fSAndroid Build Coastguard Worker  .registers 1
378*795d594fSAndroid Build Coastguard Worker  :loop_header
379*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :irreducible_loop_pre_entry
380*795d594fSAndroid Build Coastguard Worker  goto :loop_body
381*795d594fSAndroid Build Coastguard Worker  :loop_body
382*795d594fSAndroid Build Coastguard Worker  goto :loop_header
383*795d594fSAndroid Build Coastguard Worker
384*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_pre_entry
385*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :irreducible_loop_other_pre_entry
386*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_entry
387*795d594fSAndroid Build Coastguard Worker
388*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_entry
389*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :exit
390*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_body
391*795d594fSAndroid Build Coastguard Worker
392*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_body
393*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_entry
394*795d594fSAndroid Build Coastguard Worker
395*795d594fSAndroid Build Coastguard Worker  :irreducible_loop_other_pre_entry
396*795d594fSAndroid Build Coastguard Worker  goto :irreducible_loop_body
397*795d594fSAndroid Build Coastguard Worker
398*795d594fSAndroid Build Coastguard Worker  :exit
399*795d594fSAndroid Build Coastguard Worker  return-void
400*795d594fSAndroid Build Coastguard Worker.end method
401*795d594fSAndroid Build Coastguard Worker
402*795d594fSAndroid Build Coastguard Worker# Check two irreducible loops, one within another.
403*795d594fSAndroid Build Coastguard Worker#
404*795d594fSAndroid Build Coastguard Worker#                      entry
405*795d594fSAndroid Build Coastguard Worker#                    /       \
406*795d594fSAndroid Build Coastguard Worker#                   /         \
407*795d594fSAndroid Build Coastguard Worker#           loop1_header   loop2_header
408*795d594fSAndroid Build Coastguard Worker#           -   |          /       -
409*795d594fSAndroid Build Coastguard Worker#           -   |         /        -
410*795d594fSAndroid Build Coastguard Worker#           -   |        /         -
411*795d594fSAndroid Build Coastguard Worker#           -   |       /          -
412*795d594fSAndroid Build Coastguard Worker#           -  loop2_body          -
413*795d594fSAndroid Build Coastguard Worker#           -    /     \           -
414*795d594fSAndroid Build Coastguard Worker#           -   /       \          -
415*795d594fSAndroid Build Coastguard Worker#         loop1_body   loop2_back_edge
416*795d594fSAndroid Build Coastguard Worker#             |
417*795d594fSAndroid Build Coastguard Worker#             |
418*795d594fSAndroid Build Coastguard Worker#           exit
419*795d594fSAndroid Build Coastguard Worker#
420*795d594fSAndroid Build Coastguard Worker## CHECK-START: void IrreducibleLoop.analyze3(int) builder (after)
421*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto loop:<<OuterLoop:B\d+>> outer_loop:none irreducible:true
422*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto outer_loop:<<OuterLoop>> irreducible:true
423*795d594fSAndroid Build Coastguard Worker.method public static analyze3(I)V
424*795d594fSAndroid Build Coastguard Worker  .registers 1
425*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :loop2_header
426*795d594fSAndroid Build Coastguard Worker  goto :loop1_header
427*795d594fSAndroid Build Coastguard Worker
428*795d594fSAndroid Build Coastguard Worker  :loop1_header
429*795d594fSAndroid Build Coastguard Worker  goto :loop2_body
430*795d594fSAndroid Build Coastguard Worker
431*795d594fSAndroid Build Coastguard Worker  :loop2_header
432*795d594fSAndroid Build Coastguard Worker  goto :loop2_body
433*795d594fSAndroid Build Coastguard Worker
434*795d594fSAndroid Build Coastguard Worker  :loop2_body
435*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :loop2_back_edge
436*795d594fSAndroid Build Coastguard Worker  goto :loop1_body
437*795d594fSAndroid Build Coastguard Worker
438*795d594fSAndroid Build Coastguard Worker  :loop2_back_edge
439*795d594fSAndroid Build Coastguard Worker  goto :loop2_header
440*795d594fSAndroid Build Coastguard Worker
441*795d594fSAndroid Build Coastguard Worker  :loop1_body
442*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :exit
443*795d594fSAndroid Build Coastguard Worker  goto :loop1_header
444*795d594fSAndroid Build Coastguard Worker
445*795d594fSAndroid Build Coastguard Worker  :exit
446*795d594fSAndroid Build Coastguard Worker  return-void
447*795d594fSAndroid Build Coastguard Worker.end method
448*795d594fSAndroid Build Coastguard Worker
449*795d594fSAndroid Build Coastguard Worker# Check two irreducible loops, one within another. Almost identical
450*795d594fSAndroid Build Coastguard Worker# to analyze3 except the branches of the first 'if' are swapped, to
451*795d594fSAndroid Build Coastguard Worker# ensure the order at which we find the back edges does not matter.
452*795d594fSAndroid Build Coastguard Worker#
453*795d594fSAndroid Build Coastguard Worker#                      entry
454*795d594fSAndroid Build Coastguard Worker#                    /       \
455*795d594fSAndroid Build Coastguard Worker#                   /         \
456*795d594fSAndroid Build Coastguard Worker#           loop1_header   loop2_header
457*795d594fSAndroid Build Coastguard Worker#           -   |          /       -
458*795d594fSAndroid Build Coastguard Worker#           -   |         /        -
459*795d594fSAndroid Build Coastguard Worker#           -   |        /         -
460*795d594fSAndroid Build Coastguard Worker#           -   |       /          -
461*795d594fSAndroid Build Coastguard Worker#           -  loop2_body          -
462*795d594fSAndroid Build Coastguard Worker#           -    /     \           -
463*795d594fSAndroid Build Coastguard Worker#           -   /       \          -
464*795d594fSAndroid Build Coastguard Worker#         loop1_body   loop2_back_edge
465*795d594fSAndroid Build Coastguard Worker#             |
466*795d594fSAndroid Build Coastguard Worker#             |
467*795d594fSAndroid Build Coastguard Worker#           exit
468*795d594fSAndroid Build Coastguard Worker#
469*795d594fSAndroid Build Coastguard Worker## CHECK-START: void IrreducibleLoop.analyze4(int) builder (after)
470*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto loop:<<OuterLoop:B\d+>> outer_loop:none irreducible:true
471*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto outer_loop:<<OuterLoop>> irreducible:true
472*795d594fSAndroid Build Coastguard Worker.method public static analyze4(I)V
473*795d594fSAndroid Build Coastguard Worker  .registers 1
474*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :loop1_header
475*795d594fSAndroid Build Coastguard Worker  goto :loop2_header
476*795d594fSAndroid Build Coastguard Worker
477*795d594fSAndroid Build Coastguard Worker  :loop1_header
478*795d594fSAndroid Build Coastguard Worker  goto :loop2_body
479*795d594fSAndroid Build Coastguard Worker
480*795d594fSAndroid Build Coastguard Worker  :loop2_header
481*795d594fSAndroid Build Coastguard Worker  goto :loop2_body
482*795d594fSAndroid Build Coastguard Worker
483*795d594fSAndroid Build Coastguard Worker  :loop2_body
484*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :loop2_back_edge
485*795d594fSAndroid Build Coastguard Worker  goto :loop1_body
486*795d594fSAndroid Build Coastguard Worker
487*795d594fSAndroid Build Coastguard Worker  :loop2_back_edge
488*795d594fSAndroid Build Coastguard Worker  goto :loop2_header
489*795d594fSAndroid Build Coastguard Worker
490*795d594fSAndroid Build Coastguard Worker  :loop1_body
491*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :exit
492*795d594fSAndroid Build Coastguard Worker  goto :loop1_header
493*795d594fSAndroid Build Coastguard Worker
494*795d594fSAndroid Build Coastguard Worker  :exit
495*795d594fSAndroid Build Coastguard Worker  return-void
496*795d594fSAndroid Build Coastguard Worker.end method
497*795d594fSAndroid Build Coastguard Worker
498*795d594fSAndroid Build Coastguard Worker# Check two irreducible loops, one within another. Almost identical
499*795d594fSAndroid Build Coastguard Worker# to analyze3 and analyze4, except that the inner loop exits from the
500*795d594fSAndroid Build Coastguard Worker# back edge, and not the body.
501*795d594fSAndroid Build Coastguard Worker#
502*795d594fSAndroid Build Coastguard Worker#                      entry
503*795d594fSAndroid Build Coastguard Worker#                    /       \
504*795d594fSAndroid Build Coastguard Worker#                   /         \
505*795d594fSAndroid Build Coastguard Worker#           loop1_header   loop2_header
506*795d594fSAndroid Build Coastguard Worker#           -   \            /       -
507*795d594fSAndroid Build Coastguard Worker#           -    \          /        -
508*795d594fSAndroid Build Coastguard Worker#           -     \        /         -
509*795d594fSAndroid Build Coastguard Worker#           -      \      /          -
510*795d594fSAndroid Build Coastguard Worker#           -     loop2_body         -
511*795d594fSAndroid Build Coastguard Worker#           -        |               -
512*795d594fSAndroid Build Coastguard Worker#           -        |               -
513*795d594fSAndroid Build Coastguard Worker#           -   loop2_back_edge ------
514*795d594fSAndroid Build Coastguard Worker#           -        |
515*795d594fSAndroid Build Coastguard Worker#           -        |
516*795d594fSAndroid Build Coastguard Worker#           ----- loop1_body
517*795d594fSAndroid Build Coastguard Worker#                    |
518*795d594fSAndroid Build Coastguard Worker#                    |
519*795d594fSAndroid Build Coastguard Worker#                   exit
520*795d594fSAndroid Build Coastguard Worker#
521*795d594fSAndroid Build Coastguard Worker## CHECK-START: void IrreducibleLoop.analyze5(int) builder (after)
522*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto loop:<<OuterLoop:B\d+>> outer_loop:none irreducible:true
523*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: Goto outer_loop:<<OuterLoop>> irreducible:true
524*795d594fSAndroid Build Coastguard Worker.method public static analyze5(I)V
525*795d594fSAndroid Build Coastguard Worker  .registers 1
526*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :loop1_header
527*795d594fSAndroid Build Coastguard Worker  goto :loop2_header
528*795d594fSAndroid Build Coastguard Worker
529*795d594fSAndroid Build Coastguard Worker  :loop1_header
530*795d594fSAndroid Build Coastguard Worker  goto :loop2_body
531*795d594fSAndroid Build Coastguard Worker
532*795d594fSAndroid Build Coastguard Worker  :loop2_header
533*795d594fSAndroid Build Coastguard Worker  goto :loop2_body
534*795d594fSAndroid Build Coastguard Worker
535*795d594fSAndroid Build Coastguard Worker  :loop2_body
536*795d594fSAndroid Build Coastguard Worker  goto :loop2_back_edge
537*795d594fSAndroid Build Coastguard Worker
538*795d594fSAndroid Build Coastguard Worker  :loop2_back_edge
539*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :loop2_header
540*795d594fSAndroid Build Coastguard Worker  goto :loop1_body
541*795d594fSAndroid Build Coastguard Worker
542*795d594fSAndroid Build Coastguard Worker  :loop1_body
543*795d594fSAndroid Build Coastguard Worker  if-eq p0, p0, :exit
544*795d594fSAndroid Build Coastguard Worker  goto :loop1_header
545*795d594fSAndroid Build Coastguard Worker
546*795d594fSAndroid Build Coastguard Worker  :exit
547*795d594fSAndroid Build Coastguard Worker  return-void
548*795d594fSAndroid Build Coastguard Worker.end method
549*795d594fSAndroid Build Coastguard Worker
550*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.testDoNotInlineIrreducible(int) inliner (before)
551*795d594fSAndroid Build Coastguard Worker## CHECK: InvokeStaticOrDirect method_name:IrreducibleLoop.doNotInlineIrreducible
552*795d594fSAndroid Build Coastguard Worker#
553*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.testDoNotInlineIrreducible(int) inliner (after)
554*795d594fSAndroid Build Coastguard Worker## CHECK: InvokeStaticOrDirect method_name:IrreducibleLoop.doNotInlineIrreducible
555*795d594fSAndroid Build Coastguard Worker.method public static testDoNotInlineIrreducible(I)I
556*795d594fSAndroid Build Coastguard Worker  .registers 2
557*795d594fSAndroid Build Coastguard Worker  invoke-static {p0}, LIrreducibleLoop;->doNotInlineIrreducible(I)I
558*795d594fSAndroid Build Coastguard Worker  move-result v0
559*795d594fSAndroid Build Coastguard Worker  return v0
560*795d594fSAndroid Build Coastguard Worker.end method
561*795d594fSAndroid Build Coastguard Worker
562*795d594fSAndroid Build Coastguard Worker# Check that doNotInlineIrreducible has a simple irreducible loop
563*795d594fSAndroid Build Coastguard Worker#
564*795d594fSAndroid Build Coastguard Worker#        entry
565*795d594fSAndroid Build Coastguard Worker#       /    \
566*795d594fSAndroid Build Coastguard Worker#      /      \
567*795d594fSAndroid Build Coastguard Worker# loop_entry   \
568*795d594fSAndroid Build Coastguard Worker#    /    \-    \
569*795d594fSAndroid Build Coastguard Worker# try_start\-    \
570*795d594fSAndroid Build Coastguard Worker#           other_loop_entry
571*795d594fSAndroid Build Coastguard Worker#
572*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.doNotInlineIrreducible(int) register (after)
573*795d594fSAndroid Build Coastguard Worker## CHECK: irreducible:true
574*795d594fSAndroid Build Coastguard Worker#
575*795d594fSAndroid Build Coastguard Worker# Check that we didn't optimized away the try.
576*795d594fSAndroid Build Coastguard Worker## CHECK-START: int IrreducibleLoop.doNotInlineIrreducible(int) register (after)
577*795d594fSAndroid Build Coastguard Worker## CHECK: TryBoundary kind:exit
578*795d594fSAndroid Build Coastguard Worker.method public static doNotInlineIrreducible(I)I
579*795d594fSAndroid Build Coastguard Worker  .registers 3
580*795d594fSAndroid Build Coastguard Worker  const/16 v0, 42
581*795d594fSAndroid Build Coastguard Worker  const/16 v1, 21
582*795d594fSAndroid Build Coastguard Worker  # Irreducible loop
583*795d594fSAndroid Build Coastguard Worker  if-eq v1, v0, :other_loop_entry
584*795d594fSAndroid Build Coastguard Worker  :loop_entry
585*795d594fSAndroid Build Coastguard Worker  if-ne v1, v0, :try_start
586*795d594fSAndroid Build Coastguard Worker  add-int v0, v0, v0
587*795d594fSAndroid Build Coastguard Worker  :other_loop_entry
588*795d594fSAndroid Build Coastguard Worker  add-int v0, v0, v0
589*795d594fSAndroid Build Coastguard Worker  goto :loop_entry
590*795d594fSAndroid Build Coastguard Worker
591*795d594fSAndroid Build Coastguard Worker  :try_start
592*795d594fSAndroid Build Coastguard Worker  # We make this division to make sure the try doesn't get optimized out
593*795d594fSAndroid Build Coastguard Worker  div-int v0, v0, p0
594*795d594fSAndroid Build Coastguard Worker  return v0
595*795d594fSAndroid Build Coastguard Worker  :try_end
596*795d594fSAndroid Build Coastguard Worker  .catchall {:try_start .. :try_end} :catch_all
597*795d594fSAndroid Build Coastguard Worker
598*795d594fSAndroid Build Coastguard Worker  :catch_all
599*795d594fSAndroid Build Coastguard Worker  # This is only reachable if the parameter is 0
600*795d594fSAndroid Build Coastguard Worker  const/4 v0, -0x1
601*795d594fSAndroid Build Coastguard Worker  return v0
602*795d594fSAndroid Build Coastguard Worker.end method
603