c1_CFGPrinter.cpp revision 1879:f95d63e2154a
1123256Sscottl/*
2123256Sscottl * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
3123256Sscottl * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4123256Sscottl *
5123256Sscottl * This code is free software; you can redistribute it and/or modify it
6123256Sscottl * under the terms of the GNU General Public License version 2 only, as
7123256Sscottl * published by the Free Software Foundation.
8123256Sscottl *
9123256Sscottl * This code is distributed in the hope that it will be useful, but WITHOUT
10123256Sscottl * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11123256Sscottl * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12123256Sscottl * version 2 for more details (a copy is included in the LICENSE file that
13123256Sscottl * accompanied this code).
14123256Sscottl *
15123256Sscottl * You should have received a copy of the GNU General Public License version
16123256Sscottl * 2 along with this work; if not, write to the Free Software Foundation,
17123256Sscottl * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18123256Sscottl *
19123256Sscottl * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20123256Sscottl * or visit www.oracle.com if you need additional information or have any
21123256Sscottl * questions.
22123256Sscottl *
23123256Sscottl */
24123256Sscottl
25123256Sscottl#include "precompiled.hpp"
26123256Sscottl#include "c1/c1_CFGPrinter.hpp"
27123256Sscottl#include "c1/c1_IR.hpp"
28123256Sscottl#include "c1/c1_InstructionPrinter.hpp"
29123256Sscottl#include "c1/c1_LIR.hpp"
30123256Sscottl#include "c1/c1_LinearScan.hpp"
31180161Sjhb#include "c1/c1_ValueStack.hpp"
32206622Suqs
33123256Sscottl#ifndef PRODUCT
34123256Sscottl
35123256Sscottl
36180161Sjhbclass CFGPrinterOutput : public CHeapObj {
37123256Sscottl private:
38180161Sjhb  outputStream* _output;
39123256Sscottl
40123256Sscottl  Compilation*  _compilation;
41123256Sscottl  bool _do_print_HIR;
42131736Sru  bool _do_print_LIR;
43131736Sru
44180161Sjhb  class PrintBlockClosure: public BlockClosure {
45180161Sjhb    void block_do(BlockBegin* block) { if (block != NULL) CFGPrinter::output()->print_block(block); }
46131736Sru  };
47131736Sru
48128951Shmp
49123492Sroam  outputStream* output() { assert(_output != NULL, ""); return _output; }
50131736Sru
51131736Sru  void inc_indent();
52131736Sru  void dec_indent();
53131736Sru  void print(const char* format, ...);
54123256Sscottl  void print_begin(const char* tag);
55128951Shmp  void print_end(const char* tag);
56131736Sru
57131736Sru  char* method_name(ciMethod* method, bool short_name = false);
58131736Sru
59123256Sscottl public:
60131736Sru  CFGPrinterOutput();
61123256Sscottl
62131736Sru  void set_compilation(Compilation* compilation) { _compilation = compilation; }
63131736Sru  void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; }
64131736Sru
65128951Shmp  void print_compilation();
66131736Sru  void print_intervals(IntervalList* intervals, const char* name);
67131736Sru
68131736Sru  void print_state(BlockBegin* block);
69123256Sscottl  void print_operand(Value instr);
70131736Sru  void print_HIR(Value instr);
71131736Sru  void print_HIR(BlockBegin* block);
72131736Sru  void print_LIR(BlockBegin* block);
73128951Shmp  void print_block(BlockBegin* block);
74128951Shmp  void print_cfg(BlockList* blocks, const char* name);
75131736Sru  void print_cfg(IR* blocks, const char* name);
76131736Sru};
77131736Sru
78131736SruCFGPrinterOutput* CFGPrinter::_output = NULL;
79131736Sru
80131736Sru
81131736Sru
82131736Sru
83131736Sruvoid CFGPrinter::print_compilation(Compilation* compilation) {
84131736Sru  if (_output == NULL) {
85131736Sru    _output = new CFGPrinterOutput();
86131736Sru  }
87131736Sru  output()->set_compilation(compilation);
88123256Sscottl  output()->print_compilation();
89123256Sscottl}
90123256Sscottl
91123256Sscottlvoid CFGPrinter::print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
92123256Sscottl  output()->set_print_flags(do_print_HIR, do_print_LIR);
93147647Shmp  output()->print_cfg(blocks, name);
94123256Sscottl}
95
96void CFGPrinter::print_cfg(IR* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
97  output()->set_print_flags(do_print_HIR, do_print_LIR);
98  output()->print_cfg(blocks, name);
99}
100
101
102void CFGPrinter::print_intervals(IntervalList* intervals, const char* name) {
103  output()->print_intervals(intervals, name);
104}
105
106
107
108CFGPrinterOutput::CFGPrinterOutput()
109 : _output(new(ResourceObj::C_HEAP) fileStream("output.cfg"))
110{
111}
112
113
114
115void CFGPrinterOutput::inc_indent() {
116  output()->inc();
117  output()->inc();
118}
119
120void CFGPrinterOutput::dec_indent() {
121  output()->dec();
122  output()->dec();
123}
124
125void CFGPrinterOutput::print(const char* format, ...) {
126  output()->indent();
127
128  va_list ap;
129  va_start(ap, format);
130  output()->vprint_cr(format, ap);
131  va_end(ap);
132}
133
134void CFGPrinterOutput::print_begin(const char* tag) {
135  output()->indent();
136  output()->print_cr("begin_%s", tag);
137  inc_indent();
138}
139
140void CFGPrinterOutput::print_end(const char* tag) {
141  dec_indent();
142  output()->indent();
143  output()->print_cr("end_%s", tag);
144}
145
146
147char* CFGPrinterOutput::method_name(ciMethod* method, bool short_name) {
148  stringStream name;
149  if (short_name) {
150    method->print_short_name(&name);
151  } else {
152    method->print_name(&name);
153  }
154  return name.as_string();
155
156}
157
158
159void CFGPrinterOutput::print_compilation() {
160  print_begin("compilation");
161
162  print("name \"%s\"", method_name(_compilation->method(), true));
163  print("method \"%s\"", method_name(_compilation->method()));
164  print("date "INT64_FORMAT, os::javaTimeMillis());
165
166  print_end("compilation");
167}
168
169
170
171
172
173void CFGPrinterOutput::print_state(BlockBegin* block) {
174  print_begin("states");
175
176  InstructionPrinter ip(true, output());
177
178  ValueStack* state = block->state();
179  int index;
180  Value value;
181
182  for_each_state(state) {
183    print_begin("locals");
184    print("size %d", state->locals_size());
185    print("method \"%s\"", method_name(state->scope()->method()));
186
187    for_each_local_value(state, index, value) {
188      ip.print_phi(index, value, block);
189      print_operand(value);
190      output()->cr();
191    }
192    print_end("locals");
193
194    if (state->stack_size() > 0) {
195      print_begin("stack");
196      print("size %d", state->stack_size());
197      print("method \"%s\"", method_name(state->scope()->method()));
198
199      for_each_stack_value(state, index, value) {
200        ip.print_phi(index, value, block);
201        print_operand(value);
202        output()->cr();
203      }
204
205      print_end("stack");
206    }
207
208    if (state->locks_size() > 0) {
209      print_begin("locks");
210      print("size %d", state->locks_size());
211      print("method \"%s\"", method_name(state->scope()->method()));
212
213      for_each_lock_value(state, index, value) {
214        ip.print_phi(index, value, block);
215        print_operand(value);
216        output()->cr();
217      }
218      print_end("locks");
219    }
220  }
221
222  print_end("states");
223}
224
225
226void CFGPrinterOutput::print_operand(Value instr) {
227  if (instr->operand()->is_virtual()) {
228    output()->print(" \"");
229    instr->operand()->print(output());
230    output()->print("\" ");
231  }
232}
233
234void CFGPrinterOutput::print_HIR(Value instr) {
235  InstructionPrinter ip(true, output());
236
237  if (instr->is_pinned()) {
238    output()->put('.');
239  }
240
241  output()->print("%d %d ", instr->printable_bci(), instr->use_count());
242
243  print_operand(instr);
244
245  ip.print_temp(instr);
246  output()->print(" ");
247  ip.print_instr(instr);
248
249  output()->print_cr(" <|@");
250}
251
252void CFGPrinterOutput::print_HIR(BlockBegin* block) {
253  print_begin("HIR");
254
255  Value cur = block->next();
256  while (cur != NULL) {
257    print_HIR(cur);
258    cur = cur->next();
259  }
260
261  print_end("HIR");
262}
263
264void CFGPrinterOutput::print_LIR(BlockBegin* block) {
265  print_begin("LIR");
266
267  for (int i = 0; i < block->lir()->length(); i++) {
268    block->lir()->at(i)->print_on(output());
269    output()->print_cr(" <|@ ");
270  }
271
272  print_end("LIR");
273}
274
275
276void CFGPrinterOutput::print_block(BlockBegin* block) {
277  print_begin("block");
278
279  print("name \"B%d\"", block->block_id());
280
281  print("from_bci %d", block->bci());
282  print("to_bci %d", (block->end() == NULL ? -1 : block->end()->printable_bci()));
283
284  output()->indent();
285  output()->print("predecessors ");
286  int i;
287  for (i = 0; i < block->number_of_preds(); i++) {
288    output()->print("\"B%d\" ", block->pred_at(i)->block_id());
289  }
290  output()->cr();
291
292  output()->indent();
293  output()->print("successors ");
294  for (i = 0; i < block->number_of_sux(); i++) {
295    output()->print("\"B%d\" ", block->sux_at(i)->block_id());
296  }
297  output()->cr();
298
299  output()->indent();
300  output()->print("xhandlers");
301  for (i = 0; i < block->number_of_exception_handlers(); i++) {
302    output()->print("\"B%d\" ", block->exception_handler_at(i)->block_id());
303  }
304  output()->cr();
305
306  output()->indent();
307  output()->print("flags ");
308  if (block->is_set(BlockBegin::std_entry_flag))                output()->print("\"std\" ");
309  if (block->is_set(BlockBegin::osr_entry_flag))                output()->print("\"osr\" ");
310  if (block->is_set(BlockBegin::exception_entry_flag))          output()->print("\"ex\" ");
311  if (block->is_set(BlockBegin::subroutine_entry_flag))         output()->print("\"sr\" ");
312  if (block->is_set(BlockBegin::backward_branch_target_flag))   output()->print("\"bb\" ");
313  if (block->is_set(BlockBegin::parser_loop_header_flag))       output()->print("\"plh\" ");
314  if (block->is_set(BlockBegin::critical_edge_split_flag))      output()->print("\"ces\" ");
315  if (block->is_set(BlockBegin::linear_scan_loop_header_flag))  output()->print("\"llh\" ");
316  if (block->is_set(BlockBegin::linear_scan_loop_end_flag))     output()->print("\"lle\" ");
317  output()->cr();
318
319  if (block->dominator() != NULL) {
320    print("dominator \"B%d\"", block->dominator()->block_id());
321  }
322  if (block->loop_index() != -1) {
323    print("loop_index %d", block->loop_index());
324    print("loop_depth %d", block->loop_depth());
325  }
326
327  if (block->first_lir_instruction_id() != -1) {
328    print("first_lir_id %d", block->first_lir_instruction_id());
329    print("last_lir_id %d", block->last_lir_instruction_id());
330  }
331
332  if (_do_print_HIR) {
333    print_state(block);
334    print_HIR(block);
335  }
336
337  if (_do_print_LIR) {
338    print_LIR(block);
339  }
340
341  print_end("block");
342}
343
344
345
346void CFGPrinterOutput::print_cfg(BlockList* blocks, const char* name) {
347  print_begin("cfg");
348  print("name \"%s\"", name);
349
350  PrintBlockClosure print_block;
351  blocks->iterate_forward(&print_block);
352
353  print_end("cfg");
354  output()->flush();
355}
356
357void CFGPrinterOutput::print_cfg(IR* blocks, const char* name) {
358  print_begin("cfg");
359  print("name \"%s\"", name);
360
361  PrintBlockClosure print_block;
362  blocks->iterate_preorder(&print_block);
363
364  print_end("cfg");
365  output()->flush();
366}
367
368
369
370
371void CFGPrinterOutput::print_intervals(IntervalList* intervals, const char* name) {
372  print_begin("intervals");
373  print("name \"%s\"", name);
374
375  for (int i = 0; i < intervals->length(); i++) {
376    if (intervals->at(i) != NULL) {
377      intervals->at(i)->print(output());
378    }
379  }
380
381  print_end("intervals");
382  output()->flush();
383}
384
385
386#endif
387