use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.
the class PartialEscapeClosure method stripKilledLoopLocations.
@Override
protected BlockT stripKilledLoopLocations(Loop<Block> loop, BlockT originalInitialState) {
BlockT initialState = super.stripKilledLoopLocations(loop, originalInitialState);
if (loop.getDepth() > GraalOptions.EscapeAnalysisLoopCutoff.getValue(cfg.graph.getOptions())) {
/*
* After we've reached the maximum loop nesting, we'll simply materialize everything we
* can to make sure that the loops only need to be iterated one time. Care is taken here
* to not materialize virtual objects that have the "ensureVirtualized" flag set.
*/
LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
AbstractEndNode end = loopBegin.forwardEnd();
Block loopPredecessor = loop.getHeader().getFirstPredecessor();
assert loopPredecessor.getEndNode() == end;
int length = initialState.getStateCount();
boolean change;
BitSet ensureVirtualized = new BitSet(length);
for (int i = 0; i < length; i++) {
ObjectState state = initialState.getObjectStateOptional(i);
if (state != null && state.isVirtual() && state.getEnsureVirtualized()) {
ensureVirtualized.set(i);
}
}
do {
// propagate "ensureVirtualized" flag
change = false;
for (int i = 0; i < length; i++) {
if (!ensureVirtualized.get(i)) {
ObjectState state = initialState.getObjectStateOptional(i);
if (state != null && state.isVirtual()) {
for (ValueNode entry : state.getEntries()) {
if (entry instanceof VirtualObjectNode) {
if (ensureVirtualized.get(((VirtualObjectNode) entry).getObjectId())) {
change = true;
ensureVirtualized.set(i);
break;
}
}
}
}
}
}
} while (change);
for (int i = 0; i < length; i++) {
ObjectState state = initialState.getObjectStateOptional(i);
if (state != null && state.isVirtual() && !ensureVirtualized.get(i)) {
initialState.materializeBefore(end, virtualObjects.get(i), blockEffects.get(loopPredecessor));
}
}
}
return initialState;
}
use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.
the class EffectsClosure method applyEffects.
@Override
public void applyEffects() {
final StructuredGraph graph = cfg.graph;
final ArrayList<Node> obsoleteNodes = new ArrayList<>(0);
final ArrayList<GraphEffectList> effectList = new ArrayList<>();
/*
* Effects are applied during a ordered iteration over the blocks to apply them in the
* correct order, e.g., apply the effect that adds a node to the graph before the node is
* used.
*/
BlockIteratorClosure<Void> closure = new BlockIteratorClosure<Void>() {
@Override
protected Void getInitialState() {
return null;
}
private void apply(GraphEffectList effects) {
if (effects != null && !effects.isEmpty()) {
effectList.add(effects);
}
}
@Override
protected Void processBlock(Block block, Void currentState) {
apply(blockEffects.get(block));
return currentState;
}
@Override
protected Void merge(Block merge, List<Void> states) {
return null;
}
@Override
protected Void cloneState(Void oldState) {
return oldState;
}
@Override
protected List<Void> processLoop(Loop<Block> loop, Void initialState) {
LoopInfo<Void> info = ReentrantBlockIterator.processLoop(this, loop, initialState);
apply(loopMergeEffects.get(loop));
return info.exitStates;
}
};
ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
for (GraphEffectList effects : effectList) {
effects.apply(graph, obsoleteNodes, false);
}
/*
* Effects that modify the cfg (e.g., removing a branch for an if that got a constant
* condition) need to be performed after all other effects, because they change phi value
* indexes.
*/
for (GraphEffectList effects : effectList) {
effects.apply(graph, obsoleteNodes, true);
}
debug.dump(DebugContext.DETAILED_LEVEL, graph, "After applying effects");
assert VirtualUtil.assertNonReachable(graph, obsoleteNodes);
for (Node node : obsoleteNodes) {
if (node.isAlive() && node.hasNoUsages()) {
if (node instanceof FixedWithNextNode) {
assert ((FixedWithNextNode) node).next() == null;
}
node.replaceAtUsages(null);
GraphUtil.killWithUnusedFloatingInputs(node);
}
}
}
use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.
the class LoopFragment method toHirExits.
public static NodeIterable<AbstractBeginNode> toHirExits(final Iterable<Block> blocks) {
return new NodeIterable<AbstractBeginNode>() {
@Override
public Iterator<AbstractBeginNode> iterator() {
final Iterator<Block> it = blocks.iterator();
return new Iterator<AbstractBeginNode>() {
@Override
public void remove() {
throw new UnsupportedOperationException();
}
/**
* Return the true LoopExitNode for this loop or the BeginNode for the block.
*/
@Override
public AbstractBeginNode next() {
Block next = it.next();
LoopExitNode exit = next.getLoopExit();
if (exit != null) {
return exit;
}
return next.getBeginNode();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
};
}
};
}
use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.
the class ReplaceConstantNodesPhase method findFixedWithValidState.
/**
* Find first dominating {@link FixedWithNextNode} that has a valid state reaching it starting
* from the given node.
*
* @param graph
* @param stateMapper
* @param node
* @return {@link FixedWithNextNode} that we can use as an insertion point
*/
private static FixedWithNextNode findFixedWithValidState(StructuredGraph graph, FrameStateMapperClosure stateMapper, FixedWithNextNode node) {
ScheduleResult schedule = graph.getLastSchedule();
NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
Block block = nodeToBlock.get(node);
Node n = node;
do {
if (isFixedWithValidState(stateMapper, n)) {
return (FixedWithNextNode) n;
}
while (n != block.getBeginNode()) {
n = n.predecessor();
if (isFixedWithValidState(stateMapper, n)) {
return (FixedWithNextNode) n;
}
}
block = block.getDominator();
if (block != null) {
n = block.getEndNode();
}
} while (block != null);
return graph.start();
}
use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.
the class ReplaceConstantNodesPhase method tryToReplaceWithExisting.
/**
* Try to find dominating node doing the resolution that can be reused.
*
* @param graph
* @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs
* resolution.
*/
private static void tryToReplaceWithExisting(StructuredGraph graph, ConstantNode node) {
ScheduleResult schedule = graph.getLastSchedule();
NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap();
EconomicMap<Block, Node> blockToExisting = EconomicMap.create();
for (Node n : node.usages().filter(n -> isReplacementNode(n))) {
blockToExisting.put(nodeToBlock.get(n), n);
}
for (Node use : node.usages().filter(n -> !isReplacementNode(n)).snapshot()) {
boolean replaced = false;
Block b = nodeToBlock.get(use);
Node e = blockToExisting.get(b);
if (e != null) {
// the use is scheduled after it.
for (Node n : blockToNodes.get(b)) {
if (n.equals(use)) {
// Usage is before initialization, can't use it
break;
}
if (n.equals(e)) {
use.replaceFirstInput(node, e);
replaced = true;
break;
}
}
}
if (!replaced) {
// Look for dominating blocks that have existing nodes
for (Block d : blockToExisting.getKeys()) {
if (strictlyDominates(d, b)) {
use.replaceFirstInput(node, blockToExisting.get(d));
break;
}
}
}
}
}
Aggregations