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 ArrayList<Integer> setLoopEntryExit(int n, int position) { ArrayList<Integer> result = new ArrayList<Integer>(); int entryID, exitID; if (n == 1) { int id = cfg.getNextVertexID(); cfg.addBasicBlock(id); entryID = id; exitID = id; } else if (n < 3) { addNonBranchComponents(n); exitID = disconnectedVertices.get(0); entryID = disconnectedVertices.get(disconnectedVertices.size() - 1); } else { addBranchComponents(n); exitID = disconnectedBranches.get(0); entryID = disconnectedBranches.get(disconnectedBranches.size() - 1); } if (position == 1) { result.add(exitID); result.add(entryID); } else { result.add(entryID); result.add(exitID); } return result; }
void buildIndividualLoops(int loops) { for (int i = 0; i < loops; ++i) { int headerID = cfg.getNextVertexID(); Debug.debugMessage(getClass(), "Adding basic block " + headerID, 4); cfg.addBasicBlock(headerID); verticesInLoopBody.put(headerID, new ArrayList<Integer>()); int tailID = cfg.getNextVertexID(); Debug.debugMessage(getClass(), "Adding basic block " + tailID, 4); cfg.addBasicBlock(tailID); verticesInLoopBody.get(headerID).add(tailID); if (remainingVertices > 1) { int loopBody = random.nextInt(remainingVertices / 2 + 1) + 1; remainingVertices -= loopBody; decideLoopBody(loopBody, headerID); Debug.debugMessage( getClass(), "Adding edge " + headerID + "=>" + disconnectedBranches.get(0), 4); cfg.addEdge(headerID, disconnectedBranches.get(0), BranchType.TAKEN); Debug.debugMessage( getClass(), "Adding edge " + disconnectedBranches.get(disconnectedBranches.size() - 1) + "=>" + tailID, 4); cfg.addEdge( disconnectedBranches.get(disconnectedBranches.size() - 1), tailID, BranchType.TAKEN); } else { Debug.debugMessage(getClass(), "Adding edge " + headerID + "=>" + tailID, 4); cfg.addEdge(headerID, tailID, BranchType.TAKEN); } Debug.debugMessage(getClass(), "Adding edge " + tailID + "=>" + headerID, 4); cfg.addEdge(tailID, headerID, BranchType.TAKEN); disconnectedLoopsArray.add(headerID); disconnectedLoops.addVertex(headerID); } }
private void buildIndividualBlocks(int noOfComponents) { for (int i = 0; i < noOfComponents; ++i) { int branchID = cfg.getNextVertexID(); Debug.debugMessage(getClass(), "Adding basic block " + branchID, 4); cfg.addBasicBlock(branchID); int ifBranchID = cfg.getNextVertexID(); Debug.debugMessage(getClass(), "Adding basic block " + ifBranchID, 4); cfg.addBasicBlock(ifBranchID); int mergeID = cfg.getNextVertexID(); Debug.debugMessage(getClass(), "Adding basic block " + mergeID, 4); cfg.addBasicBlock(mergeID); Debug.debugMessage(getClass(), "Adding edge " + branchID + "=>" + ifBranchID, 4); cfg.addEdge(branchID, ifBranchID, BranchType.TAKEN); Debug.debugMessage(getClass(), "Adding edge " + ifBranchID + "=>" + mergeID, 4); cfg.addEdge(ifBranchID, mergeID, BranchType.TAKEN); Debug.debugMessage(getClass(), "Adding edge " + branchID + "=>" + mergeID, 4); cfg.addEdge(branchID, mergeID, BranchType.TAKEN); disconnectedBranches.add(branchID); disconnectedBranches.add(mergeID); } }
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 addNonBranchComponents(int n) { disconnectedVertices = new ArrayList<Integer>(); for (int i = 0; i < n; ++i) { int vertexID = cfg.getNextVertexID(); Debug.debugMessage(getClass(), "Adding basic block " + vertexID, 4); cfg.addBasicBlock(vertexID); disconnectedVertices.add(vertexID); } for (int i = 0; i < disconnectedVertices.size() - 1; ++i) { Debug.debugMessage( getClass(), "Adding edge " + disconnectedVertices.get(i) + "=>" + disconnectedVertices.get(i + 1), 4); cfg.addEdge(disconnectedVertices.get(i), disconnectedVertices.get(i + 1), BranchType.TAKEN); } }
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); } } }