# HG changeset patch # User Thomas Wuerthinger # Date 1423770440 -3600 # Node ID 57c53b1044a769bddb45170af0020608910650e8 # Parent fcefaa7f103d0980d5aa75aa4aeceb91ff521b06# Parent 2778032e1beb9282d2bd41297c696e5a143d3dd7 Merge. diff -r 2778032e1beb -r 57c53b1044a7 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Feb 12 10:51:16 2015 -0800 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Feb 12 20:47:20 2015 +0100 @@ -265,6 +265,7 @@ graph.maybeCompress(); SchedulePhase schedule = new SchedulePhase(); + schedule.setScheduleConstants(true); schedule.apply(graph); Debug.dump(schedule, "Final HIR schedule"); return schedule; diff -r 2778032e1beb -r 57c53b1044a7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Feb 12 10:51:16 2015 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Feb 12 20:47:20 2015 +0100 @@ -73,6 +73,19 @@ return false; } }); + r.register2("isInstance", Receiver.class, Object.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode rcvr, ValueNode object) { + if (rcvr.isConstant() && !rcvr.isNullConstant() && object.isConstant()) { + ResolvedJavaType type = builder.getConstantReflection().asJavaType(rcvr.asConstant()); + if (type != null && !type.isPrimitive()) { + builder.push(Kind.Boolean.getStackKind(), builder.append(ConstantNode.forBoolean(type.isInstance(object.asJavaConstant())))); + return true; + } + } + return false; + } + }); + // StableOptionValue.class r = new Registration(plugins, metaAccess, StableOptionValue.class); r.register1("getValue", Receiver.class, new InvocationPlugin() { diff -r 2778032e1beb -r 57c53b1044a7 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Thu Feb 12 10:51:16 2015 -0800 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Thu Feb 12 20:47:20 2015 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; -import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; @@ -306,6 +305,7 @@ private BlockMap> blockToNodesMap; private BlockMap blockToKillSet; private final SchedulingStrategy selectedStrategy; + private boolean scheduleConstants; public SchedulePhase() { this(OptScheduleOutOfLoops.getValue() ? SchedulingStrategy.LATEST_OUT_OF_LOOPS : SchedulingStrategy.LATEST); @@ -315,6 +315,10 @@ this.selectedStrategy = strategy; } + public void setScheduleConstants(boolean value) { + scheduleConstants = value; + } + @Override protected void run(StructuredGraph graph) { assert GraphOrder.assertNonCyclicGraph(graph); @@ -450,6 +454,12 @@ if (cfg.getNodeToBlock().containsKey(node)) { return; } + if (!scheduleConstants && node instanceof ConstantNode) { + return; + } + if (node instanceof VirtualObjectNode) { + return; + } // PhiNodes, ProxyNodes and FixedNodes should already have been placed in blocks by // ControlFlowGraph.identifyBlocks if (node instanceof PhiNode || node instanceof ProxyNode || node instanceof FixedNode) { @@ -473,7 +483,7 @@ assert dominates(earliestBlock, block) : String.format("%s (%s) cannot be scheduled before earliest schedule (%s). location: %s", read, block, earliestBlock, read.getLocationIdentity()); } else { - block = latestBlock(node, strategy); + block = latestBlock(node, strategy, earliestBlock); } if (block == null) { // handle nodes without usages @@ -484,16 +494,7 @@ block = scheduleOutOfLoops(node, block, earliestBlock); } - if (assertionEnabled()) { - if (scheduleRead) { - FloatingReadNode read = (FloatingReadNode) node; - MemoryNode lastLocationAccess = read.getLastLocationAccess(); - Block upperBound = blockForMemoryNode(lastLocationAccess); - assert dominates(upperBound, block) : String.format( - "out of loop movement voilated memory semantics for %s (location %s). moved to %s but upper bound is %s (earliest: %s, latest: %s)", read, - read.getLocationIdentity(), block, upperBound, earliestBlock, latest); - } - } + assert assertReadSchedule(node, earliestBlock, block, latest, scheduleRead); break; default: throw new GraalInternalError("unknown scheduling strategy"); @@ -505,11 +506,15 @@ blockToNodesMap.get(block).add(node); } - @SuppressWarnings("all") - private static boolean assertionEnabled() { - boolean enabled = false; - assert enabled = true; - return enabled; + private boolean assertReadSchedule(ValueNode node, Block earliestBlock, Block block, Block latest, boolean scheduleRead) { + if (scheduleRead) { + FloatingReadNode read = (FloatingReadNode) node; + MemoryNode lastLocationAccess = read.getLastLocationAccess(); + Block upperBound = blockForMemoryNode(lastLocationAccess); + assert dominates(upperBound, block) : String.format("out of loop movement voilated memory semantics for %s (location %s). moved to %s but upper bound is %s (earliest: %s, latest: %s)", + read, read.getLocationIdentity(), block, upperBound, earliestBlock, latest); + } + return true; } /** @@ -540,7 +545,7 @@ Block earliestBlock = earliestBlock(n); assert dominates(upperBoundBlock, earliestBlock) : "upper bound (" + upperBoundBlock + ") should dominate earliest (" + earliestBlock + ")"; - Block latestBlock = latestBlock(n, strategy); + Block latestBlock = latestBlock(n, strategy, earliestBlock); assert latestBlock != null && dominates(earliestBlock, latestBlock) : "earliest (" + earliestBlock + ") should dominate latest block (" + latestBlock + ")"; Debug.log("processing %s (accessing %s): latest %s, earliest %s, upper bound %s (%s)", n, locid, latestBlock, earliestBlock, upperBoundBlock, n.getLastLocationAccess()); @@ -613,26 +618,27 @@ * dominator of all usages. To do so all usages are also assigned to blocks. * * @param strategy + * @param earliestBlock */ - private Block latestBlock(ValueNode node, SchedulingStrategy strategy) { + private Block latestBlock(ValueNode node, SchedulingStrategy strategy, Block earliestBlock) { CommonDominatorBlockClosure cdbc = new CommonDominatorBlockClosure(null); - for (Node succ : node.successors().nonNull()) { - if (cfg.getNodeToBlock().get(succ) == null) { - throw new SchedulingError(); - } - cdbc.apply(cfg.getNodeToBlock().get(succ)); - } ensureScheduledUsages(node, strategy); for (Node usage : node.usages()) { blocksForUsage(node, usage, cdbc, strategy); + if (cdbc.block == earliestBlock) { + break; + } } - if (assertionEnabled()) { - if (cdbc.block != null && !dominates(earliestBlock(node), cdbc.block)) { - throw new SchedulingError("failed to find correct latest schedule for %s. cdbc: %s, earliest: %s", node, cdbc.block, earliestBlock(node)); - } + assert assertLatestBlockResult(node, cdbc); + return cdbc.block; + } + + private boolean assertLatestBlockResult(ValueNode node, CommonDominatorBlockClosure cdbc) throws SchedulingError { + if (cdbc.block != null && !dominates(earliestBlock(node), cdbc.block)) { + throw new SchedulingError("failed to find correct latest schedule for %s. cdbc: %s, earliest: %s", node, cdbc.block, earliestBlock(node)); } - return cdbc.block; + return true; } /** @@ -744,10 +750,8 @@ * @param usage the usage whose blocks need to be considered * @param closure the closure that will be called for each block */ - private void blocksForUsage(ValueNode node, Node usage, BlockClosure closure, SchedulingStrategy strategy) { - if (node instanceof PhiNode) { - throw new SchedulingError(node.toString()); - } + private void blocksForUsage(ValueNode node, Node usage, CommonDominatorBlockClosure closure, SchedulingStrategy strategy) { + assert !(node instanceof PhiNode); if (usage instanceof PhiNode) { // An input to a PhiNode is used at the end of the predecessor block that corresponds to @@ -757,19 +761,8 @@ PhiNode phi = (PhiNode) usage; AbstractMergeNode merge = phi.merge(); Block mergeBlock = cfg.getNodeToBlock().get(merge); - if (mergeBlock == null) { - throw new SchedulingError("no block for merge %s", merge.toString(Verbosity.Id)); - } for (int i = 0; i < phi.valueCount(); ++i) { if (phi.valueAt(i) == node) { - if (mergeBlock.getPredecessorCount() <= i) { - TTY.println(merge.toString()); - TTY.println(phi.toString()); - TTY.println(merge.cfgPredecessors().toString()); - TTY.println(mergeBlock.getPredecessors().toString()); - TTY.println(phi.inputs().toString()); - TTY.println("value count: " + phi.valueCount()); - } closure.apply(mergeBlock.getPredecessors().get(i)); } }