예제 #1
0
  private void addLoops() {
    int loops = MainProgramGenerator.Globals.getNumberOfLoops();
    int vertices = MainProgramGenerator.Globals.getNumberOfVerticesInCFG();

    if (vertices == 1) {
      cfg.addBasicBlock(vertices);
    } else {
      if (loops == 0) {
        addNoLoops(vertices);
      } else {
        int entryID, exitID, endOfExitStructure = 0;
        remainingVertices = vertices - 2 * loops;

        if (remainingVertices == 2) {
          entryID = setLoopEntryExit(1, 0).get(0);
          exitID = setLoopEntryExit(1, 1).get(0);
          remainingVertices = 0;
        } else {
          int loopEntry = random.nextInt(remainingVertices / 2) + 1;
          remainingVertices -= loopEntry;
          entryID = setLoopEntryExit(loopEntry, 0).get(0);

          int loopExit = random.nextInt(remainingVertices / 2) + 1;
          remainingVertices -= loopExit;
          ArrayList<Integer> exit = setLoopEntryExit(loopExit, 1);
          exitID = exit.get(0);
          endOfExitStructure = exit.get(1);
        }

        buildIndividualLoops(loops);
        initLevelMap();
        setLoopTree(loops);
        connectLoops();

        if (remainingVertices > 0) {
          int newExitID = setLoopEntryExit(remainingVertices, 1).get(0);
          remainingVertices = 0;
          Debug.debugMessage(getClass(), "Adding edge " + endOfExitStructure + "=>" + newExitID, 4);
          cfg.addEdge(endOfExitStructure, newExitID, BranchType.TAKEN);
        }

        Debug.debugMessage(
            getClass(), "Adding entry edge " + entryID + "=>" + disconnectedLoopsArray.get(0), 4);
        cfg.addEdge(entryID, disconnectedLoopsArray.get(0), BranchType.TAKEN);
        Debug.debugMessage(
            getClass(), "Adding exit edge " + disconnectedLoopsArray.get(0) + "=>" + exitID, 4);
        cfg.addEdge(disconnectedLoopsArray.get(0), exitID, BranchType.TAKEN);
      }
    }
  }
예제 #2
0
  private void enforceSingleEntry() {
    Debug.debugMessage(getClass(), "Enforcing single entry in CFG", 3);

    ArrayList<Vertex> noPreds = new ArrayList<Vertex>();
    for (Vertex v : cfg) {
      if (v.numOfPredecessors() == 0) {
        Debug.debugMessage(getClass(), v.getVertexID() + " is currently an entry vertex", 4);
        noPreds.add(v);
      }
    }

    while (noPreds.size() > 1) {
      int newVertexID = cfg.getNextVertexID();
      cfg.addBasicBlock(newVertexID);
      Debug.debugMessage(getClass(), "Adding basic block " + newVertexID, 4);

      for (int i = 1; i <= MainProgramGenerator.Globals.getFanOut(); ++i) {
        if (!noPreds.isEmpty()) {
          Vertex v = noPreds.remove(noPreds.size() - 1);
          Debug.debugMessage(getClass(), "...and connecting it to " + v.getVertexID(), 4);

          if (i == 1) {
            cfg.addEdge(newVertexID, v.getVertexID(), BranchType.TAKEN);
          } else {
            cfg.addEdge(newVertexID, v.getVertexID(), BranchType.NOTTAKEN);
          }
        }
      }

      noPreds.add(cfg.getVertex(newVertexID));
    }
  }
예제 #3
0
  private void setLoopTree(int loops) {
    int loopDepth = MainProgramGenerator.Globals.getLoopNestingDepth();
    ArrayList<Integer> loopsArray = new ArrayList<Integer>(disconnectedLoopsArray);
    disconnectedLoops.setRootID(loopsArray.remove(0));
    levelMap.put(disconnectedLoops.getRootID(), 0);

    while (!loopsArray.isEmpty()) {
      int loopHeader = loopsArray.remove(loopsArray.size() - 1);
      ArrayList<Integer> candidateHeaders = new ArrayList<Integer>();

      for (Integer key : levelMap.keySet()) {
        int level = levelMap.get(key);
        if (level != -1 && level <= loopDepth) {
          candidateHeaders.add(key);
        }
      }

      int predecessors = random.nextInt(candidateHeaders.size()) + 1;
      for (int i = 1; i <= predecessors; ++i) {
        int predecessorIndex = random.nextInt(candidateHeaders.size());
        int predecessorID = candidateHeaders.remove(predecessorIndex);

        disconnectedLoops.addEdge(predecessorID, loopHeader);

        if (levelMap.get(predecessorID) > levelMap.get(loopHeader)) {
          levelMap.put(loopHeader, levelMap.get(predecessorID) + 1);
        }
      }
    }
    disconnectedLoops.setHeight();
  }
예제 #4
0
  private void addSelfLoops() {
    int counter = MainProgramGenerator.Globals.getNumberOfSelfLoops();
    while (counter > 0) {
      int vertexID;
      do {
        vertexID = random.nextInt(cfg.numOfVertices() + 1);
      } while (vertexID == cfg.getEntryID());

      Debug.debugMessage(getClass(), "Adding self-loop " + vertexID + " => " + vertexID, 4);
      cfg.addEdge(vertexID, vertexID, BranchType.TAKEN);
      counter--;
    }
  }
예제 #5
0
  private void checkExits() {
    Debug.debugMessage(getClass(), "Enforcing single exit out of CFG", 3);

    ArrayList<Vertex> noSuccs = new ArrayList<Vertex>();
    for (Vertex v : cfg) {
      if (v.numOfSuccessors() == 0) {
        Debug.debugMessage(getClass(), v.getVertexID() + " is currently an exit vertex", 4);
        noSuccs.add(v);
      }
    }

    if (noSuccs.size() > MainProgramGenerator.Globals.getNumberOfReturns()) {
      int newVertexID = cfg.getNextVertexID();
      cfg.addBasicBlock(newVertexID);
      Debug.debugMessage(getClass(), "Adding basic block " + newVertexID, 4);

      while (!noSuccs.isEmpty()) {
        Vertex v = noSuccs.remove(noSuccs.size() - 1);
        Debug.debugMessage(getClass(), "...and connecting it from " + v.getVertexID(), 4);
        cfg.addEdge(v.getVertexID(), newVertexID, BranchType.TAKEN);
      }
    }
  }