28 import java.util.NoSuchElementException;
29
30 import org.graalvm.compiler.core.common.type.Stamp;
31 import org.graalvm.compiler.core.common.type.StampFactory;
32 import org.graalvm.compiler.graph.IterableNodeType;
33 import org.graalvm.compiler.graph.Node;
34 import org.graalvm.compiler.graph.NodeClass;
35 import org.graalvm.compiler.graph.iterators.NodeIterable;
36 import org.graalvm.compiler.nodeinfo.InputType;
37 import org.graalvm.compiler.nodeinfo.NodeInfo;
38 import org.graalvm.compiler.nodes.extended.AnchoringNode;
39 import org.graalvm.compiler.nodes.extended.GuardingNode;
40 import org.graalvm.compiler.nodes.spi.LIRLowerable;
41 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
42
43 @NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor})
44 public abstract class AbstractBeginNode extends FixedWithNextNode implements LIRLowerable, GuardingNode, AnchoringNode, IterableNodeType {
45
46 public static final NodeClass<AbstractBeginNode> TYPE = NodeClass.create(AbstractBeginNode.class);
47
48 protected AbstractBeginNode(NodeClass<? extends AbstractBeginNode> c) {
49 this(c, StampFactory.forVoid());
50 }
51
52 protected AbstractBeginNode(NodeClass<? extends AbstractBeginNode> c, Stamp stamp) {
53 super(c, stamp);
54 }
55
56 public static AbstractBeginNode prevBegin(FixedNode from) {
57 Node next = from;
58 while (next != null) {
59 if (next instanceof AbstractBeginNode) {
60 AbstractBeginNode begin = (AbstractBeginNode) next;
61 return begin;
62 }
63 next = next.predecessor();
64 }
65 return null;
66 }
67
74 }
75 }
76 }
77
78 public void prepareDelete() {
79 prepareDelete((FixedNode) predecessor());
80 }
81
82 public void prepareDelete(FixedNode evacuateFrom) {
83 evacuateGuards(evacuateFrom);
84 }
85
86 @Override
87 public boolean verify() {
88 assertTrue(predecessor() != null || this == graph().start() || this instanceof AbstractMergeNode, "begin nodes must be connected");
89 return super.verify();
90 }
91
92 @Override
93 public void generate(NodeLIRBuilderTool gen) {
94 // nop
95 }
96
97 public NodeIterable<GuardNode> guards() {
98 return usages().filter(GuardNode.class);
99 }
100
101 public NodeIterable<Node> anchored() {
102 return usages();
103 }
104
105 public NodeIterable<FixedNode> getBlockNodes() {
106 return new NodeIterable<FixedNode>() {
107
108 @Override
109 public Iterator<FixedNode> iterator() {
110 return new BlockNodeIterator(AbstractBeginNode.this);
111 }
112 };
113 }
114
115 private static class BlockNodeIterator implements Iterator<FixedNode> {
116
117 private FixedNode current;
118
119 BlockNodeIterator(FixedNode next) {
120 this.current = next;
121 }
122
123 @Override
124 public boolean hasNext() {
125 return current != null;
126 }
127
128 @Override
129 public FixedNode next() {
130 FixedNode ret = current;
131 if (ret == null) {
132 throw new NoSuchElementException();
|
28 import java.util.NoSuchElementException;
29
30 import org.graalvm.compiler.core.common.type.Stamp;
31 import org.graalvm.compiler.core.common.type.StampFactory;
32 import org.graalvm.compiler.graph.IterableNodeType;
33 import org.graalvm.compiler.graph.Node;
34 import org.graalvm.compiler.graph.NodeClass;
35 import org.graalvm.compiler.graph.iterators.NodeIterable;
36 import org.graalvm.compiler.nodeinfo.InputType;
37 import org.graalvm.compiler.nodeinfo.NodeInfo;
38 import org.graalvm.compiler.nodes.extended.AnchoringNode;
39 import org.graalvm.compiler.nodes.extended.GuardingNode;
40 import org.graalvm.compiler.nodes.spi.LIRLowerable;
41 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
42
43 @NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor})
44 public abstract class AbstractBeginNode extends FixedWithNextNode implements LIRLowerable, GuardingNode, AnchoringNode, IterableNodeType {
45
46 public static final NodeClass<AbstractBeginNode> TYPE = NodeClass.create(AbstractBeginNode.class);
47
48 private boolean withSpeculationFence;
49
50 protected AbstractBeginNode(NodeClass<? extends AbstractBeginNode> c) {
51 this(c, StampFactory.forVoid());
52 }
53
54 protected AbstractBeginNode(NodeClass<? extends AbstractBeginNode> c, Stamp stamp) {
55 super(c, stamp);
56 }
57
58 public static AbstractBeginNode prevBegin(FixedNode from) {
59 Node next = from;
60 while (next != null) {
61 if (next instanceof AbstractBeginNode) {
62 AbstractBeginNode begin = (AbstractBeginNode) next;
63 return begin;
64 }
65 next = next.predecessor();
66 }
67 return null;
68 }
69
76 }
77 }
78 }
79
80 public void prepareDelete() {
81 prepareDelete((FixedNode) predecessor());
82 }
83
84 public void prepareDelete(FixedNode evacuateFrom) {
85 evacuateGuards(evacuateFrom);
86 }
87
88 @Override
89 public boolean verify() {
90 assertTrue(predecessor() != null || this == graph().start() || this instanceof AbstractMergeNode, "begin nodes must be connected");
91 return super.verify();
92 }
93
94 @Override
95 public void generate(NodeLIRBuilderTool gen) {
96 if (withSpeculationFence) {
97 gen.getLIRGeneratorTool().emitSpeculationFence();
98 }
99 }
100
101 public NodeIterable<GuardNode> guards() {
102 return usages().filter(GuardNode.class);
103 }
104
105 public NodeIterable<Node> anchored() {
106 return usages();
107 }
108
109 public NodeIterable<FixedNode> getBlockNodes() {
110 return new NodeIterable<FixedNode>() {
111
112 @Override
113 public Iterator<FixedNode> iterator() {
114 return new BlockNodeIterator(AbstractBeginNode.this);
115 }
116 };
117 }
118
119 /**
120 * Set this begin node to be a speculation fence. This will prevent speculative execution of
121 * this block.
122 */
123 public void setWithSpeculationFence() {
124 this.withSpeculationFence = true;
125 }
126
127 private static class BlockNodeIterator implements Iterator<FixedNode> {
128
129 private FixedNode current;
130
131 BlockNodeIterator(FixedNode next) {
132 this.current = next;
133 }
134
135 @Override
136 public boolean hasNext() {
137 return current != null;
138 }
139
140 @Override
141 public FixedNode next() {
142 FixedNode ret = current;
143 if (ret == null) {
144 throw new NoSuchElementException();
|