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); } } }
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)); } }
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(); }
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--; } }
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); } } }