Example #1
0
  public void writeInline(EmitContext emitContext, InstructionAdapter mv) {

    // Last check for assumption violations
    types.verifyFunctionAssumptions(runtimeState);

    Label exitLabel = new Label();

    for (BasicBlock basicBlock : cfg.getBasicBlocks()) {
      if (basicBlock != cfg.getEntry() && basicBlock != cfg.getExit()) {
        for (IRLabel label : basicBlock.getLabels()) {
          mv.visitLabel(emitContext.getAsmLabel(label));
        }
        for (Statement stmt : basicBlock.getStatements()) {
          try {
            if (stmt instanceof ReturnStatement) {
              // Instead of returning, just push the return value on the stack
              // and jump to the exit point for the function.
              stmt.getRHS().load(emitContext, mv);
              mv.goTo(exitLabel);

            } else {
              stmt.emit(emitContext, mv);
            }
          } catch (NotCompilableException e) {
            throw e;
          } catch (Exception e) {
            throw new InternalCompilerException("Exception compiling statement " + stmt, e);
          }
        }
      }
    }
    mv.mark(exitLabel);
  }
Example #2
0
  public RPST build() {
    // find canonical regions
    detectRegions();

    // build tree of canonical regions
    RPSTRegion root = new RPSTRegion(cfg.getEntryBlock(), null);
    buildRegionTree(cfg.getEntryBlock(), root);

    // build children
    for (RPSTRegion r : bb2region.values()) {
      for (RPSTRegion r2 = r; r2 != null; r2 = r2.parent) {
        if (r2.parent != null) {
          r2.parent.children.add(r2);
        }
      }
    }

    RPST rpst = new RPST(cfg, new RegionImpl(cfg.getEntryBlock(), null, ParentType.ROOT));
    Map<RPSTRegion, Region> mapR = new HashMap<>();
    a(root, rpst.getRootRegion(), rpst, mapR);
    for (Map.Entry<BasicBlock, RPSTRegion> entry : bb2region.entrySet()) {
      BasicBlock bb = entry.getKey();
      RPSTRegion r = entry.getValue();
      Region r2 = mapR.get(r);
      rpst.addRegion(bb, r2);
    }

    // add non canonical region to the tree
    findNonCanonicalRegions(rpst, rpst.getRootRegion());

    return rpst;
  }
Example #3
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));
    }
  }
Example #4
0
  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;
  }
 /**
  * Gets all the edges of the graph.
  */
 private static List<DiGraphEdge<Node, Branch>> getAllEdges(
     ControlFlowGraph<Node> cfg) {
   List<DiGraphEdge<Node, Branch>> edges = new ArrayList<>();
   for (DiGraphNode<Node, Branch> n : cfg.getDirectedGraphNodes()) {
     edges.addAll(cfg.getOutEdges(n.getValue()));
   }
   return edges;
 }
  @Test
  public void singleBlock() {
    IRBody block = buildBody("y<-x+1;z<-3; 4");
    ControlFlowGraph cfg = new ControlFlowGraph(block);

    System.out.println(cfg);

    List<BasicBlock> basicBlocks = cfg.getBasicBlocks();
    assertThat(basicBlocks.size(), equalTo(3)); // entry + 1 + exit = 3
    assertThat(basicBlocks.get(1).getStatements().size(), equalTo(block.getStatements().size()));
  }
  @Test
  public void forLoop() {
    IRBody block = buildBody("y <- 0; for(i in 1:10) y <- y + i; sqrt(y + 3 * x)");
    System.out.println(block);

    ControlFlowGraph cfg = new ControlFlowGraph(block);
    System.out.println(cfg);

    List<BasicBlock> basicBlocks = cfg.getBasicBlocks();
    assertThat(basicBlocks.size(), equalTo(7));
  }
Example #8
0
 private void printAllRegions() {
   for (BasicBlock bb1 : cfg.getBasicBlocks()) {
     for (BasicBlock bb2 : cfg.getBasicBlocks()) {
       if (!bb1.equals(bb2) && getDomInfo().dominates(bb1, bb2)) {
         if (isRegion(bb1, bb2)) {
           LOGGER.debug("REGION {},{}", bb1, bb2);
         }
       }
     }
   }
 }
Example #9
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--;
    }
  }
