private static void fillKillSet(LocationSet killed, List<Node> subList) { if (!killed.isAny()) { for (Node n : subList) { // Check if this node kills a node in the watch list. if (n instanceof MemoryCheckpoint.Single) { LocationIdentity identity = ((MemoryCheckpoint.Single) n).getLocationIdentity(); killed.add(identity); if (killed.isAny()) { return; } } else if (n instanceof MemoryCheckpoint.Multi) { for (LocationIdentity identity : ((MemoryCheckpoint.Multi) n).getLocationIdentities()) { killed.add(identity); if (killed.isAny()) { return; } } } } } }
@SuppressFBWarnings( value = "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", justification = "false positive found by findbugs") private BlockMap<ArrayList<FloatingReadNode>> calcLatestBlocks( SchedulingStrategy strategy, NodeMap<Block> currentNodeMap, BlockMap<List<Node>> earliestBlockToNodesMap, NodeBitMap visited, BlockMap<List<Node>> latestBlockToNodesMap, boolean immutableGraph) { BlockMap<ArrayList<FloatingReadNode>> watchListMap = new BlockMap<>(cfg); Block[] reversePostOrder = cfg.reversePostOrder(); for (int j = reversePostOrder.length - 1; j >= 0; --j) { Block currentBlock = reversePostOrder[j]; List<Node> blockToNodes = earliestBlockToNodesMap.get(currentBlock); LocationSet killed = null; int previousIndex = blockToNodes.size(); for (int i = blockToNodes.size() - 1; i >= 0; --i) { Node currentNode = blockToNodes.get(i); assert currentNodeMap.get(currentNode) == currentBlock; assert !(currentNode instanceof PhiNode) && !(currentNode instanceof ProxyNode); assert visited.isMarked(currentNode); if (currentNode instanceof FixedNode) { // For these nodes, the earliest is at the same time the latest block. } else { Block latestBlock = null; LocationIdentity constrainingLocation = null; if (currentNode instanceof FloatingReadNode) { // We are scheduling a floating read node => check memory // anti-dependencies. FloatingReadNode floatingReadNode = (FloatingReadNode) currentNode; LocationIdentity location = floatingReadNode.getLocationIdentity(); if (location.isMutable()) { // Location can be killed. constrainingLocation = location; if (currentBlock.canKill(location)) { if (killed == null) { killed = new LocationSet(); } fillKillSet(killed, blockToNodes.subList(i + 1, previousIndex)); previousIndex = i; if (killed.contains(location)) { // Earliest block kills location => we need to stay within // earliest block. latestBlock = currentBlock; } } } } if (latestBlock == null) { // We are not constraint within earliest block => calculate optimized // schedule. calcLatestBlock( currentBlock, strategy, currentNode, currentNodeMap, constrainingLocation, watchListMap, latestBlockToNodesMap, visited, immutableGraph); } else { selectLatestBlock( currentNode, currentBlock, latestBlock, currentNodeMap, watchListMap, constrainingLocation, latestBlockToNodesMap); } } } } return watchListMap; }