Example #1
0
  @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));
  }
Example #2
0
  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();
      }
    }
  }
Example #3
0
  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;
  }
Example #4
0
  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;
  }
Example #5
0
  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;
  }