@Test public void testGetType() throws Exception { final Line line1 = new Line("E"); assertThat(line1.getType(), is(Line.LineType.SPECIAL)); final Line line2 = new Line("4"); assertThat(line2.getType(), is(Line.LineType.TRAM)); final Line line3 = new Line("155"); assertThat(line3.getType(), is(Line.LineType.BUS)); }
private void mapRegistersToVariables() { Hashtable<String, String> prevMapRegToVar = null; for (int i = 0; i < getLines().getNumItems(); i++) { Line line = getLines().getItemAtIndex(i); if (Line.Type.INSTRUCTION == line.getType()) { Instruction instr = (Instruction) line; // Copy previous map, if available if (null != prevMapRegToVar) copyHashStringToString(instr.getMapRegToValue(), prevMapRegToVar); // On a load word, map the register to the variable if (0 == instr.getInstruction().compareTo("lw") || 0 == instr.getInstruction().compareTo("li")) { instr .getMapRegToValue() .put(instr.getArgument1().getName(), instr.getArgument2().getName()); } // On a store word, remove the register mapping else if (0 == instr.getInstruction().compareTo("sw")) { // instr.getMapRegToValue().remove(instr.getArgument1().getName()); // instr.getMapRegToValue().put(instr.getArgument1().getName(), // instr.getArgument2().getName()); } prevMapRegToVar = instr.getMapRegToValue(); } } }
private Instruction getNextInstr(LineList list, int i) { Line line = null; Instruction instr = null; if (i < list.getNumItems() - 1) line = list.getItemAtIndex(i + 1); if (null != line && Line.Type.INSTRUCTION == line.getType()) { instr = (Instruction) line; } return instr; }
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; }
public boolean calculateLiveIN() { boolean bChanges = false; mapRegistersToVariables(); // The last lastLive set is a copy of liveOUT LiveSet lastLive = new LiveSet(getLiveOut()); for (int i = getLines().getNumItems() - 1; i >= 0; i--) { Line line = getLines().getItemAtIndex(i); // Copy the last live set line.getLiveSet().copy(lastLive); if (Line.Type.INSTRUCTION == line.getType()) { Instruction instr = (Instruction) line; Argument arg2 = instr.getArgument2(); // If this is a SW instruction, then remove the // target variable from the live set if (0 == instr.getInstruction().compareTo("sw")) { // Remove the mapping to the variable line.getLiveSet().remove(arg2.getName()); // See if Argument1 is mapped to a variable if (instr.getMapRegToValue().containsKey(instr.getArgument1().getName())) { String strVal = instr.getMapRegToValue().get(instr.getArgument1().getName()); // Mark the variable as live line.getLiveSet().add(strVal); } } // If this is a LW instruction, then add the loaded // variable to the live set else if (0 == instr.getInstruction().compareTo("lw") || 0 == instr.getInstruction().compareTo("li")) { line.getLiveSet().add(arg2.getName()); } else if (!instr.getIsJump() && 0 != instr.getInstruction().compareTo("syscall") && 0 != instr.getInstruction().compareTo("move") && 0 != instr.getInstruction().compareTo("li")) { // See if Argument2 is mapped to a variable if (instr.getMapRegToValue().containsKey(instr.getArgument2().getName())) { String strVal = instr.getMapRegToValue().get(instr.getArgument2().getName()); // Mark the variable as live line.getLiveSet().add(strVal); } // See if Argument3 is mapped to a variable if (instr.getMapRegToValue().containsKey(instr.getArgument3().getName())) { String strVal = instr.getMapRegToValue().get(instr.getArgument3().getName()); // Mark the variable as live line.getLiveSet().add(strVal); } } else if (0 == instr.getInstruction().compareTo("move")) { // See if Argument2 is mapped to a variable if (instr.getMapRegToValue().containsKey(instr.getArgument2().getName())) { String strVal = instr.getMapRegToValue().get(instr.getArgument2().getName()); // Mark the variable as live line.getLiveSet().add(strVal); } } } lastLive = line.getLiveSet(); } getLiveIn().copy(lastLive); return bChanges; }