Example #10
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);
      }
    }
  }
    /** @return true if all paths from block must exit with an explicit return. */
    private boolean allPathsReturn(Node function) {
      // Computes the control flow graph.
      ControlFlowAnalysis cfa = new ControlFlowAnalysis(compiler, false, false);
      cfa.process(null, function);
      ControlFlowGraph<Node> cfg = cfa.getCfg();

      Node returnPathsParent = cfg.getImplicitReturn().getValue();
      for (DiGraphNode<Node, Branch> pred : cfg.getDirectedPredNodes(returnPathsParent)) {
        Node n = pred.getValue();
        if (!n.isReturn()) {
          return false;
        }
      }
      return true;
    }
Example #12
0
  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);
    }
  }
Example #13
0
 @Override
 public int hashCode() {
   final int prime = 31;
   int result = 1;
   result = prime * result + ((cfg == null) ? 0 : cfg.hashCode());
   result = prime * result + ((context == null) ? 0 : context.hashCode());
   return result;
 }
Example #14
0
 private boolean isCommonDomFrontier(BasicBlock bb, BasicBlock entry, BasicBlock exit) {
   for (BasicBlock p : cfg.getPredecessorsOf(bb)) {
     if (getDomInfo().dominates(entry, p) && !getDomInfo().dominates(exit, p)) {
       return false;
     }
   }
   return true;
 }
 private void addIndirectEntrypoints(ControlFlowGraph.Edge edge, ControlFlowGraph cfg) {
   List<Integer> edges = program.getIndirectEdges(edge.getSource().getLastAddress());
   if (edges == null) return;
   for (Integer targetAddr : edges) {
     ControlFlowGraph.Block target = cfg.getBlockStartingAt(targetAddr);
     if (target != null) {
       ENTRYPOINTS.add(target);
     }
   }
 }
Example #16
0
 /** Test if two canonical regions could be merge in one non canonical region. */
 private boolean isNonCanonicalRegion(RPST rpst, Region region1, Region region2) {
   if (!region1.getExit().equals(region2.getEntry())) {
     return false;
   }
   if (rpst.getChildCount(region2) == 0) {
     return false;
   }
   // basic blocks of merged region
   Set<BasicBlock> basicBlocks = new HashSet<>();
   basicBlocks.addAll(rpst.getBasicBlocks(region1));
   basicBlocks.addAll(rpst.getBasicBlocks(region2));
   basicBlocks.add(region2.getExit());
   if (!basicBlocks.containsAll(cfg.getSuccessorsOf(region1.getExit()))) {
     return false;
   }
   if (!basicBlocks.containsAll(cfg.getPredecessorsOf(region1.getExit()))) {
     return false;
   }
   return true;
 }
  @Override
  public void process(Node externs, Node root) {
    this.root = root;
    astPositionCounter = 0;
    astPosition = Maps.newHashMap();
    nodePriorities = Maps.newHashMap();
    cfg = new AstControlFlowGraph(computeFallThrough(root), nodePriorities);
    NodeTraversal.traverse(compiler, root, this);
    astPosition.put(null, ++astPositionCounter); // the implicit return is last.

    // Now, generate the priority of nodes by doing a depth-first
    // search on the CFG.
    priorityCounter = 0;
    DiGraphNode<Node, Branch> entry = cfg.getEntry();
    prioritizeFromEntryNode(entry);

    if (shouldTraverseFunctions) {
      // If we're traversing inner functions, we need to rank the
      // priority of them too.
      for (DiGraphNode<Node, Branch> candidate : cfg.getDirectedGraphNodes()) {
        Node value = candidate.getValue();
        if (value != null && value.getType() == Token.FUNCTION) {
          Preconditions.checkState(!nodePriorities.containsKey(candidate) || candidate == entry);
          prioritizeFromEntryNode(candidate);
        }
      }
    }

    // At this point, all reachable nodes have been given a priority, but
    // unreachable nodes have not been given a priority. Put them last.
    // Presumably, it doesn't really matter what priority they get, since
    // this shouldn't happen in real code.
    for (DiGraphNode<Node, Branch> candidate : cfg.getDirectedGraphNodes()) {
      if (!nodePriorities.containsKey(candidate)) {
        nodePriorities.put(candidate, ++priorityCounter);
      }
    }

    // Again, the implicit return node is always last.
    nodePriorities.put(cfg.getImplicitReturn(), ++priorityCounter);
  }
 /**
  * Assert that there exists no control flow edge of the given type
  * from some node with the first token to the return node.
  */
 private static void assertNoReturnEdge(ControlFlowGraph<Node> cfg,
     int startToken) {
   List<DiGraphEdge<Node, Branch>> edges = getAllEdges(cfg);
   for (DiGraphEdge<Node, Branch> edge : edges) {
     Node source = edge.getSource().getValue();
     DiGraphNode<Node, Branch> dest = edge.getDestination();
     if (source.getType() == startToken) {
       assertFalse("Token " + startToken + " should not have an out going"
           + " edge to the implicit return", cfg.isImplicitReturn(dest));
       return;
     }
   }
 }
  private void discoverEntrypoints() {
    ENTRYPOINTS = new HashSet<ControlFlowGraph.Block>();

    // discover edges that have incoming call edges
    Iterator<ControlFlowGraph.Edge> edges = cfg.getEdgeIterator();
    while (edges.hasNext()) {
      ControlFlowGraph.Edge edge = edges.next();
      if ("CALL".equals(edge.getType())) {
        if (edge.getTarget() == null) {
          addIndirectEntrypoints(edge, cfg);
        } else ENTRYPOINTS.add(edge.getTarget());
      }
    }
  }
