46 import org.graalvm.compiler.nodes.InvokeWithExceptionNode; |
46 import org.graalvm.compiler.nodes.InvokeWithExceptionNode; |
47 import org.graalvm.compiler.nodes.LoopBeginNode; |
47 import org.graalvm.compiler.nodes.LoopBeginNode; |
48 import org.graalvm.compiler.nodes.LoopEndNode; |
48 import org.graalvm.compiler.nodes.LoopEndNode; |
49 import org.graalvm.compiler.nodes.LoopExitNode; |
49 import org.graalvm.compiler.nodes.LoopExitNode; |
50 import org.graalvm.compiler.nodes.PhiNode; |
50 import org.graalvm.compiler.nodes.PhiNode; |
|
51 import org.graalvm.compiler.nodes.ProxyNode; |
51 import org.graalvm.compiler.nodes.ReturnNode; |
52 import org.graalvm.compiler.nodes.ReturnNode; |
52 import org.graalvm.compiler.nodes.StartNode; |
53 import org.graalvm.compiler.nodes.StartNode; |
53 import org.graalvm.compiler.nodes.StructuredGraph; |
54 import org.graalvm.compiler.nodes.StructuredGraph; |
54 import org.graalvm.compiler.nodes.ValueNodeUtil; |
55 import org.graalvm.compiler.nodes.ValueNodeUtil; |
55 import org.graalvm.compiler.nodes.calc.FloatingNode; |
56 import org.graalvm.compiler.nodes.calc.FloatingNode; |
164 return set; |
165 return set; |
165 } |
166 } |
166 |
167 |
167 protected void processNode(FixedNode node, EconomicSet<LocationIdentity> currentState) { |
168 protected void processNode(FixedNode node, EconomicSet<LocationIdentity> currentState) { |
168 if (node instanceof MemoryCheckpoint.Single) { |
169 if (node instanceof MemoryCheckpoint.Single) { |
169 processIdentity(currentState, ((MemoryCheckpoint.Single) node).getLocationIdentity()); |
170 processIdentity(currentState, ((MemoryCheckpoint.Single) node).getKilledLocationIdentity()); |
170 } else if (node instanceof MemoryCheckpoint.Multi) { |
171 } else if (node instanceof MemoryCheckpoint.Multi) { |
171 for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) { |
172 for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getKilledLocationIdentities()) { |
172 processIdentity(currentState, identity); |
173 processIdentity(currentState, identity); |
173 } |
174 } |
174 } |
175 } |
175 } |
176 } |
176 |
177 |
299 this.createMemoryMapNodes = createMemoryMapNodes; |
300 this.createMemoryMapNodes = createMemoryMapNodes; |
300 } |
301 } |
301 |
302 |
302 @Override |
303 @Override |
303 protected MemoryMapImpl processNode(FixedNode node, MemoryMapImpl state) { |
304 protected MemoryMapImpl processNode(FixedNode node, MemoryMapImpl state) { |
|
305 |
|
306 if (node instanceof LoopExitNode) { |
|
307 final LoopExitNode loopExitNode = (LoopExitNode) node; |
|
308 final EconomicSet<LocationIdentity> modifiedInLoop = modifiedInLoops.get(loopExitNode.loopBegin()); |
|
309 final boolean anyModified = modifiedInLoop.contains(LocationIdentity.any()); |
|
310 state.getMap().replaceAll((locationIdentity, memoryNode) -> (anyModified || modifiedInLoop.contains(locationIdentity)) |
|
311 ? ProxyNode.forMemory(memoryNode, loopExitNode, locationIdentity) |
|
312 : memoryNode); |
|
313 } |
|
314 |
304 if (node instanceof MemoryAnchorNode) { |
315 if (node instanceof MemoryAnchorNode) { |
305 processAnchor((MemoryAnchorNode) node, state); |
316 processAnchor((MemoryAnchorNode) node, state); |
306 return state; |
317 return state; |
307 } |
318 } |
308 |
319 |
310 processAccess((MemoryAccess) node, state); |
321 processAccess((MemoryAccess) node, state); |
311 } |
322 } |
312 |
323 |
313 if (createFloatingReads && node instanceof FloatableAccessNode) { |
324 if (createFloatingReads && node instanceof FloatableAccessNode) { |
314 processFloatable((FloatableAccessNode) node, state); |
325 processFloatable((FloatableAccessNode) node, state); |
315 } else if (node instanceof MemoryCheckpoint.Single) { |
326 } |
|
327 if (node instanceof MemoryCheckpoint.Single) { |
316 processCheckpoint((MemoryCheckpoint.Single) node, state); |
328 processCheckpoint((MemoryCheckpoint.Single) node, state); |
317 } else if (node instanceof MemoryCheckpoint.Multi) { |
329 } else if (node instanceof MemoryCheckpoint.Multi) { |
318 processCheckpoint((MemoryCheckpoint.Multi) node, state); |
330 processCheckpoint((MemoryCheckpoint.Multi) node, state); |
319 } |
331 } |
320 assert MemoryCheckpoint.TypeAssertion.correctType(node) : node; |
332 assert MemoryCheckpoint.TypeAssertion.correctType(node) : node; |
321 |
333 |
322 if (createMemoryMapNodes && node instanceof ReturnNode) { |
334 if (createMemoryMapNodes && node instanceof ReturnNode) { |
323 ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapNode(state.lastMemorySnapshot))); |
335 ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapNode(state.getMap()))); |
324 } |
336 } |
325 return state; |
337 return state; |
326 } |
338 } |
327 |
339 |
328 /** |
340 /** |
353 access.setLastLocationAccess(lastLocationAccess); |
365 access.setLastLocationAccess(lastLocationAccess); |
354 } |
366 } |
355 } |
367 } |
356 |
368 |
357 private static void processCheckpoint(MemoryCheckpoint.Single checkpoint, MemoryMapImpl state) { |
369 private static void processCheckpoint(MemoryCheckpoint.Single checkpoint, MemoryMapImpl state) { |
358 processIdentity(checkpoint.getLocationIdentity(), checkpoint, state); |
370 processIdentity(checkpoint.getKilledLocationIdentity(), checkpoint, state); |
359 } |
371 } |
360 |
372 |
361 private static void processCheckpoint(MemoryCheckpoint.Multi checkpoint, MemoryMapImpl state) { |
373 private static void processCheckpoint(MemoryCheckpoint.Multi checkpoint, MemoryMapImpl state) { |
362 for (LocationIdentity identity : checkpoint.getLocationIdentities()) { |
374 for (LocationIdentity identity : checkpoint.getKilledLocationIdentities()) { |
363 processIdentity(identity, checkpoint, state); |
375 processIdentity(identity, checkpoint, state); |
364 } |
376 } |
365 } |
377 } |
366 |
378 |
367 private static void processIdentity(LocationIdentity identity, MemoryCheckpoint checkpoint, MemoryMapImpl state) { |
379 private static void processIdentity(LocationIdentity identity, MemoryCheckpoint checkpoint, MemoryMapImpl state) { |
368 if (identity.isAny()) { |
380 if (identity.isAny()) { |
369 state.lastMemorySnapshot.clear(); |
381 state.getMap().clear(); |
370 } |
382 } |
371 if (identity.isMutable()) { |
383 if (identity.isMutable()) { |
372 state.lastMemorySnapshot.put(identity, checkpoint); |
384 state.getMap().put(identity, checkpoint); |
373 } |
385 } |
374 } |
386 } |
375 |
387 |
376 @SuppressWarnings("try") |
388 @SuppressWarnings("try") |
377 private static void processFloatable(FloatableAccessNode accessNode, MemoryMapImpl state) { |
389 private static void processFloatable(FloatableAccessNode accessNode, MemoryMapImpl state) { |
403 * schedule anything immediately after the invoke. It can only schedule in the |
415 * schedule anything immediately after the invoke. It can only schedule in the |
404 * normal or exceptional successor - and we have to tell the scheduler here which |
416 * normal or exceptional successor - and we have to tell the scheduler here which |
405 * side it needs to choose by putting in the location identity on both successors. |
417 * side it needs to choose by putting in the location identity on both successors. |
406 */ |
418 */ |
407 InvokeWithExceptionNode invoke = (InvokeWithExceptionNode) node.predecessor(); |
419 InvokeWithExceptionNode invoke = (InvokeWithExceptionNode) node.predecessor(); |
408 result.lastMemorySnapshot.put(invoke.getLocationIdentity(), (MemoryCheckpoint) node); |
420 result.getMap().put(invoke.getKilledLocationIdentity(), (MemoryCheckpoint) node); |
409 } |
421 } |
410 return result; |
422 return result; |
411 } |
423 } |
412 |
424 |
413 @Override |
425 @Override |
415 EconomicSet<LocationIdentity> modifiedLocations = modifiedInLoops.get(loop); |
427 EconomicSet<LocationIdentity> modifiedLocations = modifiedInLoops.get(loop); |
416 EconomicMap<LocationIdentity, MemoryPhiNode> phis = EconomicMap.create(Equivalence.DEFAULT); |
428 EconomicMap<LocationIdentity, MemoryPhiNode> phis = EconomicMap.create(Equivalence.DEFAULT); |
417 if (modifiedLocations.contains(LocationIdentity.any())) { |
429 if (modifiedLocations.contains(LocationIdentity.any())) { |
418 // create phis for all locations if ANY is modified in the loop |
430 // create phis for all locations if ANY is modified in the loop |
419 modifiedLocations = EconomicSet.create(Equivalence.DEFAULT, modifiedLocations); |
431 modifiedLocations = EconomicSet.create(Equivalence.DEFAULT, modifiedLocations); |
420 modifiedLocations.addAll(initialState.lastMemorySnapshot.getKeys()); |
432 modifiedLocations.addAll(initialState.getMap().getKeys()); |
421 } |
433 } |
422 |
434 |
423 for (LocationIdentity location : modifiedLocations) { |
435 for (LocationIdentity location : modifiedLocations) { |
424 createMemoryPhi(loop, initialState, phis, location); |
436 createMemoryPhi(loop, initialState, phis, location); |
425 } |
437 } |
426 initialState.lastMemorySnapshot.putAll(phis); |
438 initialState.getMap().putAll(phis); |
427 |
439 |
428 LoopInfo<MemoryMapImpl> loopInfo = ReentrantNodeIterator.processLoop(this, loop, initialState); |
440 LoopInfo<MemoryMapImpl> loopInfo = ReentrantNodeIterator.processLoop(this, loop, initialState); |
429 |
441 |
430 UnmodifiableMapCursor<LoopEndNode, MemoryMapImpl> endStateCursor = loopInfo.endStates.getEntries(); |
442 UnmodifiableMapCursor<LoopEndNode, MemoryMapImpl> endStateCursor = loopInfo.endStates.getEntries(); |
431 while (endStateCursor.advance()) { |
443 while (endStateCursor.advance()) { |