14f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee/* 24f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * Copyright (C) 2015 The Android Open Source Project 34f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * 44f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * Licensed under the Apache License, Version 2.0 (the "License"); 54f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * you may not use this file except in compliance with the License. 64f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * You may obtain a copy of the License at 74f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * 84f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * http://www.apache.org/licenses/LICENSE-2.0 94f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * 104f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * Unless required by applicable law or agreed to in writing, software 114f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * distributed under the License is distributed on an "AS IS" BASIS, 124f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * See the License for the specific language governing permissions and 144f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee * limitations under the License. 154f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee */ 164f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee 174f81907c5b409bac9cf1ad13801280bb15968533Jongwon Leepublic class Main { 184f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee public static void main(String[] args) { 194f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee new Main().run(); 20239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko testPreserveFloat(); 21239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko testPreserveDouble(); 224f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee System.out.println("finish"); 234f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } 244f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee 254f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee public void run() { 264f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee double a[][] = new double[200][201]; 274f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee double b[] = new double[200]; 284f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee int n = 100; 294f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee 304f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee foo1(a, n, b); 314f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } 324f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee 334f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee void foo1(double a[][], int n, double b[]) { 344f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee double t; 354f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee int i,k; 364f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee 374f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee for (i = 0; i < n; i++) { 384f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee k = n - (i + 1); 394f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee b[k] /= a[k][k]; 404f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee t = -b[k]; 414f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee foo2(k + 1000, t, b); 424f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } 434f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } 444f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee 454f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee void foo2(int n, double c, double b[]) { 464f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee try { 474f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee foo3(n, c, b); 484f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } catch (Exception e) { 494f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } 504f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } 514f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee 524f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee void foo3(int n, double c, double b[]) { 534f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee int i = 0; 544f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee for (i = 0; i < n; i++) { 554f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee b[i + 1] += c * b[i + 1]; 564f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } 574f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee } 58239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 59239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /* 60239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * Test that we correctly preserve floating point registers when we deoptimize. 61239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * 62239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * Note: These tests rely on the deoptimization happening before the loop, 63239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * so that the loop is interpreted and fills the provided arrays. However, 64239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * the BCE transformation can be modified to execute the loop as many times 65239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * as the compiler can guarantee no AIOOBE and only deoptimize thereafter, 66239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * just before the throwing iteration. Then the floating point registers 67239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * would no longer be used after the deoptimization and another approach 68239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko * would be needed to test this. 69239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko */ 70239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 71239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko static public void testPreserveFloat() { 72239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko float[] array = new float[2]; 73239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko try { 74239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko $noinline$FloatFill(1.125f, 2.5f, array, 3); 75239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko throw new Error(); 76239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } catch (ArrayIndexOutOfBoundsException expected) { 77239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko System.out.println("array[0]=" + array[0] + "f"); 78239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko System.out.println("array[1]=" + array[1] + "f"); 79239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } 80239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } 81239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 82239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-START: void Main.$noinline$FloatFill(float, float, float[], int) BCE (after) 83239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-DAG: Deoptimize 84239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-DAG: Deoptimize 85239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-DAG: Deoptimize 86239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-NOT: Deoptimize 87239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 88239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-START: void Main.$noinline$FloatFill(float, float, float[], int) BCE (after) 89239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-NOT: BoundsCheck 90239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 91239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko public static void $noinline$FloatFill(float f1, float f2, float[] array, int n) { 92239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko if (doThrow) { throw new Error(); } 93239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko for (int i = 0; i < n; ++i) { 94239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko array[i] = ((i & 1) == 1) ? f1 : f2; 95239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko f1 += 1.5f; 96239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko f2 += 2.25f; 97239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } 98239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } 99239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 100239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko static public void testPreserveDouble() { 101239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko double[] array = new double[2]; 102239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko try { 103239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko $noinline$DoubleFill(2.125, 3.5, array, 3); 104239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko throw new Error(); 105239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } catch (ArrayIndexOutOfBoundsException expected) { 106239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko System.out.println("array[0]=" + array[0]); 107239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko System.out.println("array[1]=" + array[1]); 108239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } 109239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } 110239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 111239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-START: void Main.$noinline$DoubleFill(double, double, double[], int) BCE (after) 112239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-DAG: Deoptimize 113239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-DAG: Deoptimize 114239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-DAG: Deoptimize 115239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-NOT: Deoptimize 116239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 117239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-START: void Main.$noinline$DoubleFill(double, double, double[], int) BCE (after) 118239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko /// CHECK-NOT: BoundsCheck 119239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 120239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko public static void $noinline$DoubleFill(double d1, double d2, double[] array, int n) { 121239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko if (doThrow) { throw new Error(); } 122239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko for (int i = 0; i < n; ++i) { 123239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko array[i] = ((i & 1) == 1) ? d1 : d2; 124239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko d1 += 1.5; 125239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko d2 += 2.25; 126239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } 127239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko } 128239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko 129239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko public static boolean doThrow = false; 1304f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee} 1314f81907c5b409bac9cf1ad13801280bb15968533Jongwon Lee 132