# HG changeset patch # User Doug Simon # Date 1402419140 -7200 # Node ID b38191cd1665f3ede3bb101f277c5c50a78c88df # Parent 2023d61204169cea67c0906757ec6965ab0342b5 removed code to make recording usages optional for ConstantNodes (GRAAL-508) diff -r 2023d6120416 -r b38191cd1665 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSensitiveReductionTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSensitiveReductionTest.java Tue Jun 10 18:50:26 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSensitiveReductionTest.java Tue Jun 10 18:52:20 2014 +0200 @@ -148,9 +148,7 @@ new FlowSensitiveReductionPhase(getMetaAccess()).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); for (ConstantNode constant : getConstantNodes(graph)) { - if (ConstantNodeRecordsUsages || !constant.gatherUsages(graph).isEmpty()) { - assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); - } + assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } } @@ -186,9 +184,7 @@ new FlowSensitiveReductionPhase(getMetaAccess()).apply(graph, new PhaseContext(getProviders(), null)); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); for (ConstantNode constant : getConstantNodes(graph)) { - if (ConstantNodeRecordsUsages || !constant.gatherUsages(graph).isEmpty()) { - assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); - } + assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } } diff -r 2023d6120416 -r b38191cd1665 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Jun 10 18:50:26 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Jun 10 18:52:20 2014 +0200 @@ -213,14 +213,8 @@ protected int countUnusedConstants(StructuredGraph graph) { int total = 0; for (ConstantNode node : getConstantNodes(graph)) { - if (!ConstantNodeRecordsUsages) { - if (node.gatherUsages(graph).isEmpty()) { - total++; - } - } else { - if (node.usages().isEmpty()) { - total++; - } + if (node.usages().isEmpty()) { + total++; } } return total; diff -r 2023d6120416 -r b38191cd1665 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Tue Jun 10 18:50:26 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Tue Jun 10 18:52:20 2014 +0200 @@ -26,7 +26,6 @@ import static com.oracle.graal.compiler.GraalDebugConfig.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.lir.LIR.*; -import static com.oracle.graal.nodes.ConstantNode.*; import java.util.*; import java.util.Map.Entry; @@ -44,7 +43,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.gen.*; -import com.oracle.graal.lir.gen.LIRGenerator.LoadConstant; import com.oracle.graal.lir.gen.LIRGenerator.Options; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -135,48 +133,7 @@ if (nodeOperands == null) { return null; } - Value operand = nodeOperands.get(node); - if (operand == null) { - operand = getConstantOperand(node); - } - return operand; - } - - private Value getConstantOperand(ValueNode node) { - if (!ConstantNodeRecordsUsages) { - Constant value = node.asConstant(); - if (value != null) { - if (gen.canInlineConstant(value)) { - return setResult(node, value); - } else { - Variable loadedValue; - if (gen.getConstantLoads() == null) { - gen.setConstantLoads(new HashMap<>()); - } - LoadConstant load = gen.getConstantLoads().get(value); - assert gen.getCurrentBlock() instanceof Block; - if (load == null) { - int index = gen.getResult().getLIR().getLIRforBlock(gen.getCurrentBlock()).size(); - loadedValue = gen.emitMove(value); - LIRInstruction op = gen.getResult().getLIR().getLIRforBlock(gen.getCurrentBlock()).get(index); - gen.getConstantLoads().put(value, new LoadConstant(loadedValue, gen.getCurrentBlock(), index, op)); - } else { - AbstractBlock dominator = ControlFlowGraph.commonDominator((Block) load.getBlock(), (Block) gen.getCurrentBlock()); - loadedValue = load.getVariable(); - if (dominator != load.getBlock()) { - load.unpin(gen.getResult().getLIR()); - } else { - assert load.getBlock() != gen.getCurrentBlock() || load.getIndex() < gen.getResult().getLIR().getLIRforBlock(gen.getCurrentBlock()).size(); - } - load.setBlock(dominator); - } - return loadedValue; - } - } - } else { - // Constant is loaded by ConstantNode.generate() - } - return null; + return nodeOperands.get(node); } public ValueNode valueForOperand(Value value) { @@ -252,10 +209,7 @@ if (Options.TraceLIRGeneratorLevel.getValue() >= 3) { TTY.println("LIRGen for " + instr); } - if (!ConstantNodeRecordsUsages && instr instanceof ConstantNode) { - // Loading of constants is done lazily by operand() - - } else if (instr instanceof ValueNode) { + if (instr instanceof ValueNode) { ValueNode valueNode = (ValueNode) instr; Value operand = getOperand(valueNode); if (operand == null) { diff -r 2023d6120416 -r b38191cd1665 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Tue Jun 10 18:50:26 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Tue Jun 10 18:52:20 2014 +0200 @@ -45,7 +45,7 @@ @Override protected boolean verify(StructuredGraph graph, PhaseContext context) { for (ConstantNode node : getConstantNodes(graph)) { - if (node.recordsUsages() || !node.gatherUsages(graph).isEmpty()) { + if (node.recordsUsages()) { if (isObject(node) && !isNullReference(node) && !isInternedString(node) && !isDirectMethodHandle(node) && !isBoundMethodHandle(node)) { throw new VerificationError("illegal object constant: " + node); } diff -r 2023d6120416 -r b38191cd1665 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Tue Jun 10 18:50:26 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Tue Jun 10 18:52:20 2014 +0200 @@ -24,8 +24,6 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.api.meta.Value.*; -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.lir.LIR.*; import static com.oracle.graal.lir.LIRValueUtil.*; import java.util.*; @@ -42,7 +40,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.BlockEndOp; import com.oracle.graal.lir.StandardOp.LabelOp; -import com.oracle.graal.lir.StandardOp.NoOp; import com.oracle.graal.options.*; /** @@ -64,97 +61,6 @@ private AbstractBlock currentBlock; - /** - * Handle for an operation that loads a constant into a variable. The operation starts in the - * first block where the constant is used but will eventually be - * {@linkplain LIRGenerator#insertConstantLoads() moved} to a block dominating all usages of the - * constant. - */ - public static class LoadConstant implements Comparable { - /** - * The index of {@link #op} within {@link #block}'s instruction list or -1 if {@code op} is - * to be moved to a dominator block. - */ - int index; - - /** - * The operation that loads the constant. - */ - private final LIRInstruction op; - - /** - * The block that does or will contain {@link #op}. This is initially the block where the - * first usage of the constant is seen during LIR generation. - */ - AbstractBlock block; - - /** - * The variable into which the constant is loaded. - */ - final Variable variable; - - public LoadConstant(Variable variable, AbstractBlock block, int index, LIRInstruction op) { - this.variable = variable; - this.block = block; - this.index = index; - this.op = op; - } - - /** - * Sorts {@link LoadConstant} objects according to their enclosing blocks. This is used to - * group loads per block in {@link LIRGenerator#insertConstantLoads()}. - */ - public int compareTo(LoadConstant o) { - if (block.getId() < o.block.getId()) { - return -1; - } - if (block.getId() > o.block.getId()) { - return 1; - } - return 0; - } - - @Override - public String toString() { - return block + "#" + op; - } - - /** - * Removes the {@link #op} from its original location if it is still at that location. - */ - public void unpin(LIR lir) { - if (index >= 0) { - // Replace the move with a filler op so that the operation - // list does not need to be adjusted. - List instructions = lir.getLIRforBlock(block); - instructions.set(index, new NoOp(null, -1)); - index = -1; - } - } - - public AbstractBlock getBlock() { - return block; - } - - public void setBlock(AbstractBlock block) { - this.block = block; - } - - public Variable getVariable() { - return variable; - } - - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - } - - private Map constantLoads; - private LIRGenerationResult res; public LIRGenerator(CodeGenProviders providers, CallingConvention cc, LIRGenerationResult res) { @@ -409,83 +315,6 @@ @Override public void beforeRegisterAllocation() { - insertConstantLoads(); - } - - /** - * Moves deferred {@linkplain LoadConstant loads} of constants into blocks dominating all usages - * of the constant. Any operations inserted into a block are guaranteed to be immediately prior - * to the first control flow instruction near the end of the block. - */ - private void insertConstantLoads() { - if (constantLoads != null) { - // Remove loads where all usages are in the same block. - for (Iterator> iter = constantLoads.entrySet().iterator(); iter.hasNext();) { - LoadConstant lc = iter.next().getValue(); - - // Move loads of constant outside of loops - if (OptScheduleOutOfLoops.getValue()) { - AbstractBlock outOfLoopDominator = lc.block; - while (outOfLoopDominator.getLoop() != null) { - outOfLoopDominator = outOfLoopDominator.getDominator(); - } - if (outOfLoopDominator != lc.block) { - lc.unpin(res.getLIR()); - lc.block = outOfLoopDominator; - } - } - - if (lc.index != -1) { - assert res.getLIR().getLIRforBlock(lc.block).get(lc.index) == lc.op; - iter.remove(); - } - } - if (constantLoads.isEmpty()) { - return; - } - - // Sorting groups the loads per block. - LoadConstant[] groupedByBlock = constantLoads.values().toArray(new LoadConstant[constantLoads.size()]); - Arrays.sort(groupedByBlock); - - int groupBegin = 0; - while (true) { - int groupEnd = groupBegin + 1; - AbstractBlock block = groupedByBlock[groupBegin].block; - while (groupEnd < groupedByBlock.length && groupedByBlock[groupEnd].block == block) { - groupEnd++; - } - int groupSize = groupEnd - groupBegin; - - List ops = res.getLIR().getLIRforBlock(block); - int lastIndex = ops.size() - 1; - assert ops.get(lastIndex) instanceof BlockEndOp; - int insertionIndex = lastIndex; - for (int i = Math.max(0, lastIndex - MAX_EXCEPTION_EDGE_OP_DISTANCE_FROM_END); i < lastIndex; i++) { - if (getExceptionEdge(ops.get(i)) != null) { - insertionIndex = i; - break; - } - } - - if (groupSize == 1) { - ops.add(insertionIndex, groupedByBlock[groupBegin].op); - } else { - assert groupSize > 1; - List moves = new ArrayList<>(groupSize); - for (int i = groupBegin; i < groupEnd; i++) { - moves.add(groupedByBlock[i].op); - } - ops.addAll(insertionIndex, moves); - } - - if (groupEnd == groupedByBlock.length) { - break; - } - groupBegin = groupEnd; - } - constantLoads = null; - } } /** @@ -573,12 +402,4 @@ public LIRGenerationResult getResult() { return res; } - - public Map getConstantLoads() { - return constantLoads; - } - - public void setConstantLoads(Map constantLoads) { - this.constantLoads = constantLoads; - } } diff -r 2023d6120416 -r b38191cd1665 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Tue Jun 10 18:50:26 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Tue Jun 10 18:52:20 2014 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.lir.gen; -import java.util.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; @@ -31,7 +29,6 @@ import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.compiler.common.spi.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.gen.LIRGenerator.*; public interface LIRGeneratorTool extends ArithmeticLIRGenerator { @@ -55,10 +52,6 @@ void doBlockEnd(AbstractBlock block); - Map getConstantLoads(); - - void setConstantLoads(Map constantLoads); - Value emitLoad(PlatformKind kind, Value address, LIRFrameState state); void emitStore(PlatformKind kind, Value address, Value input, LIRFrameState state); diff -r 2023d6120416 -r b38191cd1665 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Tue Jun 10 18:50:26 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Tue Jun 10 18:52:20 2014 +0200 @@ -67,32 +67,9 @@ return value; } - /** - * Used to measure the impact of ConstantNodes not recording their usages. This and all code - * predicated on this value being true will be removed at some point. - */ - public static final boolean ConstantNodeRecordsUsages = Boolean.parseBoolean(System.getProperty("graal.constantNodeRecordsUsages", "true")); - @Override public boolean recordsUsages() { - return ConstantNodeRecordsUsages; - } - - /** - * Computes the usages of this node by iterating over all the nodes in the graph, searching for - * those that have this node as an input. - */ - public List gatherUsages(StructuredGraph graph) { - assert !ConstantNodeRecordsUsages; - List usages = new ArrayList<>(); - for (Node node : graph.getNodes()) { - for (Node input : node.inputs()) { - if (input == this) { - usages.add(node); - } - } - } - return usages; + return true; } /** @@ -104,25 +81,15 @@ } /** - * Replaces this node at its usages with another node. If {@link #ConstantNodeRecordsUsages} is - * false, this is an expensive operation that should only be used in test/verification/AOT code. + * Replaces this node at its usages with another node. */ public void replace(StructuredGraph graph, Node replacement) { - if (!recordsUsages()) { - List usages = gatherUsages(graph); - for (Node usage : usages) { - usage.replaceFirstInput(this, replacement); - } - graph.removeFloating(this); - } else { - assert graph == graph(); - graph().replaceFloating(this, replacement); - } + assert graph == graph(); + graph().replaceFloating(this, replacement); } @Override public void generate(NodeLIRBuilderTool gen) { - assert ConstantNodeRecordsUsages : "LIR generator should generate constants per-usage"; if (gen.getLIRGeneratorTool().canInlineConstant(value) || onlyUsedInVirtualState()) { gen.setResult(this, value); } else {