blob: 5fef766684e22422e85273d098dbbece038814bc [file] [log] [blame]
// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize.peepholes;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.StackValues;
import com.android.tools.r8.ir.code.Value;
import java.util.List;
import java.util.function.Predicate;
public class PeepholeHelper {
public static Predicate<Instruction> withoutLocalInfo(Predicate<Instruction> predicate) {
return t ->
predicate.test(t)
&& !t.hasInValueWithLocalInfo()
&& (t.outValue() == null || !t.outValue().hasLocalInfo());
}
public static Instruction resetNext(InstructionListIterator it, int count) {
Instruction instruction = null;
for (int i = 0; i < count; i++) {
instruction = it.previous();
}
return instruction;
}
public static void resetPrevious(InstructionListIterator it, int count) {
for (int i = 0; i < count; i++) {
it.next();
}
}
public static int numberOfValuesPutOnStack(Instruction instruction) {
Value outValue = instruction.outValue();
if (outValue instanceof StackValues) {
return ((StackValues) outValue).getStackValues().length;
} else if (outValue != null && outValue.isValueOnStack()) {
return 1;
}
return 0;
}
public static int numberOfValuesConsumedFromStack(Instruction instruction) {
int count = 0;
for (int i = instruction.inValues().size() - 1; i >= 0; i--) {
if (instruction.inValues().get(i).isValueOnStack()) {
count += 1;
}
}
return count;
}
public static void moveInstructionsUpToCurrentPosition(
InstructionListIterator it, List<Instruction> instructions) {
assert !instructions.isEmpty();
for (Instruction instruction : instructions) {
for (Value inValue : instruction.inValues()) {
inValue.addUser(instruction);
}
it.add(instruction);
}
Instruction current = it.nextUntil(i -> i == instructions.get(0));
for (int i = 0; i < instructions.size(); i++) {
assert current == instructions.get(i);
it.removeOrReplaceByDebugLocalRead();
current = it.next();
}
it.previousUntil(i -> i == instructions.get(instructions.size() - 1));
it.next();
}
}