/** * Maps all non-parameter, non-local variable registers. */ private void handleNormalUnassociated() { int szSsaRegs = ssaMeth.getRegCount(); for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) { if (ssaRegsMapped.get(ssaReg)) { // We already did this one continue; } RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg); if (ssaSpec == null) continue; int category = ssaSpec.getCategory(); // Find a rop reg that does not interfere int ropReg = findNextUnreservedRopReg(paramRangeEnd, category); while (!canMapReg(ssaSpec, ropReg)) { ropReg = findNextUnreservedRopReg(ropReg + 1, category); } addMapping(ssaSpec, ropReg); } }
/** * Handles all insns that want a register range for their sources. */ private void handleInvokeRangeInsns() { for (NormalSsaInsn insn : invokeRangeInsns) { adjustAndMapSourceRangeRange(insn); } }
/** {@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 phis"); handlePhiInsns(); if (DEBUG) System.out.println("--->Mapping others"); handleNormalUnassociated(); return mapper; }
/** * Finds unreserved rop registers with a specific category. * * @param startReg {@code >= 0;} a rop register to start the search at * @param regCategory {@code > 0;} category of the searched registers. * @return {@code >= 0;} start of available registers. */ private int findNextUnreservedRopReg(int startReg, int regCategory) { return findNextUnreservedRopReg(startReg, regCategory, getAlignment(regCategory)); }
/** * Maps any parameter that isn't local-associated, which can happen * in the case where there is no java debug info. */ private void handleUnassociatedParameters() { int szSsaRegs = ssaMeth.getRegCount(); for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) { if (ssaRegsMapped.get(ssaReg)) { // We already did this one above continue; } int paramIndex = getParameterIndexForReg(ssaReg); RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg); if (paramIndex >= 0) { addMapping(ssaSpec, paramIndex); } } }
/** * Finds an unreserved range that will fit the sources of the * specified instruction. Does not bother trying to center the range * around an already-mapped source register; * * @param insn {@code non-null;} insn to build range for * @param rangeLength {@code >=0;} length required in register units * @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 rop register that starts the fitting range */ private int findAnyFittingRange(NormalSsaInsn insn, int rangeLength, int[] categoriesForIndex, BitSet outMovesRequired) { int rangeStart = paramRangeEnd; while (true) { rangeStart = findNextUnreservedRopReg(rangeStart, rangeLength); int fitWidth = fitPlanForRange(rangeStart, insn, categoriesForIndex, outMovesRequired); if (fitWidth >= 0) { break; } rangeStart++; outMovesRequired.clear(); } return rangeStart; }
int newRegStart = findRangeAndAdjust(insn); LocalItem localItem = getLocalItemForReg(sourceReg); addMapping(source, curRopReg); markReserved(curRopReg, category); ArrayList<RegisterSpec> similarRegisters = localVariables.get(localItem); tryMapReg(similarSpec, curRopReg, category);
if (rangeStart < 0 || spansParamRange(rangeStart, rangeLength)) { continue; = fitPlanForRange(rangeStart, insn, categoriesForIndex, curMovesRequired); resultMovesRequired = new BitSet(szSources); resultRangeStart = findAnyFittingRange(insn, rangeLength, categoriesForIndex, resultMovesRequired); insn.changeOneSource(i, insertMoveBefore(insn, sources.get(i)));
ropReg = findRopRegForLocal(ropReg, maxCategory); if (canMapRegs(specs, ropReg)) { done = tryMapRegs(specs, ropReg, maxCategory, true);
/** * Tries to map an SSA register to a rop register. * * @param ssaSpec {@code non-null;} SSA register * @param ropReg {@code >=0;} rop register * @param maxAllowedCategory {@code 1..2;} the maximum category * that the SSA register is allowed to be * @return {@code true} if map succeeded, {@code false} if not */ private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg, int maxAllowedCategory) { if (ssaSpec.getCategory() <= maxAllowedCategory && !ssaRegsMapped.get(ssaSpec.getReg()) && canMapReg(ssaSpec, ropReg)) { addMapping(ssaSpec, ropReg); return true; } return false; }
int category = checkRegSpec.getCategory(); while (!tryMapRegs(ssaRegs, ropReg, category, false)) { ropReg = findNextUnreservedRopReg(ropReg + 1, category);
for (int category : categoriesForIndex) { if (category == 2) { if (isEven(regNumber)) { p64bitsAligned++; } else { if (isEven(paramRangeEnd)) { alignment = Alignment.ODD; } else { if (isEven(paramRangeEnd)) { alignment = Alignment.EVEN; } else { rangeStart = findNextUnreservedRopReg(rangeStart, rangeLength, alignment); int fitWidth = fitPlanForRange(rangeStart, insn, categoriesForIndex, outMovesRequired);
/** * Checks to see if a list of SSA registers can all be mapped into * the same rop reg. Ignores registers that have already been mapped, * and checks the interference graph and ensures the range does not * cross the parameter range. * * @param specs {@code non-null;} SSA registers to check * @param ropReg {@code >=0;} rop register to check mapping to * @return {@code true} if all unmapped registers can be mapped */ private boolean canMapRegs(ArrayList<RegisterSpec> specs, int ropReg) { for (RegisterSpec spec : specs) { if (ssaRegsMapped.get(spec.getReg())) continue; if (!canMapReg(spec, ropReg)) return false; } return true; }
new FirstFitLocalCombiningAllocator(ssaMeth, interference, minimizeRegisters);
/** * 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); done = tryMapRegs(specs, ropReg, maxCategory, true); // Increment for next call to findNext. ropReg++; } while (!done); } }
int newRegStart = findRangeAndAdjust(insn); LocalItem localItem = getLocalItemForReg(sourceReg); addMapping(source, curRopReg); markReserved(curRopReg, category); ArrayList<RegisterSpec> similarRegisters = localVariables.get(localItem); tryMapReg(similarSpec, curRopReg, category);
if (rangeStart < 0 || spansParamRange(rangeStart, rangeLength)) { continue; = fitPlanForRange(rangeStart, insn, categoriesForIndex, curMovesRequired); resultMovesRequired = new BitSet(szSources); resultRangeStart = findAnyFittingRange(insn, rangeLength, categoriesForIndex, resultMovesRequired); insn.changeOneSource(i, insertMoveBefore(insn, sources.get(i)));
/** * Maps any parameter that isn't local-associated, which can happen * in the case where there is no java debug info. */ private void handleUnassociatedParameters() { int szSsaRegs = ssaMeth.getRegCount(); for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) { if (ssaRegsMapped.get(ssaReg)) { // We already did this one above continue; } int paramIndex = getParameterIndexForReg(ssaReg); RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg); if (paramIndex >= 0) { addMapping(ssaSpec, paramIndex); } } }
ropReg = findRopRegForLocal(ropReg, maxCategory); if (canMapRegs(specs, ropReg)) { done = tryMapRegs(specs, ropReg, maxCategory, true);
/** * Tries to map an SSA register to a rop register. * * @param ssaSpec {@code non-null;} SSA register * @param ropReg {@code >=0;} rop register * @param maxAllowedCategory {@code 1..2;} the maximum category * that the SSA register is allowed to be * @return {@code true} if map succeeded, {@code false} if not */ private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg, int maxAllowedCategory) { if (ssaSpec.getCategory() <= maxAllowedCategory && !ssaRegsMapped.get(ssaSpec.getReg()) && canMapReg(ssaSpec, ropReg)) { addMapping(ssaSpec, ropReg); return true; } return false; }