blob: fb334519ffe3fdd2360b62aebf8c1854a7594e9d [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 java.util.List;
import java.util.function.Predicate;
public class PeepholeHelper {
public static class PeepholeLayout {
private Instruction[] instructions;
private List<Predicate<Instruction>> predicates;
public PeepholeLayout(Instruction[] instructions, List<Predicate<Instruction>> predicates) {
this.instructions = instructions;
this.predicates = predicates;
}
public Instruction[] test(InstructionListIterator it) {
int index = 0;
boolean success = true;
for (Predicate<Instruction> p : predicates) {
if (!it.hasNext()) {
success = false;
break;
}
int insertIndex = index++;
instructions[insertIndex] = it.next();
if (!p.test(instructions[insertIndex])) {
success = false;
break;
}
}
for (int i = 0; i < index; i++) {
it.previous();
}
return success ? instructions : null;
}
}
public static PeepholeLayout getLayout(List<Predicate<Instruction>> predicates) {
Instruction[] arr = new Instruction[predicates.size()];
return new PeepholeLayout(arr, predicates);
}
public static void swapNextTwoInstructions(InstructionListIterator it) {
assert it.hasNext();
Instruction moveForward = it.next();
Instruction moveBack = it.next();
it.set(moveForward);
// Two calls to previous is needed because the iterator moves between elements.
it.previous();
it.previous();
it.set(moveBack);
it.next();
}
}