src/share/vm/c1/c1_CFGPrinter.cpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 6680
78bbf4d43a14
parent 0
f90c822e73f8
child 9448
73d689add964
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 2005, 2014, 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  */
    25 #include "precompiled.hpp"
    26 #include "c1/c1_CFGPrinter.hpp"
    27 #include "c1/c1_IR.hpp"
    28 #include "c1/c1_InstructionPrinter.hpp"
    29 #include "c1/c1_LIR.hpp"
    30 #include "c1/c1_LinearScan.hpp"
    31 #include "c1/c1_ValueStack.hpp"
    33 #ifndef PRODUCT
    36 class CFGPrinterOutput : public CHeapObj<mtCompiler> {
    37  private:
    38   outputStream* _output;
    40   Compilation*  _compilation;
    41   bool _do_print_HIR;
    42   bool _do_print_LIR;
    44   class PrintBlockClosure: public BlockClosure {
    45     void block_do(BlockBegin* block) { if (block != NULL) CFGPrinter::output()->print_block(block); }
    46   };
    49   outputStream* output() { assert(_output != NULL, ""); return _output; }
    51   void inc_indent();
    52   void dec_indent();
    53   void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
    54   void print_begin(const char* tag);
    55   void print_end(const char* tag);
    57   char* method_name(ciMethod* method, bool short_name = false);
    59  public:
    60   CFGPrinterOutput();
    62   void set_compilation(Compilation* compilation) { _compilation = compilation; }
    63   void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; }
    65   void print_compilation();
    66   void print_intervals(IntervalList* intervals, const char* name);
    68   void print_state(BlockBegin* block);
    69   void print_operand(Value instr);
    70   void print_HIR(Value instr);
    71   void print_HIR(BlockBegin* block);
    72   void print_LIR(BlockBegin* block);
    73   void print_block(BlockBegin* block);
    74   void print_cfg(BlockList* blocks, const char* name);
    75   void print_cfg(IR* blocks, const char* name);
    76 };
    78 CFGPrinterOutput* CFGPrinter::_output = NULL;
    83 void CFGPrinter::print_compilation(Compilation* compilation) {
    84   if (_output == NULL) {
    85     _output = new CFGPrinterOutput();
    86   }
    87   output()->set_compilation(compilation);
    88   output()->print_compilation();
    89 }
    91 void CFGPrinter::print_cfg(BlockList* 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 }
    96 void 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 }
   102 void CFGPrinter::print_intervals(IntervalList* intervals, const char* name) {
   103   output()->print_intervals(intervals, name);
   104 }
   108 CFGPrinterOutput::CFGPrinterOutput()
   109  : _output(new(ResourceObj::C_HEAP, mtCompiler) fileStream("output.cfg"))
   110 {
   111 }
   115 void CFGPrinterOutput::inc_indent() {
   116   output()->inc();
   117   output()->inc();
   118 }
   120 void CFGPrinterOutput::dec_indent() {
   121   output()->dec();
   122   output()->dec();
   123 }
   125 void CFGPrinterOutput::print(const char* format, ...) {
   126   output()->indent();
   128   va_list ap;
   129   va_start(ap, format);
   130   output()->vprint_cr(format, ap);
   131   va_end(ap);
   132 }
   134 void CFGPrinterOutput::print_begin(const char* tag) {
   135   output()->indent();
   136   output()->print_cr("begin_%s", tag);
   137   inc_indent();
   138 }
   140 void CFGPrinterOutput::print_end(const char* tag) {
   141   dec_indent();
   142   output()->indent();
   143   output()->print_cr("end_%s", tag);
   144 }
   147 char* 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();
   156 }
   159 void CFGPrinterOutput::print_compilation() {
   160   print_begin("compilation");
   162   print("name \"%s\"", method_name(_compilation->method(), true));
   163   print("method \"%s\"", method_name(_compilation->method()));
   164   print("date "INT64_FORMAT, (int64_t) os::javaTimeMillis());
   166   print_end("compilation");
   167 }
   173 void CFGPrinterOutput::print_state(BlockBegin* block) {
   174   print_begin("states");
   176   InstructionPrinter ip(true, output());
   178   ValueStack* state = block->state();
   179   int index;
   180   Value value;
   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()));
   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");
   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()));
   199       for_each_stack_value(state, index, value) {
   200         ip.print_phi(index, value, block);
   201         print_operand(value);
   202         output()->cr();
   203       }
   205       print_end("stack");
   206     }
   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()));
   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   }
   222   print_end("states");
   223 }
   226 void CFGPrinterOutput::print_operand(Value instr) {
   227   if (instr->operand()->is_virtual()) {
   228     output()->print(" \"");
   229     instr->operand()->print(output());
   230     output()->print("\" ");
   231   }
   232 }
   234 void CFGPrinterOutput::print_HIR(Value instr) {
   235   InstructionPrinter ip(true, output());
   237   if (instr->is_pinned()) {
   238     output()->put('.');
   239   }
   241   output()->print("%d %d ", instr->printable_bci(), instr->use_count());
   243   print_operand(instr);
   245   ip.print_temp(instr);
   246   output()->print(" ");
   247   ip.print_instr(instr);
   249   output()->print_cr(" <|@");
   250 }
   252 void CFGPrinterOutput::print_HIR(BlockBegin* block) {
   253   print_begin("HIR");
   255   Value cur = block->next();
   256   while (cur != NULL) {
   257     print_HIR(cur);
   258     cur = cur->next();
   259   }
   261   print_end("HIR");
   262 }
   264 void CFGPrinterOutput::print_LIR(BlockBegin* block) {
   265   print_begin("LIR");
   267   for (int i = 0; i < block->lir()->length(); i++) {
   268     block->lir()->at(i)->print_on(output());
   269     output()->print_cr(" <|@ ");
   270   }
   272   print_end("LIR");
   273 }
   276 void CFGPrinterOutput::print_block(BlockBegin* block) {
   277   print_begin("block");
   279   print("name \"B%d\"", block->block_id());
   281   print("from_bci %d", block->bci());
   282   print("to_bci %d", (block->end() == NULL ? -1 : block->end()->printable_bci()));
   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();
   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();
   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();
   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();
   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   }
   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   }
   332   if (_do_print_HIR) {
   333     print_state(block);
   334     print_HIR(block);
   335   }
   337   if (_do_print_LIR) {
   338     print_LIR(block);
   339   }
   341   print_end("block");
   342 }
   346 void CFGPrinterOutput::print_cfg(BlockList* blocks, const char* name) {
   347   print_begin("cfg");
   348   print("name \"%s\"", name);
   350   PrintBlockClosure print_block;
   351   blocks->iterate_forward(&print_block);
   353   print_end("cfg");
   354   output()->flush();
   355 }
   357 void CFGPrinterOutput::print_cfg(IR* blocks, const char* name) {
   358   print_begin("cfg");
   359   print("name \"%s\"", name);
   361   PrintBlockClosure print_block;
   362   blocks->iterate_preorder(&print_block);
   364   print_end("cfg");
   365   output()->flush();
   366 }
   371 void CFGPrinterOutput::print_intervals(IntervalList* intervals, const char* name) {
   372   print_begin("intervals");
   373   print("name \"%s\"", name);
   375   for (int i = 0; i < intervals->length(); i++) {
   376     if (intervals->at(i) != NULL) {
   377       intervals->at(i)->print(output());
   378     }
   379   }
   381   print_end("intervals");
   382   output()->flush();
   383 }
   386 #endif

mercurial