src/share/vm/c1/c1_CFGPrinter.cpp

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

Initial load

     1 /*
     2  * Copyright 2005-2006 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_c1_CFGPrinter.cpp.incl"
    28 #ifndef PRODUCT
    31 class CFGPrinterOutput : public CHeapObj {
    32  private:
    33   outputStream* _output;
    35   Compilation*  _compilation;
    36   bool _do_print_HIR;
    37   bool _do_print_LIR;
    39   class PrintBlockClosure: public BlockClosure {
    40     void block_do(BlockBegin* block) { if (block != NULL) CFGPrinter::output()->print_block(block); }
    41   };
    44   outputStream* output() { assert(_output != NULL, ""); return _output; }
    46   void inc_indent();
    47   void dec_indent();
    48   void print(const char* format, ...);
    49   void print_begin(const char* tag);
    50   void print_end(const char* tag);
    52   char* method_name(ciMethod* method, bool short_name = false);
    54  public:
    55   CFGPrinterOutput();
    57   void set_compilation(Compilation* compilation) { _compilation = compilation; }
    58   void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; }
    60   void print_compilation();
    61   void print_intervals(IntervalList* intervals, const char* name);
    63   void print_state(BlockBegin* block);
    64   void print_operand(Value instr);
    65   void print_HIR(Value instr);
    66   void print_HIR(BlockBegin* block);
    67   void print_LIR(BlockBegin* block);
    68   void print_block(BlockBegin* block);
    69   void print_cfg(BlockList* blocks, const char* name);
    70   void print_cfg(IR* blocks, const char* name);
    71 };
    73 CFGPrinterOutput* CFGPrinter::_output = NULL;
    78 void CFGPrinter::print_compilation(Compilation* compilation) {
    79   if (_output == NULL) {
    80     _output = new CFGPrinterOutput();
    81   }
    82   output()->set_compilation(compilation);
    83   output()->print_compilation();
    84 }
    86 void CFGPrinter::print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
    87   output()->set_print_flags(do_print_HIR, do_print_LIR);
    88   output()->print_cfg(blocks, name);
    89 }
    91 void CFGPrinter::print_cfg(IR* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
    92   output()->set_print_flags(do_print_HIR, do_print_LIR);
    93   output()->print_cfg(blocks, name);
    94 }
    97 void CFGPrinter::print_intervals(IntervalList* intervals, const char* name) {
    98   output()->print_intervals(intervals, name);
    99 }
   103 CFGPrinterOutput::CFGPrinterOutput()
   104  : _output(new(ResourceObj::C_HEAP) fileStream("output.cfg"))
   105 {
   106 }
   110 void CFGPrinterOutput::inc_indent() {
   111   output()->inc();
   112   output()->inc();
   113 }
   115 void CFGPrinterOutput::dec_indent() {
   116   output()->dec();
   117   output()->dec();
   118 }
   120 void CFGPrinterOutput::print(const char* format, ...) {
   121   output()->indent();
   123   va_list ap;
   124   va_start(ap, format);
   125   output()->vprint_cr(format, ap);
   126   va_end(ap);
   127 }
   129 void CFGPrinterOutput::print_begin(const char* tag) {
   130   output()->indent();
   131   output()->print_cr("begin_%s", tag);
   132   inc_indent();
   133 }
   135 void CFGPrinterOutput::print_end(const char* tag) {
   136   dec_indent();
   137   output()->indent();
   138   output()->print_cr("end_%s", tag);
   139 }
   142 char* CFGPrinterOutput::method_name(ciMethod* method, bool short_name) {
   143   stringStream name;
   144   if (short_name) {
   145     method->print_short_name(&name);
   146   } else {
   147     method->print_name(&name);
   148   }
   149   return name.as_string();
   151 }
   154 void CFGPrinterOutput::print_compilation() {
   155   print_begin("compilation");
   157   print("name \"%s\"", method_name(_compilation->method(), true));
   158   print("method \"%s\"", method_name(_compilation->method()));
   159   print("date "INT64_FORMAT, os::javaTimeMillis());
   161   print_end("compilation");
   162 }
   168 void CFGPrinterOutput::print_state(BlockBegin* block) {
   169   print_begin("states");
   171   InstructionPrinter ip(true, output());
   173   ValueStack* state = block->state();
   174   int index;
   175   Value value;
   177   if (state->stack_size() > 0) {
   178     print_begin("stack");
   179     print("size %d", state->stack_size());
   181     for_each_stack_value(state, index, value) {
   182       ip.print_phi(index, value, block);
   183       print_operand(value);
   184       output()->cr();
   185     }
   187     print_end("stack");
   188   }
   190   if (state->locks_size() > 0) {
   191     print_begin("locks");
   192     print("size %d", state->locks_size());
   194     for_each_lock_value(state, index, value) {
   195       ip.print_phi(index, value, block);
   196       print_operand(value);
   197       output()->cr();
   198     }
   199     print_end("locks");
   200   }
   202   for_each_state(state) {
   203     print_begin("locals");
   204     print("size %d", state->locals_size());
   205     print("method \"%s\"", method_name(state->scope()->method()));
   207     for_each_local_value(state, index, value) {
   208       ip.print_phi(index, value, block);
   209       print_operand(value);
   210       output()->cr();
   211     }
   212     print_end("locals");
   213   }
   215   print_end("states");
   216 }
   219 void CFGPrinterOutput::print_operand(Value instr) {
   220   if (instr->operand()->is_virtual()) {
   221     output()->print(" \"");
   222     instr->operand()->print(output());
   223     output()->print("\" ");
   224   }
   225 }
   227 void CFGPrinterOutput::print_HIR(Value instr) {
   228   InstructionPrinter ip(true, output());
   230   if (instr->is_pinned()) {
   231     output()->put('.');
   232   }
   233   output()->print("%d %d ", instr->bci(), instr->use_count());
   235   print_operand(instr);
   237   ip.print_temp(instr);
   238   output()->print(" ");
   239   ip.print_instr(instr);
   241   output()->print_cr(" <|@");
   242 }
   244 void CFGPrinterOutput::print_HIR(BlockBegin* block) {
   245   print_begin("HIR");
   247   Value cur = block->next();
   248   while (cur != NULL) {
   249     print_HIR(cur);
   250     cur = cur->next();
   251   }
   253   print_end("HIR");
   254 }
   256 void CFGPrinterOutput::print_LIR(BlockBegin* block) {
   257   print_begin("LIR");
   259   for (int i = 0; i < block->lir()->length(); i++) {
   260     block->lir()->at(i)->print_on(output());
   261     output()->print_cr(" <|@ ");
   262   }
   264   print_end("LIR");
   265 }
   268 void CFGPrinterOutput::print_block(BlockBegin* block) {
   269   print_begin("block");
   271   print("name \"B%d\"", block->block_id());
   273   print("from_bci %d", block->bci());
   274   print("to_bci %d", (block->end() == NULL ? -1 : block->end()->bci()));
   276   output()->indent();
   277   output()->print("predecessors ");
   278   int i;
   279   for (i = 0; i < block->number_of_preds(); i++) {
   280     output()->print("\"B%d\" ", block->pred_at(i)->block_id());
   281   }
   282   output()->cr();
   284   output()->indent();
   285   output()->print("successors ");
   286   for (i = 0; i < block->number_of_sux(); i++) {
   287     output()->print("\"B%d\" ", block->sux_at(i)->block_id());
   288   }
   289   output()->cr();
   291   output()->indent();
   292   output()->print("xhandlers");
   293   for (i = 0; i < block->number_of_exception_handlers(); i++) {
   294     output()->print("\"B%d\" ", block->exception_handler_at(i)->block_id());
   295   }
   296   output()->cr();
   298   output()->indent();
   299   output()->print("flags ");
   300   if (block->is_set(BlockBegin::std_entry_flag))                output()->print("\"std\" ");
   301   if (block->is_set(BlockBegin::osr_entry_flag))                output()->print("\"osr\" ");
   302   if (block->is_set(BlockBegin::exception_entry_flag))          output()->print("\"ex\" ");
   303   if (block->is_set(BlockBegin::subroutine_entry_flag))         output()->print("\"sr\" ");
   304   if (block->is_set(BlockBegin::backward_branch_target_flag))   output()->print("\"bb\" ");
   305   if (block->is_set(BlockBegin::parser_loop_header_flag))       output()->print("\"plh\" ");
   306   if (block->is_set(BlockBegin::critical_edge_split_flag))      output()->print("\"ces\" ");
   307   if (block->is_set(BlockBegin::linear_scan_loop_header_flag))  output()->print("\"llh\" ");
   308   if (block->is_set(BlockBegin::linear_scan_loop_end_flag))     output()->print("\"lle\" ");
   309   output()->cr();
   311   if (block->dominator() != NULL) {
   312     print("dominator \"B%d\"", block->dominator()->block_id());
   313   }
   314   if (block->loop_index() != -1) {
   315     print("loop_index %d", block->loop_index());
   316     print("loop_depth %d", block->loop_depth());
   317   }
   319   if (block->first_lir_instruction_id() != -1) {
   320     print("first_lir_id %d", block->first_lir_instruction_id());
   321     print("last_lir_id %d", block->last_lir_instruction_id());
   322   }
   324   if (_do_print_HIR) {
   325     print_state(block);
   326     print_HIR(block);
   327   }
   329   if (_do_print_LIR) {
   330     print_LIR(block);
   331   }
   333   print_end("block");
   334 }
   338 void CFGPrinterOutput::print_cfg(BlockList* blocks, const char* name) {
   339   print_begin("cfg");
   340   print("name \"%s\"", name);
   342   PrintBlockClosure print_block;
   343   blocks->iterate_forward(&print_block);
   345   print_end("cfg");
   346   output()->flush();
   347 }
   349 void CFGPrinterOutput::print_cfg(IR* blocks, const char* name) {
   350   print_begin("cfg");
   351   print("name \"%s\"", name);
   353   PrintBlockClosure print_block;
   354   blocks->iterate_preorder(&print_block);
   356   print_end("cfg");
   357   output()->flush();
   358 }
   363 void CFGPrinterOutput::print_intervals(IntervalList* intervals, const char* name) {
   364   print_begin("intervals");
   365   print("name \"%s\"", name);
   367   for (int i = 0; i < intervals->length(); i++) {
   368     if (intervals->at(i) != NULL) {
   369       intervals->at(i)->print(output());
   370     }
   371   }
   373   print_end("intervals");
   374   output()->flush();
   375 }
   378 #endif

mercurial