public boolean optimizeRegisterAllocation(RegAllocContext context, int nMaxRegisters) { boolean bChanges = false; ArrayList<Instruction> removeList = new ArrayList<Instruction>(); // Iterate through instructions for (int i = 0; i < getLines().getNumItems(); i++) { Line line = getLines().getItemAtIndex(i); Instruction nextInstr = getNextInstr(getLines(), i); if (Line.Type.INSTRUCTION == line.getType()) { Instruction instr = (Instruction) line; // If this is a LI instruction if (0 == instr.getInstruction().compareTo("li")) { // If the register is $v0, do nothing if (0 != instr.getArgument1().getName().compareTo("$v0")) { // Allocate Free register for dest String strFreeReg = findFirstFreeReg(context, instr.getLiveSet(), nMaxRegisters); // Map old register to this instruction context.mapRegToInstruction.put(instr.getArgument1().getName(), instr); context.regMap.put(strFreeReg, instr.getArgument2().getName()); context.variableLocs.put(instr.getArgument2().getName(), strFreeReg); // Rewrite Argument1 with new register instr.getArgument1().setOrigName(strFreeReg); } } // If this is a LW instruction else if (0 == instr.getInstruction().compareTo("lw")) { // If the variable is in a register, then remove this instruction if (0 != context.variableLocs.get(instr.getArgument2().getName()).compareTo("m")) { Line nextLine = getLines().getItemAtIndex(i + 1); Instruction next = null; if (Line.Type.INSTRUCTION == nextLine.getType()) next = (Instruction) nextLine; if (null == next || 0 != next.getInstruction().compareTo("sw")) removeList.add(instr); } // else if the variable is live, else // if(instr.getLiveSet().contains(instr.getArgument2().getName())) { // 1) allocate free register String strFreeReg = findFirstFreeReg(context, instr.getLiveSet(), nMaxRegisters); // 2) patch instruction if (null != strFreeReg) { context.regMap.put(strFreeReg, instr.getArgument2().getName()); context.variableLocs.put(instr.getArgument2().getName(), strFreeReg); instr.getArgument1().setOrigName(strFreeReg); } } } // If this is a SW instruction else if (0 == instr.getInstruction().compareTo("sw")) { // If the register is $v0, do nothing if (0 != instr.getArgument1().getName().compareTo("$v0")) { // If the instruction that is mapped to the register is an LW, then use the register // from that instruction. Line prevLine = getLines().getItemAtIndex(i - 1); Instruction prevInstr = null; if (Line.Type.INSTRUCTION == prevLine.getType()) prevInstr = (Instruction) prevLine; // context.mapRegToInstruction.get(instr.getArgument1().getOrigName()); if (null != prevInstr && 0 == prevInstr.getInstruction().compareTo("lw")) { String strReg = prevInstr.getArgument1().getOrigName(); instr.getArgument1().setOrigName(strReg); context.regMap.put(strReg, instr.getArgument2().getName()); context.variableLocs.put(instr.getArgument2().getName(), strReg); } // If the variable is live else if (null != nextInstr && nextInstr.getLiveSet().contains(instr.getArgument2().getName())) { // Add the variable to the live set instr.getLiveSet().add(instr.getArgument2().getName()); String strOldReg = instr.getArgument1().getOrigName(); String strNewReg = ""; // If the variable is already in a register if (0 != context.variableLocs.get(instr.getArgument2().getName()).compareTo("m")) { // Patch current instruction to use that register strNewReg = context.variableLocs.get(instr.getArgument2().getName()); instr.getArgument1().setOrigName(strNewReg); } // Else else { // Allocate free register strNewReg = findFirstFreeReg(context, instr.getLiveSet(), nMaxRegisters); // patch instruction if (null != strNewReg) { context.regMap.put(strNewReg, instr.getArgument2().getName()); context.variableLocs.put(instr.getArgument2().getName(), strNewReg); instr.getArgument1().setOrigName(strNewReg); } } // Patch register's last-used instruction Instruction oldInstr = context.mapRegToInstruction.get(strOldReg); if (null != oldInstr) oldInstr.getArgument1().setOrigName(strNewReg); } // If the previous instruction is an operation... else if (null != prevInstr && prevInstr.isOperation()) { String strReg = prevInstr.getArgument1().getOrigName(); instr.getArgument1().setOrigName(strReg); // Remove the mapping from the register to the instruction context.mapRegToInstruction.remove(prevInstr.getArgument1().getName()); // context.regMap.put(strReg, instr.getArgument2().getName()); // context.variableLocs.put(instr.getArgument2().getName(), strReg); } // If the register is mapped to a variable held in a register else if (instr.getMapRegToValue().containsKey(instr.getArgument1().getName())) { String strOldReg = instr.getArgument1().getName(); String strVar = instr.getMapRegToValue().get(instr.getArgument1().getName()); String strNewReg = context.variableLocs.get(strVar); if (null != strNewReg && 0 != strNewReg.compareTo("m")) { // Update the register instr.getArgument1().setOrigName(strNewReg); // Find last instruction that referenced old reg Instruction oldInstr = context.mapRegToInstruction.get(strOldReg); if (null != oldInstr) { oldInstr.getArgument1().setOrigName(strNewReg); } } } else // Use temp { String strOldReg = instr.getArgument1().getName(); // Allocate temp register for dest String strTempReg = getTempRegister(nMaxRegisters); // Update the register instr.getArgument1().setOrigName(strTempReg); // Find last instruction that referenced old reg Instruction oldInstr = context.mapRegToInstruction.get(strOldReg); if (null != oldInstr) { oldInstr.getArgument1().setOrigName(strTempReg); } } } } // If it is the NEG function else if (0 == instr.getInstruction().compareTo("neg")) { remapRegister(context, instr, instr.getArgument1()); } // If this is another non-jump instruction else if (!instr.getIsJump() && 0 != instr.getInstruction().compareTo("syscall") && 0 != instr.getInstruction().compareTo("move")) { // Allocate temp register for dest String strTempReg = getTempRegister(nMaxRegisters); // Map old register to this instruction context.mapRegToInstruction.put(instr.getArgument1().getName(), instr); // Rewrite Argument1 with temp register instr.getArgument1().setOrigName(strTempReg); remapRegister(context, instr, instr.getArgument2()); remapRegister(context, instr, instr.getArgument3()); } else if (0 == instr.getInstruction().compareTo("move")) { remapRegister(context, instr, instr.getArgument2()); } // If this is a jump instruction else if (instr.getIsJump() && Instruction.BranchType.JUMP != instr.getBranchType()) { String strTempReg = getTempRegister(nMaxRegisters); // Rewrite Argument1 with temp register instr.getArgument1().setOrigName(strTempReg); } } deallocateNonLiveVars(line, context, nMaxRegisters); } // Remove lines for (int i = 0; i < removeList.size(); i++) { getLines().removeLine(removeList.get(i)); } return bChanges; }