You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
4.3 KiB

/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class HoistIndirect {
public static int svar = 0;
int[] array;
class Test {
int a = 0;
int foo(int x) {
return x + 10;
}
void set_test(Test test) {
test.a = 5;
}
int get_test(Test test) {
return test.a;
}
int get_sum_test(Test test, int x) {
return test.a + x;
}
Test return_only(Test t) {
return t;
}
int indirect_modification_dont_hoist(int size, Test t) {
int d = 0;
for (int i = 0; i < size; i++) {
set_test(t);
d = get_test(t); // don't hoist since t changes
}
return d;
}
void variant_arg_dont_hoist(int size, Test t) {
for (int i = 0; i < size; i++) {
set_test(t); // t is invalidated
get_sum_test(
return_only(t),
size); // foo' and return_only's arguments are variant, hence don't hoist
}
;
}
// t changes deep in the call stack
int deep_modification_dont_hoist(int size) {
int d = 0;
Test t = new Test();
for (int i = 0; i < size; i++) {
indirect_modification_dont_hoist(size, t);
}
return d;
}
// foo(3) is ok to hoist, but can't detect this right now
int indirect_modification_hoist_FN(int size) {
int d = 0;
Test t = new Test();
for (int i = 0; i < size; i++) {
set_test(t); // this (and t) is invalidated here
d = foo(3); // foo becomes variant due to implicit arg. this being invalidated above
}
return d;
}
}
void set() {
svar = 5;
}
int get() {
return svar;
}
int indirect_this_modification_dont_hoist(int size) {
int d = 0;
for (int i = 0; i < size; i++) {
d = get(); // don't hoist since this.svar changes in the loop
set();
}
return d;
}
int direct_this_modification_dont_hoist_FP(int size) {
int d = 0;
for (int i = 0; i < size; i++) {
d += get(); // don't hoist since this.svar changes in the loop
svar = i;
}
return d;
}
int this_modification_outside_hoist(int size) {
int d = 0;
set();
for (int i = 0; i < size; i++) {
d += get(); // ok to hoist since set is outside
}
return d;
}
int arg_modification_hoist(int size, Test t) {
int d = 0;
for (int i = 0; i < size; i++) {
d += get(); // ok to hoist since set_test doesn't modify this
t.set_test(t);
}
return d;
}
void set_ith(int i, int[] array) {
array[i] = 0;
}
int get_ith(int i, int[] array) {
return array[i];
}
int modified_array_dont_hoist(int size, Test t) {
int d = 0;
for (int i = 0; i < size; i++) {
set_ith(i, array);
d += get_ith(size, array); // don't hoist since array changes
}
return d;
}
int independent_hoist(int size, Test t) {
int d = 0;
for (int i = 0; i < size; i++) {
set_ith(i, array);
t.foo(size); // hoist call to foo
d += get_ith(size, array); // don't hoist since array changes
}
return d;
}
static int regionFirst(int[] region) {
return region[0];
}
static void incrDest(int[] source, int[] dest) {
dest[0] = source[0] + 1;
}
static void sumDest(int[] source, int[] dest, int x) {
dest[0] = source[0] + x;
}
void irvar_change_dont_hoist(int[][] nextRegionM, int p, int[] tempRegion) {
for (int i = 0; i < 10; i++) {
if (i < regionFirst(nextRegionM[p])) {
incrDest(tempRegion, nextRegionM[p]); // invalidate nextRegionM
}
}
}
void tmp_irvar_change_dont_hoist(int[][] nextRegionM, int p, int[] tempRegion) {
for (int i = 0; i < 10; i++) {
if (i < regionFirst(nextRegionM[p])) {
int[] arr = nextRegionM[p];
incrDest(tempRegion, arr); // invalidate nextRegionM
}
}
}
int double_me(int p) {
return 2 * p;
}
void irvar_independent_hoist(int[][] nextRegionM, int p, int[] tempRegion) {
for (int i = 0; i < 10; i++) {
if (i < regionFirst(nextRegionM[p]) + double_me(p)) { // double_me(p) can be hoisted
sumDest(tempRegion, nextRegionM[p], i); // invalidate nextRegionM
}
}
}
}