Exemplo n.º 1
0
      @Override
      public Boolean caseProcedure(Procedure procedure) {
        this.procedure = procedure;

        // Test if The procedure contains a BlockWhile before size - 1
        int blockSize = procedure.getBlocks().size();
        if (blockSize > 1) {
          Block block = procedure.getBlocks().get(blockSize - 2);
          if (block.isBlockWhile()) {
            // If it is check if an additional loop should be added
            doSwitch(block);
          } else {
            return true;
          }
        }

        return false;
      }
Exemplo n.º 2
0
  private boolean isSinlgeReturnBlock(Block block) {
    if (block.isBlockBasic()) {
      BlockBasic basic = (BlockBasic) block;
      if (basic.getInstructions().size() == 1) {
        Instruction instruction = basic.getInstructions().get(0);
        if (instruction.isInstReturn()) {
          return true;
        }
      }
    }

    return false;
  }
Exemplo n.º 3
0
  @Override
  public Void caseAction(Action action) {
    // FIXME: Do not detect a pathological case for the moment,
    // extra clock cycles

    for (Port port : action.getOutputPattern().getPorts()) {
      int size = action.getOutputPattern().getNumTokensMap().get(port);
      if (size > 1) {
        Var newVar = newPortToVarMap.get(port);
        Var var = action.getOutputPattern().getPortToVarMap().get(port);

        EList<Use> uses = var.getUses();
        while (!uses.isEmpty()) {
          uses.get(0).setVariable(newVar);
        }
        EList<Def> defs = var.getDefs();
        while (!defs.isEmpty()) {
          defs.get(0).setVariable(newVar);
        }

        // Create the Block while for the repeat
        BlockWhile whileBlock = IrFactory.eINSTANCE.createBlockWhile();
        whileBlock.setJoinBlock(IrFactory.eINSTANCE.createBlockBasic());

        // Create the condition
        Type type = IrFactory.eINSTANCE.createTypeInt(32);
        Var index = IrFactory.eINSTANCE.createVar(type, "rp_Index_" + port.getName(), true, 0);

        action.getBody().getLocals().add(index);

        ExprVar condE0 = IrFactory.eINSTANCE.createExprVar(index);
        ExprInt condE1 = IrFactory.eINSTANCE.createExprInt(size);

        ExprBinary whileCond =
            IrFactory.eINSTANCE.createExprBinary(
                condE0, OpBinary.LT, condE1, IrFactory.eINSTANCE.createTypeBool());

        whileBlock.setCondition(whileCond);

        // Create an if block with a pin Status as condition

        Var pinStatus =
            IrFactory.eINSTANCE.createVar(
                IrFactory.eINSTANCE.createTypeBool(), "portStatus_" + port.getName(), true, 0);
        action.getBody().getLocals().add(pinStatus);

        // Add portStatus to the first block of the while
        BlockBasic firstWhileBlock = IrFactory.eINSTANCE.createBlockBasic();
        InstPortStatus portStatus = XronosIrUtil.createInstPortStatus(pinStatus, port);
        firstWhileBlock.add(portStatus);
        whileBlock.getBlocks().add(firstWhileBlock);

        BlockIf blockIf = IrFactory.eINSTANCE.createBlockIf();
        blockIf.setJoinBlock(IrFactory.eINSTANCE.createBlockBasic());

        ExprVar ifCond = IrFactory.eINSTANCE.createExprVar(pinStatus);
        blockIf.setCondition(ifCond);

        // -----------------------------------------------------------
        // Then Block

        // Create While blockBasic
        BlockBasic thenBlock = IrFactory.eINSTANCE.createBlockBasic();

        // Create a Load instruction
        Type tmpLoadType = IrUtil.copy(port.getType());
        Var tmpLoad =
            IrFactory.eINSTANCE.createVar(tmpLoadType, "tmp_rp_" + port.getName(), true, 0);
        action.getBody().getLocals().add(tmpLoad);

        ExprVar loadIndex = IrFactory.eINSTANCE.createExprVar(index);

        InstLoad load =
            IrFactory.eINSTANCE.createInstLoad(
                tmpLoad, newVar, Arrays.asList((Expression) loadIndex));

        thenBlock.add(load);

        // Create the Port Write instruction
        InstPortWrite portWrite = XronosIrUtil.createInstPortWrite(port, tmpLoad, false);

        thenBlock.add(portWrite);

        // Create the instruction assign with index++
        ExprVar assignE0 = IrFactory.eINSTANCE.createExprVar(index);
        ExprInt assignE1 = IrFactory.eINSTANCE.createExprInt(1);

        ExprBinary assignValue =
            IrFactory.eINSTANCE.createExprBinary(
                assignE0, OpBinary.PLUS, assignE1, IrFactory.eINSTANCE.createTypeInt());

        InstAssign assignIndex = IrFactory.eINSTANCE.createInstAssign(index, assignValue);
        thenBlock.add(assignIndex);

        // -----------------------------------------------------------

        // Add to thenBlocks the thenBlock
        blockIf.getThenBlocks().add(thenBlock);

        // Add the ifBlock to the Block While
        whileBlock.getBlocks().add(blockIf);

        // Create a Block Basic with rp_Index_ to 0
        BlockBasic initRpIndex = IrFactory.eINSTANCE.createBlockBasic();
        InstAssign rpAssignZero = IrFactory.eINSTANCE.createInstAssign(index, 0);
        initRpIndex.add(rpAssignZero);

        // Add the BlockWhile to the body of the procedure
        int indexBlock = action.getBody().getBlocks().size();
        Block lastBlock = action.getBody().getBlocks().get(indexBlock - 1);
        if (isSinlgeReturnBlock(lastBlock)) {
          action.getBody().getBlocks().add(indexBlock - 1, initRpIndex);
          action.getBody().getBlocks().add(indexBlock, whileBlock);
        } else {
          if (lastBlock.isBlockBasic()) {
            BlockBasic basic = (BlockBasic) lastBlock;
            int instrSize = basic.getInstructions().size();
            if (basic.getInstructions().get(instrSize - 1).isInstReturn()) {
              Instruction returnInst = basic.getInstructions().get(instrSize - 1);
              BlockBasic newLastBlock = IrFactory.eINSTANCE.createBlockBasic();
              newLastBlock.add(returnInst);
              action.getBody().getBlocks().add(initRpIndex);
              action.getBody().getBlocks().add(whileBlock);
              action.getBody().getBlocks().add(newLastBlock);
            }
          }
        }
      }
    }

    return null;
  }