comparison graal/GraalCompiler/src/com/sun/c1x/lir/LIRList.java @ 2509:16b9a8b5ad39

Renamings Runtime=>GraalRuntime and Compiler=>GraalCompiler
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 27 Apr 2011 11:50:44 +0200
parents graal/Compiler/src/com/sun/c1x/lir/LIRList.java@9ec15d6914ca
children a384fac3fd34
comparison
equal deleted inserted replaced
2508:fea94949e0a2 2509:16b9a8b5ad39
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.lir;
24
25 import java.util.*;
26
27 import com.sun.c1x.*;
28 import com.sun.c1x.alloc.*;
29 import com.sun.c1x.asm.*;
30 import com.sun.c1x.debug.*;
31 import com.sun.c1x.gen.*;
32 import com.sun.c1x.globalstub.*;
33 import com.sun.c1x.ir.*;
34 import com.sun.c1x.lir.FrameMap.StackBlock;
35 import com.sun.cri.ci.*;
36 import com.sun.cri.ci.CiTargetMethod.Mark;
37 import com.sun.cri.ri.*;
38 import com.sun.cri.xir.CiXirAssembler.XirMark;
39 import com.sun.cri.xir.*;
40
41 /**
42 * This class represents a list of LIR instructions and contains factory methods for creating and appending LIR
43 * instructions to this list.
44 *
45 * @author Marcelo Cintra
46 * @author Thomas Wuerthinger
47 * @author Ben L. Titzer
48 */
49 public final class LIRList {
50
51 private List<LIRInstruction> operations;
52 private final LIRGenerator generator;
53
54 private final LIROpcode runtimeCallOp;
55
56 private LIROpcode directCallOp(RiMethod method) {
57 return C1XOptions.UseConstDirectCall && method.hasCompiledCode() ? LIROpcode.ConstDirectCall : LIROpcode.DirectCall;
58 }
59
60 public LIRList(LIRGenerator generator) {
61 this.generator = generator;
62 this.operations = new ArrayList<LIRInstruction>(8);
63 runtimeCallOp = C1XOptions.UseConstDirectCall ? LIROpcode.ConstDirectCall : LIROpcode.DirectCall;
64 }
65
66 private void append(LIRInstruction op) {
67 if (C1XOptions.PrintIRWithLIR && !TTY.isSuppressed()) {
68 generator.maybePrintCurrentInstruction();
69 TTY.println(op.toStringWithIdPrefix());
70 TTY.println();
71 }
72 operations.add(op);
73 assert op.verify();
74 }
75
76 public List<LIRInstruction> instructionsList() {
77 return operations;
78 }
79
80 public int length() {
81 return operations.size();
82 }
83
84 public LIRInstruction at(int i) {
85 return operations.get(i);
86 }
87
88 public void callDirect(RiMethod method, CiValue result, List<CiValue> arguments, LIRDebugInfo info, Map<XirMark, Mark> marks, List<CiValue> pointerSlots) {
89 append(new LIRCall(directCallOp(method), method, result, arguments, info, marks, false, pointerSlots));
90 }
91
92 public void callIndirect(RiMethod method, CiValue result, List<CiValue> arguments, LIRDebugInfo info, Map<XirMark, Mark> marks, List<CiValue> pointerSlots) {
93 append(new LIRCall(LIROpcode.IndirectCall, method, result, arguments, info, marks, false, pointerSlots));
94 }
95
96 public void callNative(String symbol, CiValue result, List<CiValue> arguments, LIRDebugInfo info, Map<XirMark, Mark> marks) {
97 append(new LIRCall(LIROpcode.NativeCall, symbol, result, arguments, info, marks, false, null));
98 }
99
100 public void templateCall(CiValue result, List<CiValue> arguments) {
101 append(new LIRCall(LIROpcode.TemplateCall, null, result, arguments, null, null, false, null));
102 }
103
104 public void membar(int barriers) {
105 append(new LIRMemoryBarrier(barriers));
106 }
107
108 public void osrEntry(CiValue osrPointer) {
109 append(new LIROp0(LIROpcode.OsrEntry, osrPointer));
110 }
111
112 public void branchDestination(Label lbl) {
113 append(new LIRLabel(lbl));
114 }
115
116 public void negate(CiValue src, CiValue dst, GlobalStub globalStub) {
117 LIRNegate op = new LIRNegate(src, dst);
118 op.globalStub = globalStub;
119 append(op);
120 }
121
122 public void lea(CiValue src, CiValue dst) {
123 append(new LIROp1(LIROpcode.Lea, src, dst));
124 }
125
126 public void unalignedMove(CiValue src, CiValue dst) {
127 append(new LIROp1(LIROp1.LIRMoveKind.Unaligned, src, dst, dst.kind, null));
128 }
129
130 public void move(CiAddress src, CiValue dst, LIRDebugInfo info) {
131 append(new LIROp1(LIROpcode.Move, src, dst, src.kind, info));
132 }
133
134 public void move(CiValue src, CiAddress dst, LIRDebugInfo info) {
135 append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, info));
136 }
137
138 public void move(CiValue src, CiValue dst, CiKind kind) {
139 append(new LIROp1(LIROpcode.Move, src, dst, kind, null));
140 }
141
142 public void move(CiValue src, CiValue dst) {
143 append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, null));
144 }
145
146 public void volatileMove(CiValue src, CiValue dst, CiKind kind, LIRDebugInfo info) {
147 append(new LIROp1(LIROp1.LIRMoveKind.Volatile, src, dst, kind, info));
148 }
149
150 public void oop2reg(Object o, CiValue reg) {
151 append(new LIROp1(LIROpcode.Move, CiConstant.forObject(o), reg));
152 }
153
154 public void returnOp(CiValue result) {
155 append(new LIROp1(LIROpcode.Return, result));
156 }
157
158 public void monitorAddress(int monitor, CiValue dst) {
159 append(new LIRMonitorAddress(dst, monitor));
160 }
161
162 public void infopoint(LIROpcode opcode, CiValue dst, LIRDebugInfo info) {
163 append(new LIROp0(opcode, dst, info));
164 }
165
166 public void alloca(StackBlock stackBlock, CiValue dst) {
167 append(new LIRStackAllocate(dst, stackBlock));
168 }
169
170 public void convert(int code, CiValue left, CiValue dst, GlobalStub globalStub) {
171 LIRConvert op = new LIRConvert(code, left, dst);
172 op.globalStub = globalStub;
173 append(op);
174 }
175
176 public void logicalAnd(CiValue left, CiValue right, CiValue dst) {
177 append(new LIROp2(LIROpcode.LogicAnd, left, right, dst));
178 }
179
180 public void logicalOr(CiValue left, CiValue right, CiValue dst) {
181 append(new LIROp2(LIROpcode.LogicOr, left, right, dst));
182 }
183
184 public void logicalXor(CiValue left, CiValue right, CiValue dst) {
185 append(new LIROp2(LIROpcode.LogicXor, left, right, dst));
186 }
187
188 public void nullCheck(CiValue opr, LIRDebugInfo info) {
189 append(new LIROp1(LIROpcode.NullCheck, opr, info));
190 }
191
192 public void throwException(CiValue exceptionPC, CiValue exceptionOop, LIRDebugInfo info) {
193 append(new LIROp2(LIROpcode.Throw, exceptionPC, exceptionOop, CiValue.IllegalValue, info, CiKind.Illegal, true));
194 }
195
196 public void unwindException(CiValue exceptionPC, CiValue exceptionOop, LIRDebugInfo info) {
197 append(new LIROp2(LIROpcode.Unwind, exceptionPC, exceptionOop, CiValue.IllegalValue, info));
198 }
199
200 public void compareTo(CiValue left, CiValue right, CiValue dst) {
201 append(new LIROp2(LIROpcode.CompareTo, left, right, dst));
202 }
203
204 public void cmp(Condition condition, CiValue left, CiValue right, LIRDebugInfo info) {
205 append(new LIROp2(LIROpcode.Cmp, condition, left, right, info));
206 }
207
208 public void cmp(Condition condition, CiValue left, CiValue right) {
209 cmp(condition, left, right, null);
210 }
211
212 public void cmp(Condition condition, CiValue left, int right, LIRDebugInfo info) {
213 cmp(condition, left, CiConstant.forInt(right), info);
214 }
215
216 public void cmp(Condition condition, CiValue left, int right) {
217 cmp(condition, left, right, null);
218 }
219
220 public void cmove(Condition condition, CiValue src1, CiValue src2, CiValue dst) {
221 append(new LIROp2(LIROpcode.Cmove, condition, src1, src2, dst));
222 }
223
224 public void abs(CiValue from, CiValue to, CiValue tmp) {
225 append(new LIROp2(LIROpcode.Abs, from, tmp, to));
226 }
227
228 public void sqrt(CiValue from, CiValue to, CiValue tmp) {
229 append(new LIROp2(LIROpcode.Sqrt, from, tmp, to));
230 }
231
232 public void log(CiValue from, CiValue to, CiValue tmp) {
233 append(new LIROp2(LIROpcode.Log, from, tmp, to));
234 }
235
236 public void log10(CiValue from, CiValue to, CiValue tmp) {
237 append(new LIROp2(LIROpcode.Log10, from, tmp, to));
238 }
239
240 public void sin(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) {
241 append(new LIROp2(LIROpcode.Sin, from, tmp1, to, tmp2));
242 }
243
244 public void cos(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) {
245 append(new LIROp2(LIROpcode.Cos, from, tmp1, to, tmp2));
246 }
247
248 public void tan(CiValue from, CiValue to, CiValue tmp1, CiValue tmp2) {
249 append(new LIROp2(LIROpcode.Tan, from, tmp1, to, tmp2));
250 }
251
252 public void add(CiValue left, CiValue right, CiValue res) {
253 append(new LIROp2(LIROpcode.Add, left, right, res));
254 }
255
256 public void sub(CiValue left, CiValue right, CiValue res) {
257 append(new LIROp2(LIROpcode.Sub, left, right, res));
258 }
259
260 public void mul(CiValue left, CiValue right, CiValue res) {
261 append(new LIROp2(LIROpcode.Mul, left, right, res));
262 }
263
264 public void div(CiValue left, CiValue right, CiValue res, LIRDebugInfo info) {
265 append(new LIROp2(LIROpcode.Div, left, right, res, info));
266 }
267
268 public void rem(CiValue left, CiValue right, CiValue res, LIRDebugInfo info) {
269 append(new LIROp2(LIROpcode.Rem, left, right, res, info));
270 }
271
272 public void jump(BlockBegin block) {
273 append(new LIRBranch(Condition.TRUE, CiKind.Illegal, block));
274 }
275
276 public void branch(Condition cond, Label lbl) {
277 append(new LIRBranch(cond, lbl));
278 }
279
280 public void branch(Condition cond, Label lbl, LIRDebugInfo info) {
281 append(new LIRBranch(cond, lbl, info));
282 }
283
284 public void branch(Condition cond, CiKind kind, BlockBegin block) {
285 assert kind != CiKind.Float && kind != CiKind.Double : "no fp comparisons";
286 append(new LIRBranch(cond, kind, block));
287 }
288
289 public void branch(Condition cond, CiKind kind, BlockBegin block, BlockBegin unordered) {
290 assert kind == CiKind.Float || kind == CiKind.Double : "fp comparisons only";
291 append(new LIRBranch(cond, kind, block, unordered));
292 }
293
294 public void tableswitch(CiValue index, int lowKey, BlockBegin defaultTargets, BlockBegin[] targets) {
295 append(new LIRTableSwitch(index, lowKey, defaultTargets, targets));
296 }
297
298 public void shiftLeft(CiValue value, int count, CiValue dst) {
299 shiftLeft(value, CiConstant.forInt(count), dst, CiValue.IllegalValue);
300 }
301
302 public void shiftRight(CiValue value, int count, CiValue dst) {
303 shiftRight(value, CiConstant.forInt(count), dst, CiValue.IllegalValue);
304 }
305
306 public void lcmp2int(CiValue left, CiValue right, CiValue dst) {
307 append(new LIROp2(LIROpcode.Cmpl2i, left, right, dst));
308 }
309
310 public void callRuntime(CiRuntimeCall rtCall, CiValue result, List<CiValue> arguments, LIRDebugInfo info) {
311 append(new LIRCall(runtimeCallOp, rtCall, result, arguments, info, null, false, null));
312 }
313
314 public void pause() {
315 append(new LIROp0(LIROpcode.Pause));
316 }
317
318 public void breakpoint() {
319 append(new LIROp0(LIROpcode.Breakpoint));
320 }
321
322 public void prefetch(CiAddress addr, boolean isStore) {
323 append(new LIROp1(isStore ? LIROpcode.Prefetchw : LIROpcode.Prefetchr, addr));
324 }
325
326 public void idiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) {
327 append(new LIROp3(LIROpcode.Idiv, left, right, tmp, res, info));
328 }
329
330 public void irem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) {
331 append(new LIROp3(LIROpcode.Irem, left, right, tmp, res, info));
332 }
333
334 public void ldiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) {
335 append(new LIROp3(LIROpcode.Ldiv, left, right, tmp, res, info));
336 }
337
338 public void lrem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) {
339 append(new LIROp3(LIROpcode.Lrem, left, right, tmp, res, info));
340 }
341
342 public void lsb(CiValue src, CiValue dst) {
343 append(new LIRSignificantBit(LIROpcode.Lsb, src, dst));
344 }
345
346 public void msb(CiValue src, CiValue dst) {
347 append(new LIRSignificantBit(LIROpcode.Msb, src, dst));
348 }
349
350 public void wdiv(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) {
351 append(new LIROp3(LIROpcode.Wdiv, left, right, tmp, res, info));
352 }
353
354 public void wrem(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) {
355 append(new LIROp3(LIROpcode.Wrem, left, right, tmp, res, info));
356 }
357
358 public void wdivi(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) {
359 append(new LIROp3(LIROpcode.Wdivi, left, right, tmp, res, info));
360 }
361
362 public void wremi(CiValue left, CiValue right, CiValue res, CiValue tmp, LIRDebugInfo info) {
363 append(new LIROp3(LIROpcode.Wremi, left, right, tmp, res, info));
364 }
365
366 public void cmpMemInt(Condition condition, CiValue base, int disp, int c, LIRDebugInfo info) {
367 append(new LIROp2(LIROpcode.Cmp, condition, new CiAddress(CiKind.Int, base, disp), CiConstant.forInt(c), info));
368 }
369
370 public void cmpRegMem(Condition condition, CiValue reg, CiAddress addr, LIRDebugInfo info) {
371 append(new LIROp2(LIROpcode.Cmp, condition, reg, addr, info));
372 }
373
374 public void shiftLeft(CiValue value, CiValue count, CiValue dst, CiValue tmp) {
375 append(new LIROp2(LIROpcode.Shl, value, count, dst, tmp));
376 }
377
378 public void shiftRight(CiValue value, CiValue count, CiValue dst, CiValue tmp) {
379 append(new LIROp2(LIROpcode.Shr, value, count, dst, tmp));
380 }
381
382 public void unsignedShiftRight(CiValue value, CiValue count, CiValue dst, CiValue tmp) {
383 append(new LIROp2(LIROpcode.Ushr, value, count, dst, tmp));
384 }
385
386 public void fcmp2int(CiValue left, CiValue right, CiValue dst, boolean isUnorderedLess) {
387 append(new LIROp2(isUnorderedLess ? LIROpcode.Ucmpfd2i : LIROpcode.Cmpfd2i, left, right, dst));
388 }
389
390 public void casLong(CiValue addr, CiValue cmpValue, CiValue newValue) {
391 // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue,
392 // implying successful swap of newValue into addr
393 append(new LIRCompareAndSwap(LIROpcode.CasLong, addr, cmpValue, newValue));
394 }
395
396 public void casObj(CiValue addr, CiValue cmpValue, CiValue newValue) {
397 // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue,
398 // implying successful swap of newValue into addr
399 append(new LIRCompareAndSwap(LIROpcode.CasObj, addr, cmpValue, newValue));
400 }
401
402 public void casInt(CiValue addr, CiValue cmpValue, CiValue newValue) {
403 // Compare and swap produces condition code "zero" if contentsOf(addr) == cmpValue,
404 // implying successful swap of newValue into addr
405 append(new LIRCompareAndSwap(LIROpcode.CasInt, addr, cmpValue, newValue));
406 }
407
408 public void store(CiValue src, CiAddress dst, LIRDebugInfo info) {
409 append(new LIROp1(LIROpcode.Move, src, dst, dst.kind, info));
410 }
411
412 public void load(CiAddress src, CiValue dst, LIRDebugInfo info) {
413 append(new LIROp1(LIROpcode.Move, src, dst, src.kind, info));
414 }
415
416 public static void printBlock(BlockBegin x) {
417 // print block id
418 BlockEnd end = x.end();
419 TTY.print("B%d ", x.blockID);
420
421 // print flags
422 if (x.checkBlockFlag(BlockBegin.BlockFlag.StandardEntry)) {
423 TTY.print("std ");
424 }
425 if (x.checkBlockFlag(BlockBegin.BlockFlag.OsrEntry)) {
426 TTY.print("osr ");
427 }
428 if (x.checkBlockFlag(BlockBegin.BlockFlag.ExceptionEntry)) {
429 TTY.print("ex ");
430 }
431 if (x.checkBlockFlag(BlockBegin.BlockFlag.SubroutineEntry)) {
432 TTY.print("jsr ");
433 }
434 if (x.checkBlockFlag(BlockBegin.BlockFlag.BackwardBranchTarget)) {
435 TTY.print("bb ");
436 }
437 if (x.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopHeader)) {
438 TTY.print("lh ");
439 }
440 if (x.checkBlockFlag(BlockBegin.BlockFlag.LinearScanLoopEnd)) {
441 TTY.print("le ");
442 }
443
444 // print block bci range
445 TTY.print("[%d, %d] ", x.bci(), (end == null ? -1 : end.bci()));
446
447 // print predecessors and successors
448 if (x.numberOfPreds() > 0) {
449 TTY.print("preds: ");
450 for (int i = 0; i < x.numberOfPreds(); i++) {
451 TTY.print("B%d ", x.predAt(i).blockID);
452 }
453 }
454
455 if (x.numberOfSux() > 0) {
456 TTY.print("sux: ");
457 for (int i = 0; i < x.numberOfSux(); i++) {
458 TTY.print("B%d ", x.suxAt(i).blockID);
459 }
460 }
461
462 // print exception handlers
463 if (x.numberOfExceptionHandlers() > 0) {
464 TTY.print("xhandler: ");
465 for (int i = 0; i < x.numberOfExceptionHandlers(); i++) {
466 TTY.print("B%d ", x.exceptionHandlerAt(i).blockID);
467 }
468 }
469
470 TTY.println();
471 }
472
473 public static void printLIR(List<BlockBegin> blocks) {
474 if (TTY.isSuppressed()) {
475 return;
476 }
477 TTY.println("LIR:");
478 int i;
479 for (i = 0; i < blocks.size(); i++) {
480 BlockBegin bb = blocks.get(i);
481 printBlock(bb);
482 TTY.println("__id_Instruction___________________________________________");
483 bb.lir().printInstructions();
484 }
485 }
486
487 private void printInstructions() {
488 for (int i = 0; i < operations.size(); i++) {
489 TTY.println(operations.get(i).toStringWithIdPrefix());
490 TTY.println();
491 }
492 TTY.println();
493 }
494
495 public void append(LIRInsertionBuffer buffer) {
496 assert this == buffer.lirList() : "wrong lir list";
497 int n = operations.size();
498
499 if (buffer.numberOfOps() > 0) {
500 // increase size of instructions list
501 for (int i = 0; i < buffer.numberOfOps(); i++) {
502 operations.add(null);
503 }
504 // insert ops from buffer into instructions list
505 int opIndex = buffer.numberOfOps() - 1;
506 int ipIndex = buffer.numberOfInsertionPoints() - 1;
507 int fromIndex = n - 1;
508 int toIndex = operations.size() - 1;
509 for (; ipIndex >= 0; ipIndex--) {
510 int index = buffer.indexAt(ipIndex);
511 // make room after insertion point
512 while (index < fromIndex) {
513 operations.set(toIndex--, operations.get(fromIndex--));
514 }
515 // insert ops from buffer
516 for (int i = buffer.countAt(ipIndex); i > 0; i--) {
517 operations.set(toIndex--, buffer.opAt(opIndex--));
518 }
519 }
520 }
521
522 buffer.finish();
523 }
524
525 public void insertBefore(int i, LIRInstruction op) {
526 operations.add(i, op);
527 }
528
529 public void xir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, int tempInputCount, int tempCount, CiValue[] inputOperands, int[] operandIndices, int outputOperandIndex,
530 LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod method, List<CiValue> pointerSlots) {
531 append(new LIRXirInstruction(snippet, operands, outputOperand, tempInputCount, tempCount, inputOperands, operandIndices, outputOperandIndex, info, infoAfter, method, pointerSlots));
532 }
533 }