use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class DalvInsn method expandedPrefix.
/**
* Gets the instruction prefix required, if any, to use in an expanded
* version of this instance. Will not generate moves for registers
* marked compatible to the format by the given BitSet.
*
* @see #expandedVersion
*
* @param compatRegs {@code non-null;} set of compatible registers
* @return {@code null-ok;} the prefix, if any
*/
public DalvInsn expandedPrefix(BitSet compatRegs) {
RegisterSpecList regs = registers;
boolean firstBit = compatRegs.get(0);
if (hasResult())
compatRegs.set(0);
regs = regs.subset(compatRegs);
if (hasResult())
compatRegs.set(0, firstBit);
if (regs.size() == 0)
return null;
return new HighRegisterPrefix(position, regs);
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
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();
}
}
});
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class NormalSsaInsn method mapSourceRegisters.
/**
* {@inheritDoc}
*/
@Override
public final void mapSourceRegisters(RegisterMapper mapper) {
RegisterSpecList oldSources = insn.getSources();
RegisterSpecList newSources = mapper.map(oldSources);
if (newSources != oldSources) {
insn = insn.withNewRegisters(getResult(), newSources);
getBlock().getParent().onSourcesChanged(this, oldSources);
}
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class NormalSsaInsn method setNewSources.
/**
* Changes the source list of the insn. New source list should be the
* same size and consist of sources of identical types.
*
* @param newSources non-null new sources list.
*/
public final void setNewSources(RegisterSpecList newSources) {
RegisterSpecList origSources = insn.getSources();
if (origSources.size() != newSources.size()) {
throw new RuntimeException("Sources counts don't match");
}
insn = insn.withNewRegisters(getResult(), newSources);
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class SsaBasicBlock method scheduleUseBeforeAssigned.
/**
* Ensures that all move operations in this block occur such that
* reads of any register happen before writes to that register.
* NOTE: caller is expected to returnSpareRegisters()!
*
* TODO: See Briggs, et al "Practical Improvements to the Construction and
* Destruction of Static Single Assignment Form" section 5. a) This can
* be done in three passes.
*
* @param toSchedule List of instructions. Must consist only of moves.
*/
private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {
BitSet regsUsedAsSources = new BitSet(parent.getRegCount());
// TODO: Get rid of this.
BitSet regsUsedAsResults = new BitSet(parent.getRegCount());
int sz = toSchedule.size();
int insertPlace = 0;
while (insertPlace < sz) {
int oldInsertPlace = insertPlace;
// Record all registers used as sources in this block.
for (int i = insertPlace; i < sz; i++) {
setRegsUsed(regsUsedAsSources, toSchedule.get(i).getSources().get(0));
setRegsUsed(regsUsedAsResults, toSchedule.get(i).getResult());
}
/*
* If there are no circular dependencies, then there exists
* n instructions where n > 1 whose result is not used as a source.
*/
for (int i = insertPlace; i < sz; i++) {
SsaInsn insn = toSchedule.get(i);
/*
* Move these n registers to the front, since they overwrite
* nothing.
*/
if (!checkRegUsed(regsUsedAsSources, insn.getResult())) {
Collections.swap(toSchedule, i, insertPlace++);
}
}
/*
* If we've made no progress in this iteration, there's a
* circular dependency. Split it using the temp reg.
*/
if (oldInsertPlace == insertPlace) {
SsaInsn insnToSplit = null;
// Find an insn whose result is used as a source.
for (int i = insertPlace; i < sz; i++) {
SsaInsn insn = toSchedule.get(i);
if (checkRegUsed(regsUsedAsSources, insn.getResult()) && checkRegUsed(regsUsedAsResults, insn.getSources().get(0))) {
insnToSplit = insn;
/*
* We're going to split this insn; move it to the
* front.
*/
Collections.swap(toSchedule, insertPlace, i);
break;
}
}
// At least one insn will be set above.
RegisterSpec result = insnToSplit.getResult();
RegisterSpec tempSpec = result.withReg(parent.borrowSpareRegister(result.getCategory()));
NormalSsaInsn toAdd = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, tempSpec, insnToSplit.getSources()), this);
toSchedule.add(insertPlace++, toAdd);
RegisterSpecList newSources = RegisterSpecList.make(tempSpec);
NormalSsaInsn toReplace = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, newSources), this);
toSchedule.set(insertPlace, toReplace);
// The size changed.
sz = toSchedule.size();
}
regsUsedAsSources.clear();
regsUsedAsResults.clear();
}
}
Aggregations