package com.android.dx.ssa.back;
import com.android.dx.rop.code.*;
import com.android.dx.rop.cst.CstInteger;
import com.android.dx.ssa.InterferenceRegisterMapper;
import com.android.dx.ssa.RegisterMapper;
import com.android.dx.ssa.SsaInsn;
import com.android.dx.ssa.SsaMethod;
import com.android.dx.ssa.NormalSsaInsn;
import com.android.dx.ssa.PhiInsn;
import com.android.dx.ssa.Optimizer;
import com.android.dx.ssa.SsaBasicBlock;
import com.android.dx.util.IntSet;
import com.android.dx.util.IntIterator;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Map;
import java.util.TreeMap;
/**
* Allocates registers in a first-fit fashion, with the bottom reserved for
* method parameters and all SSAregisters representing the same local variable
* kept together if possible.
*/
public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
/** local debug flag */
private static final boolean DEBUG = false;
/** maps local variable to a list of associated SSA registers */
private final Map<LocalItem, ArrayList<RegisterSpec>> localVariables;
/** list of move-result-pesudo instructions seen in this method */
private final ArrayList<NormalSsaInsn> moveResultPseudoInsns;
/** list of invoke-range instructions seen in this method */
private final ArrayList<NormalSsaInsn> invokeRangeInsns;
/** indexed by SSA reg; the set of SSA regs we've mapped */
private final BitSet ssaRegsMapped;
/** Register mapper which will be our result */
private final InterferenceRegisterMapper mapper;
/** end of rop registers range (starting at 0) reserved for parameters */
private final int paramRangeEnd;
/** set of rop registers reserved for parameters or local variables */
private final BitSet reservedRopRegs;
/** set of rop registers that have been used by anything */
private final BitSet usedRopRegs;
/** true if converter should take steps to minimize rop-form registers */
private final boolean minimizeRegisters;
/**
* Constructs instance.
*
* @param ssaMeth {@code non-null;} method to process
* @param interference non-null interference graph for SSA registers
* @param minimizeRegisters true if converter should take steps to
* minimize rop-form registers
*/
public FirstFitLocalCombiningAllocator(
SsaMethod ssaMeth, InterferenceGraph interference,
boolean minimizeRegisters) {
super(ssaMeth, interference);
ssaRegsMapped = new BitSet(ssaMeth.getRegCount());
mapper = new InterferenceRegisterMapper(
interference, ssaMeth.getRegCount());
this.minimizeRegisters = minimizeRegisters;
/*
* Reserve space for the params at the bottom of the register
* space. Later, we'll flip the params to the end of the register
* space.
*/
paramRangeEnd = ssaMeth.getParamWidth();
reservedRopRegs = new BitSet(paramRangeEnd * 2);
reservedRopRegs.set(0, paramRangeEnd);
usedRopRegs = new BitSet(paramRangeEnd * 2);
localVariables = new TreeMap<LocalItem, ArrayList<RegisterSpec>>();
moveResultPseudoInsns = new ArrayList<NormalSsaInsn>();
invokeRangeInsns = new ArrayList<NormalSsaInsn>();
}
/** {@inheritDoc} */
@Override
public boolean wantsParamsMovedHigh() {
return true;
}
/** {@inheritDoc} */
@Override
public RegisterMapper allocateRegisters() {
analyzeInstructions();
if (DEBUG) {
printLocalVars();
}
if (DEBUG) System.out.println("--->Mapping local-associated params");
handleLocalAssociatedParams();
if (DEBUG) System.out.println("--->Mapping other params");
handleUnassociatedParameters();
if (DEBUG) System.out.println("--->Mapping invoke-range");
handleInvokeRangeInsns();
if (DEBUG) {
System.out.println("--->Mapping local-associated non-params");
}
handleLocalAssociatedOther();
if (DEBUG) System.out.println("--->Mapping check-cast results");
handleCheckCastResults();
if (DEBUG) System.out.println("--->Mapping others");
handleNormalUnassociated();
return mapper;
}
/**
* Dumps local variable table to stdout for debugging.
*/
private void printLocalVars() {
System.out.println("Printing local vars");
for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> e :
localVariables.entrySet()) {
StringBuilder regs = new StringBuilder();
regs.append('{');
regs.append(' ');
for (RegisterSpec reg : e.getValue()) {
regs.append('v');
regs.append(reg.getReg());
regs.append(' ');
}
regs.append('}');
System.out.printf("Local: %s Registers: %s\n", e.getKey(), regs);
}
}
/**
* Maps all local-associated parameters to rop registers.
*/
private void handleLocalAssociatedParams() {
for (ArrayList<RegisterSpec> ssaRegs : localVariables.values()) {
int sz = ssaRegs.size();
int paramIndex = -1;
int paramCategory = 0;
// First, find out if this local variable is a parameter.
for (int i = 0; i < sz; i++) {
RegisterSpec ssaSpec = ssaRegs.get(i);
int ssaReg = ssaSpec.getReg();
paramIndex = getParameterIndexForReg(ssaReg);
if (paramIndex >= 0) {
paramCategory = ssaSpec.getCategory();
addMapping(ssaSpec, paramIndex);
break;
}
}
if (paramIndex < 0) {
// This local wasn't a parameter.
continue;
}
// Any remaining local-associated registers will be mapped later.
tryMapRegs(ssaRegs, paramIndex, paramCategory, true);
}
}
/**
* Gets the parameter index for SSA registers that are method parameters.
* {@code -1} is returned for non-parameter registers.
*
* @param ssaReg {@code >=0;} SSA register to look up
* @return parameter index or {@code -1} if not a parameter
*/
private int getParameterIndexForReg(int ssaReg) {
SsaInsn defInsn = ssaMeth.getDefinitionForRegister(ssaReg);
if (defInsn == null) {
return -1;
}
Rop opcode = defInsn.getOpcode();
// opcode == null for phi insns.
if (opcode != null && opcode.getOpcode() == RegOps.MOVE_PARAM) {
CstInsn origInsn = (CstInsn) defInsn.getOriginalRopInsn();
return ((CstInteger) origInsn.getConstant()).getValue();
}
return -1;
}
/**
* Maps all local-associated registers that are not parameters.
* Tries to find an unreserved range that's wide enough for all of
* the SSA registers, and then tries to map them all to that
* range. If not all fit, a new range is tried until all registers
* have been fit.
*/
private void handleLocalAssociatedOther() {
for (ArrayList<RegisterSpec> specs : localVariables.values()) {
int ropReg = 0;
boolean done;
do {
int maxCategory = 1;
// Compute max category for remaining unmapped registers.
int sz = specs.size();
for (int i = 0; i < sz; i++) {
RegisterSpec ssaSpec = specs.get(i);
int category = ssaSpec.getCategory();
if (!ssaRegsMapped.get(ssaSpec.getReg())
&& category > maxCategory) {
maxCategory = category;
}
}
ropReg = findRopRegForLocal(ropReg, maxCategory);
没有合适的资源?快使用搜索试试~ 我知道了~
FirstFitLocalCombiningAllocator.rar_The First
共1个文件
c:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 180 浏览量
2022-09-24
06:20:21
上传
评论
收藏 7KB RAR 举报
温馨提示
Allocates registers in a first-fit fashion, with the bottom reserved for method parameters and all SSAregisters representing the same local variable kept together if possible.
资源推荐
资源详情
资源评论
收起资源包目录
FirstFitLocalCombiningAllocator.rar (1个子文件)
FirstFitLocalCombiningAllocator.c 32KB
共 1 条
- 1
资源评论
Kinonoyomeo
- 粉丝: 77
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功