Example #20
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);
      }
    }
  }
  /**
   * Assert that there exists a control flow edge of the given type
   * from some node with the first token to the return node.
   */
  private static void assertReturnEdge(ControlFlowGraph<Node> cfg,
      int startToken) {
    List<DiGraphEdge<Node, Branch>> edges = getAllEdges(cfg);
    for (DiGraphEdge<Node, Branch> edge : edges) {
      Node source = edge.getSource().getValue();
      DiGraphNode<Node, Branch> dest = edge.getDestination();
      if (source.getType() == startToken &&
          cfg.isImplicitReturn(dest)) {
        return;
      }
    }

    fail("No return edge found");
  }
 private FlowState<LiveVariablesAnalysis.LiveVariableLattice> getFlowStateAtX(
     Node node, ControlFlowGraph<Node> cfg) {
   if (node.getType() == Token.LABEL) {
     if (node.getFirstChild().getString().equals("X")) {
       return cfg.getNode(node.getLastChild()).getAnnotation();
     }
   }
   for (Node c = node.getFirstChild(); c != null; c = c.getNext()) {
     FlowState<LiveVariablesAnalysis.LiveVariableLattice> state = getFlowStateAtX(c, cfg);
     if (state != null) {
       return state;
     }
   }
   return null;
 }
Example #23
0
  @Override
  @SuppressWarnings({"AccessingNonPublicFieldOfAnotherObject"})
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;

    SuperGraphNode other = (SuperGraphNode) obj;
    if (cfg == null) {
      if (other.cfg != null) return false;
    } else if (!cfg.equals(other.cfg)) return false;
    if (context == null) {
      if (other.context != null) return false;
    } else if (!context.equals(other.context)) return false;
    return true;
  }
Example #24
0
  private void connectBranches(int noOfComponents, int unusedNodes) {
    if (noOfComponents > 1) {
      int destinationToRemove = random.nextInt(2);
      for (int i = 0; i < disconnectedBranches.size() - 3; i = i + 2) {
        if (random.nextBoolean()) {
          int sourceID = disconnectedBranches.get(i);
          int destinationRemovedID;
          if (destinationToRemove == 0) {
            destinationRemovedID =
                cfg.getVertex(sourceID).getNthSuccessor(destinationToRemove).getVertexID();
          } else {
            destinationRemovedID = disconnectedBranches.get(i + 1);
          }
          Debug.debugMessage(
              getClass(), "Removing edge " + sourceID + "=>" + destinationRemovedID, 4);
          cfg.removeEdge(sourceID, destinationRemovedID);

          int newDestinationID = disconnectedBranches.get(i + 2);
          Debug.debugMessage(getClass(), "Adding edge " + sourceID + "=>" + newDestinationID, 4);
          cfg.addEdge(sourceID, newDestinationID, BranchType.TAKEN);

          sourceID = disconnectedBranches.get(i + 3);
          Debug.debugMessage(
              getClass(), "Adding edge " + sourceID + "=>" + destinationRemovedID, 4);
          cfg.addEdge(sourceID, destinationRemovedID, BranchType.TAKEN);

        } else {
          Debug.debugMessage(
              getClass(),
              "Adding edge "
                  + disconnectedBranches.get(i + 1)
                  + "=>"
                  + disconnectedBranches.get(i + 2),
              4);
          cfg.addEdge(
              disconnectedBranches.get(i + 1), disconnectedBranches.get(i + 2), BranchType.TAKEN);
        }
      }
    }

    if (unusedNodes > 0) {
      addNonBranchComponents(unusedNodes);
      Debug.debugMessage(
          getClass(),
          "Adding edge "
              + disconnectedBranches.get(disconnectedBranches.size() - 1)
              + "=>"
              + disconnectedVertices.get(0),
          4);
      cfg.addEdge(
          disconnectedBranches.get(disconnectedBranches.size() - 1),
          disconnectedVertices.get(0),
          BranchType.TAKEN);
    }
  }
