Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //
     18 // Test on loop unrolling. Removes loop control overhead (including suspend
     19 // checks) and exposes more opportunities for constant folding.
     20 //
     21 public class Main {
     22 
     23   static int sA = 0;
     24 
     25   /// CHECK-START: void Main.unroll() loop_optimization (before)
     26   /// CHECK-DAG: Phi            loop:<<Loop:B\d+>>
     27   /// CHECK-DAG: StaticFieldSet loop:<<Loop>>
     28   //
     29   /// CHECK-START: void Main.unroll() loop_optimization (after)
     30   /// CHECK-DAG: StaticFieldSet loop:none
     31   //
     32   /// CHECK-START: void Main.unroll() instruction_simplifier$after_bce (after)
     33   /// CHECK-DAG: <<Int:i\d+>> IntConstant    68                  loop:none
     34   /// CHECK-DAG:              StaticFieldSet [{{l\d+}},<<Int>>]  loop:none
     35   //
     36   /// CHECK-START: void Main.unroll() loop_optimization (after)
     37   /// CHECK-NOT: Phi
     38   public static void unroll() {
     39     for (int i = 4; i < 5; i++) {
     40       sA = 17 * i;
     41     }
     42   }
     43 
     44   /// CHECK-START: int Main.unrollLV() loop_optimization (before)
     45   /// CHECK-DAG: <<Phi:i\d+>> Phi              loop:<<Loop:B\d+>>
     46   /// CHECK-DAG:              StaticFieldSet   loop:<<Loop>>
     47   /// CHECK-DAG:              Return [<<Phi>>] loop:none
     48   //
     49   /// CHECK-START: int Main.unrollLV() loop_optimization (after)
     50   /// CHECK-DAG: StaticFieldSet loop:none
     51   //
     52   /// CHECK-START: int Main.unrollLV() instruction_simplifier$after_bce (after)
     53   /// CHECK-DAG: <<Int1:i\d+>> IntConstant    187                 loop:none
     54   /// CHECK-DAG: <<Int2:i\d+>> IntConstant    12                  loop:none
     55   /// CHECK-DAG:               StaticFieldSet [{{l\d+}},<<Int1>>] loop:none
     56   /// CHECK-DAG:               Return [<<Int2>>]                  loop:none
     57   //
     58   /// CHECK-START: int Main.unrollLV() loop_optimization (after)
     59   /// CHECK-NOT: Phi
     60   public static int unrollLV() {
     61     int i;
     62     for (i = 11; i < 12; i++) {
     63       sA = 17 * i;
     64     }
     65     return i;
     66   }
     67 
     68   /// CHECK-START: void Main.unrollNest() loop_optimization (before)
     69   /// CHECK-DAG:               SuspendCheck    loop:none
     70   /// CHECK-DAG: <<Phi1:i\d+>> Phi             loop:<<Loop1:B\d+>> outer_loop:none
     71   /// CHECK-DAG:               SuspendCheck    loop:<<Loop1>>      outer_loop:none
     72   /// CHECK-DAG: <<Phi2:i\d+>> Phi             loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
     73   /// CHECK-DAG:               SuspendCheck    loop:<<Loop2>>      outer_loop:<<Loop1>>
     74   /// CHECK-DAG: <<Phi3:i\d+>> Phi             loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
     75   /// CHECK-DAG:               SuspendCheck    loop:<<Loop3>>      outer_loop:<<Loop2>>
     76   /// CHECK-DAG:               StaticFieldSet  loop:<<Loop3>>      outer_loop:<<Loop2>>
     77   //
     78   /// CHECK-START: void Main.unrollNest() loop_optimization (after)
     79   /// CHECK-DAG: StaticFieldSet loop:none
     80   /// CHECK-DAG: SuspendCheck   loop:none
     81   /// CHECK-NOT: SuspendCheck
     82   //
     83   /// CHECK-START: void Main.unrollNest() instruction_simplifier$after_bce (after)
     84   /// CHECK-DAG: <<Int:i\d+>> IntConstant    6                   loop:none
     85   /// CHECK-DAG:              StaticFieldSet [{{l\d+}},<<Int>>]  loop:none
     86   //
     87   /// CHECK-START: void Main.unrollNest() loop_optimization (after)
     88   /// CHECK-NOT: Phi
     89   public static void unrollNest() {
     90     // Unrolling each loop in turn ultimately removes the complete nest!
     91     for (int i = 4; i < 5; i++) {
     92       for (int j = 5; j < 6; j++) {
     93         for (int k = 6; k < 7; k++) {
     94           sA = k;
     95         }
     96       }
     97     }
     98   }
     99 
    100   //
    101   // Verifier.
    102   //
    103 
    104   public static void main(String[] args) {
    105     unroll();
    106     expectEquals(68, sA);
    107     expectEquals(12, unrollLV());
    108     expectEquals(187, sA);
    109     unrollNest();
    110     expectEquals(6, sA);
    111     System.out.println("passed");
    112   }
    113 
    114   private static void expectEquals(int expected, int result) {
    115     if (expected != result) {
    116       throw new Error("Expected: " + expected + ", found: " + result);
    117     }
    118   }
    119 }
    120