private static Block calcBlockForUsage( Node node, Node usage, Block startBlock, NodeMap<Block> currentNodeMap) { assert !(node instanceof PhiNode); Block currentBlock = startBlock; if (usage instanceof PhiNode) { // An input to a PhiNode is used at the end of the predecessor block that // corresponds to the PhiNode input. One PhiNode can use an input multiple times. PhiNode phi = (PhiNode) usage; AbstractMergeNode merge = phi.merge(); Block mergeBlock = currentNodeMap.get(merge); for (int i = 0; i < phi.valueCount(); ++i) { if (phi.valueAt(i) == node) { Block otherBlock = mergeBlock.getPredecessors()[i]; currentBlock = AbstractControlFlowGraph.commonDominatorTyped(currentBlock, otherBlock); } } } else if (usage instanceof AbstractBeginNode) { AbstractBeginNode abstractBeginNode = (AbstractBeginNode) usage; if (abstractBeginNode instanceof StartNode) { currentBlock = AbstractControlFlowGraph.commonDominatorTyped( currentBlock, currentNodeMap.get(abstractBeginNode)); } else { Block otherBlock = currentNodeMap.get(abstractBeginNode).getDominator(); currentBlock = AbstractControlFlowGraph.commonDominatorTyped(currentBlock, otherBlock); } } else { // All other types of usages: Put the input into the same block as the usage. Block otherBlock = currentNodeMap.get(usage); currentBlock = AbstractControlFlowGraph.commonDominatorTyped(currentBlock, otherBlock); } return currentBlock; }
public void finish(LIRGeneratorTool gen) { Debug.dump(gen.getResult().getLIR(), "Before SSI operands"); AbstractControlFlowGraph<?> cfg = gen.getResult().getLIR().getControlFlowGraph(); for (AbstractBlockBase<?> block : cfg.getBlocks()) { // set label BlockData data = blockData.get(block); if (data != null) { if (data.incoming != null && data.incoming.size() > 0) { LabelOp label = getLabel(gen, block); label.addIncomingValues(data.incoming.toArray(new Value[data.incoming.size()])); } // set block end if (data.outgoing != null && data.outgoing.size() > 0) { BlockEndOp blockEndOp = getBlockEnd(gen, block); blockEndOp.addOutgoingValues(data.outgoing.toArray(new Value[data.outgoing.size()])); } } } }
private static boolean checkLatestEarliestRelation( Node currentNode, Block earliestBlock, Block latestBlock) { assert AbstractControlFlowGraph.dominates(earliestBlock, latestBlock) || (currentNode instanceof VirtualState && latestBlock == earliestBlock.getDominator()) : String.format( "%s %s (%s) %s (%s)", currentNode, earliestBlock, earliestBlock.getBeginNode(), latestBlock, latestBlock.getBeginNode()); return true; }
@Override public void defineOperand(Value operand, AbstractBlockBase<?> block) { assert block != null : "block is null"; if (processValue(operand)) { AbstractBlockBase<?> defBlock = getDefinitionBlock(operand); if (defBlock == null) { setDefinitionBlock(operand, block); } else { /* * Redefinition: this can happen for nodes that do not produce a new value but proxy * another one (PiNode, reinterpret). */ assert AbstractControlFlowGraph.dominates(defBlock, block) : String.format( "Definition of %s in %s does not dominate the redefinition %s", operand, defBlock, block); } } }
@Override public void accessOperand(Value operand, AbstractBlockBase<?> block) { assert block != null : "block is null"; if (operand instanceof CompositeValue) { ((CompositeValue) operand) .forEachComponent( null, OperandMode.USE, (op, value, mode, flag) -> { accessOperand(value, block); return value; }); } else if (processValue(operand)) { AbstractBlockBase<?> defBlock = getDefinitionBlock(operand); assert defBlock != null : "Value is not defined: " + operand; assert AbstractControlFlowGraph.dominates(defBlock, block) : "Block " + defBlock + " does not dominate " + block; accessRecursive(operand, defBlock, block); } }