use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class SsaMethod method buildUseList.
/**
* Builds useList and unmodifiableUseList.
*/
private void buildUseList() {
if (backMode) {
throw new RuntimeException("No use list in back mode");
}
useList = new ArrayList[registerCount];
for (int i = 0; i < registerCount; i++) {
useList[i] = new ArrayList();
}
forEachInsn(new SsaInsn.Visitor() {
/** {@inheritDoc} */
public void visitMoveInsn(NormalSsaInsn insn) {
addToUses(insn);
}
/** {@inheritDoc} */
public void visitPhiInsn(PhiInsn phi) {
addToUses(phi);
}
/** {@inheritDoc} */
public void visitNonMoveInsn(NormalSsaInsn insn) {
addToUses(insn);
}
/**
* Adds specified insn to the uses list for all of its sources.
* @param insn {@code non-null;} insn to process
*/
private void addToUses(SsaInsn insn) {
RegisterSpecList rl = insn.getSources();
int sz = rl.size();
for (int i = 0; i < sz; i++) {
useList[rl.get(i).getReg()].add(insn);
}
}
});
unmodifiableUseList = new List[registerCount];
for (int i = 0; i < registerCount; i++) {
unmodifiableUseList[i] = Collections.unmodifiableList(useList[i]);
}
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class FirstFitLocalCombiningAllocator method findRangeAndAdjust.
/**
* Find a contiguous rop register range that fits the specified
* instruction's sources. First, try to center the range around
* sources that have already been mapped to rop registers. If that fails,
* just find a new contiguous range that doesn't interfere.
*
* @param insn {@code non-null;} the insn whose sources need to
* fit. Must be last insn in basic block.
* @return {@code >= 0;} rop register of start of range
*/
private int findRangeAndAdjust(NormalSsaInsn insn) {
RegisterSpecList sources = insn.getSources();
int szSources = sources.size();
// the category for each source index
int[] categoriesForIndex = new int[szSources];
int rangeLength = 0;
// Compute rangeLength and categoriesForIndex
for (int i = 0; i < szSources; i++) {
int category = sources.get(i).getCategory();
categoriesForIndex[i] = category;
rangeLength += categoriesForIndex[i];
}
// the highest score of fits tried so far
int maxScore = Integer.MIN_VALUE;
// the high scoring range's start
int resultRangeStart = -1;
// by source index: set of sources needing moves in high scoring plan
BitSet resultMovesRequired = null;
/*
* First, go through each source that's already been mapped. Try
* to center the range around the rop register this source is mapped
* to.
*/
int rangeStartOffset = 0;
for (int i = 0; i < szSources; i++) {
int ssaCenterReg = sources.get(i).getReg();
if (i != 0) {
rangeStartOffset -= categoriesForIndex[i - 1];
}
if (!ssaRegsMapped.get(ssaCenterReg)) {
continue;
}
int rangeStart = mapper.oldToNew(ssaCenterReg) + rangeStartOffset;
if (rangeStart < 0 || spansParamRange(rangeStart, rangeLength)) {
continue;
}
BitSet curMovesRequired = new BitSet(szSources);
int fitWidth = fitPlanForRange(rangeStart, insn, categoriesForIndex, curMovesRequired);
if (fitWidth < 0) {
continue;
}
int score = fitWidth - curMovesRequired.cardinality();
if (score > maxScore) {
maxScore = score;
resultRangeStart = rangeStart;
resultMovesRequired = curMovesRequired;
}
if (fitWidth == rangeLength) {
// We can't do any better than this, so stop here
break;
}
}
if (resultRangeStart == -1) {
resultMovesRequired = new BitSet(szSources);
resultRangeStart = findAnyFittingRange(insn, rangeLength, categoriesForIndex, resultMovesRequired);
}
for (int i = resultMovesRequired.nextSetBit(0); i >= 0; i = resultMovesRequired.nextSetBit(i + 1)) {
insn.changeOneSource(i, insertMoveBefore(insn, sources.get(i)));
}
return resultRangeStart;
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class FirstFitLocalCombiningAllocator method ssaSetToSpecs.
/**
* Converts a bit set of SSA registers into a RegisterSpecList containing
* the definition specs of all the registers.
*
* @param ssaSet {@code non-null;} set of SSA registers
* @return list of RegisterSpecs as noted above
*/
RegisterSpecList ssaSetToSpecs(IntSet ssaSet) {
RegisterSpecList result = new RegisterSpecList(ssaSet.elements());
IntIterator iter = ssaSet.iterator();
int i = 0;
while (iter.hasNext()) {
result.set(i++, getDefinitionSpecForSsaReg(iter.next()));
}
return result;
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class FirstFitLocalCombiningAllocator method fitPlanForRange.
/**
* Attempts to build a plan for fitting a range of sources into rop
* registers.
*
* @param ropReg {@code >= 0;} rop reg that begins range
* @param insn {@code non-null;} insn to plan range for
* @param categoriesForIndex {@code non-null;} indexed by source index;
* the category for each source
* @param outMovesRequired {@code non-null;} an output parameter indexed by
* source index that will contain the set of sources which need
* moves inserted
* @return the width of the fit that that does not involve added moves or
* {@code -1} if "no fit possible"
*/
private int fitPlanForRange(int ropReg, NormalSsaInsn insn, int[] categoriesForIndex, BitSet outMovesRequired) {
RegisterSpecList sources = insn.getSources();
int szSources = sources.size();
int fitWidth = 0;
IntSet liveOut = insn.getBlock().getLiveOutRegs();
RegisterSpecList liveOutSpecs = ssaSetToSpecs(liveOut);
// An SSA reg may only be mapped into a range once.
BitSet seen = new BitSet(ssaMeth.getRegCount());
for (int i = 0; i < szSources; i++) {
RegisterSpec ssaSpec = sources.get(i);
int ssaReg = ssaSpec.getReg();
int category = categoriesForIndex[i];
if (i != 0) {
ropReg += categoriesForIndex[i - 1];
}
if (ssaRegsMapped.get(ssaReg) && mapper.oldToNew(ssaReg) == ropReg) {
// This is a register that is already mapped appropriately.
fitWidth += category;
} else if (rangeContainsReserved(ropReg, category)) {
fitWidth = -1;
break;
} else if (!ssaRegsMapped.get(ssaReg) && canMapReg(ssaSpec, ropReg) && !seen.get(ssaReg)) {
// This is a register that can be mapped appropriately.
fitWidth += category;
} else if (!mapper.areAnyPinned(liveOutSpecs, ropReg, category) && !mapper.areAnyPinned(sources, ropReg, category)) {
/*
* This is a source that can be moved. We can insert a
* move as long as:
*
* * no SSA register pinned to the desired rop reg
* is live out on the block
*
* * no SSA register pinned to desired rop reg is
* a source of this insn (since this may require
* overlapping moves, which we can't presently handle)
*/
outMovesRequired.set(i);
} else {
fitWidth = -1;
break;
}
seen.set(ssaReg);
}
return fitWidth;
}
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();
}
}
});
}
Aggregations