Mercurial > hg > graal-jvmci-8
annotate graal/GraalCompiler/src/com/sun/c1x/ir/Merge.java @ 2827:bd17ac598c6e
Graph cloning, initial version (not completely working)
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Mon, 30 May 2011 18:46:57 +0200 |
parents | 015be60afcf3 |
children | d6f3dbb4e3b5 |
rev | line source |
---|---|
2795 | 1 /* |
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.sun.c1x.ir; | |
24 | |
25 import com.oracle.graal.graph.*; | |
26 import com.sun.c1x.debug.*; | |
27 import com.sun.c1x.util.*; | |
28 import com.sun.c1x.value.*; | |
29 import com.sun.cri.ci.*; | |
30 | |
31 /** | |
32 * Denotes the beginning of a basic block, and holds information | |
33 * about the basic block, including the successor and | |
34 * predecessor blocks, exception handlers, liveness information, etc. | |
35 */ | |
2799
e1dad0edd57a
first part of loop reworking
Lukas Stadler <lukas.stadler@jku.at>
parents:
2795
diff
changeset
|
36 public class Merge extends StateSplit { |
2795 | 37 |
38 private static final int INPUT_COUNT = 0; | |
39 | |
40 private static final int SUCCESSOR_COUNT = 0; | |
41 | |
42 @Override | |
43 protected int inputCount() { | |
44 return super.inputCount() + INPUT_COUNT; | |
45 } | |
46 | |
47 @Override | |
48 protected int successorCount() { | |
49 return super.successorCount() + SUCCESSOR_COUNT; | |
50 } | |
51 | |
52 @Override | |
53 public boolean needsStateAfter() { | |
54 return false; | |
55 } | |
56 | |
57 /** | |
58 * Constructs a new Merge at the specified bytecode index. | |
59 * @param bci the bytecode index of the start | |
60 * @param blockID the ID of the block | |
61 * @param graph | |
62 */ | |
2799
e1dad0edd57a
first part of loop reworking
Lukas Stadler <lukas.stadler@jku.at>
parents:
2795
diff
changeset
|
63 public Merge(Graph graph) { |
2795 | 64 super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); |
65 } | |
66 | |
2799
e1dad0edd57a
first part of loop reworking
Lukas Stadler <lukas.stadler@jku.at>
parents:
2795
diff
changeset
|
67 protected Merge(int inputCount, int successorCount, Graph graph) { |
e1dad0edd57a
first part of loop reworking
Lukas Stadler <lukas.stadler@jku.at>
parents:
2795
diff
changeset
|
68 super(CiKind.Illegal, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); |
2795 | 69 } |
70 | |
71 @Override | |
72 public void accept(ValueVisitor v) { | |
73 v.visitMerge(this); | |
74 } | |
75 | |
76 @Override | |
77 public String toString() { | |
78 StringBuilder builder = new StringBuilder(); | |
79 builder.append("merge #"); | |
80 builder.append(id()); | |
81 builder.append(" ["); | |
82 | |
83 builder.append("]"); | |
2800
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
84 |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
85 builder.append(" -> "); |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
86 boolean hasSucc = false; |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
87 for (Node s : this.successors()) { |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
88 if (hasSucc) { |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
89 builder.append(", "); |
2795 | 90 } |
2800
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
91 builder.append("#"); |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
92 if (s != null) { |
2795 | 93 builder.append(s.id()); |
2800
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
94 } else { |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
95 builder.append("null"); |
2795 | 96 } |
2800
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
97 hasSucc = true; |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
98 } |
e3a0630a1dab
added code for computing dominators.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2795
diff
changeset
|
99 |
2795 | 100 return builder.toString(); |
101 } | |
102 | |
103 public void printWithoutPhis(LogStream out) { | |
104 // print block id | |
105 out.print("B").print(id()).print(" "); | |
106 | |
107 // print flags | |
108 StringBuilder sb = new StringBuilder(8); | |
109 if (sb.length() != 0) { | |
110 out.print('(').print(sb.toString()).print(')'); | |
111 } | |
112 | |
113 // print block bci range | |
114 out.print('[').print(-1).print(", ").print(-1).print(']'); | |
115 | |
116 // print block successors | |
117 //if (end != null && end.blockSuccessors().size() > 0) { | |
118 out.print(" ."); | |
119 for (Node successor : this.successors()) { | |
120 if (successor instanceof Value) { | |
121 out.print((Value) successor); | |
122 } else { | |
123 out.print(successor.toString()); | |
124 } | |
125 } | |
126 //} | |
127 | |
128 // print predecessors | |
2805
c3f64b66fc78
Towards removing the next pointer from Constant and ArithmeticOp
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2804
diff
changeset
|
129 // if (!blockPredecessors().isEmpty()) { |
c3f64b66fc78
Towards removing the next pointer from Constant and ArithmeticOp
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2804
diff
changeset
|
130 // out.print(" pred:"); |
c3f64b66fc78
Towards removing the next pointer from Constant and ArithmeticOp
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2804
diff
changeset
|
131 // for (Instruction pred : blockPredecessors()) { |
c3f64b66fc78
Towards removing the next pointer from Constant and ArithmeticOp
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2804
diff
changeset
|
132 // out.print(pred.block()); |
c3f64b66fc78
Towards removing the next pointer from Constant and ArithmeticOp
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2804
diff
changeset
|
133 // } |
c3f64b66fc78
Towards removing the next pointer from Constant and ArithmeticOp
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2804
diff
changeset
|
134 // } |
2795 | 135 } |
136 | |
137 @Override | |
138 public void print(LogStream out) { | |
139 | |
140 printWithoutPhis(out); | |
141 | |
142 // print phi functions | |
143 boolean hasPhisInLocals = false; | |
144 boolean hasPhisOnStack = false; | |
145 | |
146 //if (end() != null && end().stateAfter() != null) { | |
147 FrameState state = stateBefore(); | |
148 | |
149 int i = 0; | |
150 while (!hasPhisOnStack && i < state.stackSize()) { | |
151 Value value = state.stackAt(i); | |
152 hasPhisOnStack = isPhiAtBlock(value); | |
2821
015be60afcf3
removed flags from Value class
Lukas Stadler <lukas.stadler@jku.at>
parents:
2805
diff
changeset
|
153 if (value != null && !(value instanceof Phi && ((Phi) value).isDead())) { |
2795 | 154 i += value.kind.sizeInSlots(); |
155 } else { | |
156 i++; | |
157 } | |
158 } | |
159 | |
160 for (i = 0; !hasPhisInLocals && i < state.localsSize();) { | |
161 Value value = state.localAt(i); | |
162 hasPhisInLocals = isPhiAtBlock(value); | |
163 // also ignore illegal HiWords | |
2821
015be60afcf3
removed flags from Value class
Lukas Stadler <lukas.stadler@jku.at>
parents:
2805
diff
changeset
|
164 if (value != null && !(value instanceof Phi && ((Phi) value).isDead())) { |
2795 | 165 i += value.kind.sizeInSlots(); |
166 } else { | |
167 i++; | |
168 } | |
169 } | |
170 //} | |
171 | |
172 // print values in locals | |
173 if (hasPhisInLocals) { | |
174 out.println(); | |
175 out.println("Locals:"); | |
176 | |
177 int j = 0; | |
178 while (j < state.localsSize()) { | |
179 Value value = state.localAt(j); | |
180 if (value != null) { | |
181 out.println(stateString(j, value)); | |
182 // also ignore illegal HiWords | |
2821
015be60afcf3
removed flags from Value class
Lukas Stadler <lukas.stadler@jku.at>
parents:
2805
diff
changeset
|
183 if (value instanceof Phi && ((Phi) value).isDead()) { |
015be60afcf3
removed flags from Value class
Lukas Stadler <lukas.stadler@jku.at>
parents:
2805
diff
changeset
|
184 j += 1; |
015be60afcf3
removed flags from Value class
Lukas Stadler <lukas.stadler@jku.at>
parents:
2805
diff
changeset
|
185 } else { |
015be60afcf3
removed flags from Value class
Lukas Stadler <lukas.stadler@jku.at>
parents:
2805
diff
changeset
|
186 j += value.kind.sizeInSlots(); |
015be60afcf3
removed flags from Value class
Lukas Stadler <lukas.stadler@jku.at>
parents:
2805
diff
changeset
|
187 } |
2795 | 188 } else { |
189 j++; | |
190 } | |
191 } | |
192 out.println(); | |
193 } | |
194 | |
195 // print values on stack | |
196 if (hasPhisOnStack) { | |
197 out.println(); | |
198 out.println("Stack:"); | |
199 int j = 0; | |
200 while (j < stateBefore().stackSize()) { | |
201 Value value = stateBefore().stackAt(j); | |
202 if (value != null) { | |
203 out.println(stateString(j, value)); | |
204 j += value.kind.sizeInSlots(); | |
205 } else { | |
206 j++; | |
207 } | |
208 } | |
209 } | |
210 | |
211 } | |
212 | |
213 /** | |
214 * Determines if a given instruction is a phi whose {@linkplain Phi#block() join block} is a given block. | |
215 * | |
216 * @param value the instruction to test | |
217 * @param block the block that may be the join block of {@code value} if {@code value} is a phi | |
218 * @return {@code true} if {@code value} is a phi and its join block is {@code block} | |
219 */ | |
220 private boolean isPhiAtBlock(Value value) { | |
221 return value instanceof Phi && ((Phi) value).block() == this; | |
222 } | |
223 | |
224 | |
225 /** | |
226 * Formats a given instruction as a value in a {@linkplain FrameState frame state}. If the instruction is a phi defined at a given | |
227 * block, its {@linkplain Phi#valueCount() inputs} are appended to the returned string. | |
228 * | |
229 * @param index the index of the value in the frame state | |
230 * @param value the frame state value | |
231 * @param block if {@code value} is a phi, then its inputs are formatted if {@code block} is its | |
232 * {@linkplain Phi#block() join point} | |
233 * @return the instruction representation as a string | |
234 */ | |
235 public String stateString(int index, Value value) { | |
236 StringBuilder sb = new StringBuilder(30); | |
237 sb.append(String.format("%2d %s", index, Util.valueString(value))); | |
238 if (value instanceof Phi) { | |
239 Phi phi = (Phi) value; | |
240 // print phi operands | |
241 if (phi.block() == this) { | |
242 sb.append(" ["); | |
243 for (int j = 0; j < phi.valueCount(); j++) { | |
244 sb.append(' '); | |
245 Value operand = phi.valueAt(j); | |
246 if (operand != null) { | |
247 sb.append(Util.valueString(operand)); | |
248 } else { | |
249 sb.append("NULL"); | |
250 } | |
251 } | |
252 sb.append("] "); | |
253 } | |
254 } | |
255 return sb.toString(); | |
256 } | |
2827
bd17ac598c6e
Graph cloning, initial version (not completely working)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2821
diff
changeset
|
257 |
bd17ac598c6e
Graph cloning, initial version (not completely working)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2821
diff
changeset
|
258 @Override |
bd17ac598c6e
Graph cloning, initial version (not completely working)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2821
diff
changeset
|
259 public Node copy(Graph into) { |
bd17ac598c6e
Graph cloning, initial version (not completely working)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2821
diff
changeset
|
260 assert getClass() == Merge.class : "copy of " + getClass(); |
bd17ac598c6e
Graph cloning, initial version (not completely working)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2821
diff
changeset
|
261 Merge x = new Merge(into); |
bd17ac598c6e
Graph cloning, initial version (not completely working)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2821
diff
changeset
|
262 x.setNonNull(isNonNull()); |
bd17ac598c6e
Graph cloning, initial version (not completely working)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2821
diff
changeset
|
263 return x; |
bd17ac598c6e
Graph cloning, initial version (not completely working)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2821
diff
changeset
|
264 } |
2795 | 265 } |