use of com.android.dx.rop.code.Rop in project dexmaker by linkedin.
the class Code method loadConstant.
// instructions: locals
/**
* Copies the constant value {@code value} to {@code target}. The constant
* must be a primitive, String, Class, TypeId, or null.
*/
public <T> void loadConstant(Local<T> target, T value) {
Rop rop = value == null ? Rops.CONST_OBJECT_NOTHROW : Rops.opConst(target.type.ropType);
if (rop.getBranchingness() == BRANCH_NONE) {
addInstruction(new PlainCstInsn(rop, sourcePosition, target.spec(), RegisterSpecList.EMPTY, Constants.getConstant(value)));
} else {
addInstruction(new ThrowingCstInsn(rop, sourcePosition, RegisterSpecList.EMPTY, catches, Constants.getConstant(value)));
moveResult(target, true);
}
}
use of com.android.dx.rop.code.Rop in project dexmaker by linkedin.
the class Code method op.
/**
* Executes {@code op} and sets {@code target} to the result. For most
* binary operations, the types of {@code a} and {@code b} must be the same.
* Shift operations (like {@link BinaryOp#SHIFT_LEFT}) require {@code b} to
* be an {@code int}, even when {@code a} is a {@code long}.
*/
public <T1, T2> void op(BinaryOp op, Local<T1> target, Local<T1> a, Local<T2> b) {
Rop rop = op.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
RegisterSpecList sources = RegisterSpecList.make(a.spec(), b.spec());
if (rop.getBranchingness() == BRANCH_NONE) {
addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), sources));
} else {
addInstruction(new ThrowingInsn(rop, sourcePosition, sources, catches));
moveResult(target, true);
}
}
use of com.android.dx.rop.code.Rop in project buck by facebook.
the class ConstCollector method run.
/**
* Applies the optimization.
*/
private void run() {
int regSz = ssaMeth.getRegCount();
ArrayList<TypedConstant> constantList = getConstsSortedByCountUse();
int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);
SsaBasicBlock start = ssaMeth.getEntryBlock();
// Constant to new register containing the constant
HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec>(toCollect);
for (int i = 0; i < toCollect; i++) {
TypedConstant cst = constantList.get(i);
RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);
Rop constRop = Rops.opConst(cst);
if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
start.addInsnToHead(new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst));
} else {
// We need two new basic blocks along with the new insn
SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor();
// Insert a block containing the const insn.
SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock);
constBlock.replaceLastInsn(new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst));
// Insert a block containing the move-result-pseudo insn.
SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock);
PlainInsn insn = new PlainInsn(Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY);
resultBlock.addInsnToHead(insn);
}
newRegs.put(cst, result);
}
updateConstUses(newRegs, regSz);
}
use of com.android.dx.rop.code.Rop in project buck by facebook.
the class EscapeAnalysis method processRegister.
/**
* Iterate through all the uses of a new object.
*
* @param result {@code non-null;} register where new object is stored
* @param escSet {@code non-null;} EscapeSet for the new object
*/
private void processRegister(RegisterSpec result, EscapeSet escSet) {
ArrayList<RegisterSpec> regWorklist = new ArrayList<RegisterSpec>();
regWorklist.add(result);
// Go through the worklist
while (!regWorklist.isEmpty()) {
int listSize = regWorklist.size() - 1;
RegisterSpec def = regWorklist.remove(listSize);
List<SsaInsn> useList = ssaMeth.getUseListForRegister(def.getReg());
// Handle all the uses of this register
for (SsaInsn use : useList) {
Rop useOpcode = use.getOpcode();
if (useOpcode == null) {
// Handle phis
processPhiUse(use, escSet, regWorklist);
} else {
// Handle other opcodes
processUse(def, use, escSet, regWorklist);
}
}
}
}
use of com.android.dx.rop.code.Rop in project buck by facebook.
the class LiteralOpUpgrader method run.
/**
* Run the literal op upgrader
*/
private void run() {
final TranslationAdvice advice = Optimizer.getAdvice();
ssaMeth.forEachInsn(new SsaInsn.Visitor() {
public void visitMoveInsn(NormalSsaInsn insn) {
// do nothing
}
public void visitPhiInsn(PhiInsn insn) {
// do nothing
}
public void visitNonMoveInsn(NormalSsaInsn insn) {
Insn originalRopInsn = insn.getOriginalRopInsn();
Rop opcode = originalRopInsn.getOpcode();
RegisterSpecList sources = insn.getSources();
// Replace insns with constant results with const insns
if (tryReplacingWithConstant(insn))
return;
if (sources.size() != 2) {
// We're only dealing with two-source insns here.
return;
}
if (opcode.getBranchingness() == Rop.BRANCH_IF) {
/*
* An if instruction can become an if-*z instruction.
*/
if (isConstIntZeroOrKnownNull(sources.get(0))) {
replacePlainInsn(insn, sources.withoutFirst(), RegOps.flippedIfOpcode(opcode.getOpcode()), null);
} else if (isConstIntZeroOrKnownNull(sources.get(1))) {
replacePlainInsn(insn, sources.withoutLast(), opcode.getOpcode(), null);
}
} else if (advice.hasConstantOperation(opcode, sources.get(0), sources.get(1))) {
insn.upgradeToLiteral();
} else if (opcode.isCommutative() && advice.hasConstantOperation(opcode, sources.get(1), sources.get(0))) {
/*
* An instruction can be commuted to a literal operation
*/
insn.setNewSources(RegisterSpecList.make(sources.get(1), sources.get(0)));
insn.upgradeToLiteral();
}
}
});
}
Aggregations