Example #25
0
  public LoopsData(final StructuredGraph graph) {
    cfg =
        Debug.scope(
            "ControlFlowGraph",
            new Callable<ControlFlowGraph>() {

              @Override
              public ControlFlowGraph call() throws Exception {
                return ControlFlowGraph.compute(graph, true, true, true, true);
              }
            });
    for (Loop lirLoop : cfg.getLoops()) {
      LoopEx ex = new LoopEx(lirLoop, this);
      lirLoopToEx.put(lirLoop, ex);
      loopBeginToEx.put(ex.loopBegin(), ex);
    }
  }
Example #26
0
  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);
    }
  }
Example #27
0
  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);
    }
  }
  /** Given an entry node, find all the nodes reachable from that node and prioritize them. */
  private void prioritizeFromEntryNode(DiGraphNode<Node, Branch> entry) {
    PriorityQueue<DiGraphNode<Node, Branch>> worklist =
        new PriorityQueue<DiGraphNode<Node, Branch>>(10, priorityComparator);
    worklist.add(entry);

    while (!worklist.isEmpty()) {
      DiGraphNode<Node, Branch> current = worklist.remove();
      if (nodePriorities.containsKey(current)) {
        continue;
      }

      nodePriorities.put(current, ++priorityCounter);

      List<DiGraphNode<Node, Branch>> successors = cfg.getDirectedSuccNodes(current);
      for (DiGraphNode<Node, Branch> candidate : successors) {
        worklist.add(candidate);
      }
    }
  }
 /** Determines if the subtree might throw an exception. */
 private static boolean mayThrowException(Node n) {
   switch (n.getType()) {
     case Token.CALL:
     case Token.GETPROP:
     case Token.GETELEM:
     case Token.THROW:
     case Token.NEW:
     case Token.ASSIGN:
     case Token.INC:
     case Token.DEC:
     case Token.INSTANCEOF:
       return true;
     case Token.FUNCTION:
       return false;
   }
   for (Node c = n.getFirstChild(); c != null; c = c.getNext()) {
     if (!ControlFlowGraph.isEnteringNewCfgNode(c) && mayThrowException(c)) {
       return true;
     }
   }
   return false;
 }
  private HashMap<ControlFlowGraph.Block, Collection<ControlFlowGraph.Block>>
      buildProcedureBlockLists() {
    // maps procedure entry to list blocks in the procedure
    HashMap<ControlFlowGraph.Block, Collection<ControlFlowGraph.Block>> procMap =
        new HashMap<ControlFlowGraph.Block, Collection<ControlFlowGraph.Block>>();

    // create the initial map of entry points to empty lists
    for (ControlFlowGraph.Block entry : ENTRYPOINTS) {
      procMap.put(entry, new LinkedList<ControlFlowGraph.Block>());
    }

    // add each block to the list of its respective procedure
    Iterator<ControlFlowGraph.Block> block_iter = cfg.getBlockIterator();
    while (block_iter.hasNext()) {
      ControlFlowGraph.Block block = block_iter.next();
      Object mark = ENTRYMAP.get(block);
      if (mark == null || !(mark instanceof ControlFlowGraph.Block)) continue;
      ControlFlowGraph.Block entry = (ControlFlowGraph.Block) mark;
      procMap.get(entry).add(block);
    }
    return procMap;
  }