1 /*
   2  * Copyright (c) 2005, 2017, 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  */
  24 
  25 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "c1/c1_CFGPrinter.hpp"
  28 #include "c1/c1_IR.hpp"
  29 #include "c1/c1_InstructionPrinter.hpp"
  30 #include "c1/c1_LIR.hpp"
  31 #include "c1/c1_LinearScan.hpp"
  32 #include "c1/c1_ValueStack.hpp"
  33 
  34 #ifndef PRODUCT
  35 
  36 void CFGPrinter::print_compilation(Compilation* compilation) {
  37   CFGPrinterOutput* output = compilation->cfg_printer_output();
  38   output->print_compilation();
  39 }
  40 
  41 void CFGPrinter::print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
  42   CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
  43   output->set_print_flags(do_print_HIR, do_print_LIR);
  44   output->print_cfg(blocks, name);
  45 }
  46 
  47 void CFGPrinter::print_cfg(IR* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
  48   CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
  49   output->set_print_flags(do_print_HIR, do_print_LIR);
  50   output->print_cfg(blocks, name);
  51 }
  52 
  53 void CFGPrinter::print_intervals(IntervalList* intervals, const char* name) {
  54   CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
  55   output->print_intervals(intervals, name);
  56 }
  57 
  58 
  59 CFGPrinterOutput::CFGPrinterOutput(Compilation* compilation)
  60  : _output(NULL),
  61    _compilation(compilation),
  62    _do_print_HIR(false),
  63    _do_print_LIR(false)
  64 {
  65   char file_name[O_BUFLEN];
  66   jio_snprintf(file_name, sizeof(file_name), "output_tid" UINTX_FORMAT "_pid%u.cfg",
  67                os::current_thread_id(), os::current_process_id());
  68   _output = new(ResourceObj::C_HEAP, mtCompiler) fileStream(file_name, "at");
  69 }
  70 
  71 void CFGPrinterOutput::inc_indent() {
  72   output()->inc();
  73   output()->inc();
  74 }
  75 
  76 void CFGPrinterOutput::dec_indent() {
  77   output()->dec();
  78   output()->dec();
  79 }
  80 
  81 void CFGPrinterOutput::print(const char* format, ...) {
  82   output()->indent();
  83 
  84   va_list ap;
  85   va_start(ap, format);
  86   output()->vprint_cr(format, ap);
  87   va_end(ap);
  88 }
  89 
  90 void CFGPrinterOutput::print_begin(const char* tag) {
  91   output()->indent();
  92   output()->print_cr("begin_%s", tag);
  93   inc_indent();
  94 }
  95 
  96 void CFGPrinterOutput::print_end(const char* tag) {
  97   dec_indent();
  98   output()->indent();
  99   output()->print_cr("end_%s", tag);
 100 }
 101 
 102 
 103 char* CFGPrinterOutput::method_name(ciMethod* method, bool short_name) {
 104   stringStream name;
 105   if (short_name) {
 106     method->print_short_name(&name);
 107   } else {
 108     method->print_name(&name);
 109   }
 110   return name.as_string();
 111 
 112 }
 113 
 114 
 115 void CFGPrinterOutput::print_compilation() {
 116   print_begin("compilation");
 117 
 118   print("name \"%s\"", method_name(_compilation->method(), true));
 119   print("method \"%s\"", method_name(_compilation->method()));
 120   print("date " INT64_FORMAT, (int64_t) os::javaTimeMillis());
 121 
 122   print_end("compilation");
 123 }
 124 
 125 
 126 
 127 
 128 
 129 void CFGPrinterOutput::print_state(BlockBegin* block) {
 130   print_begin("states");
 131 
 132   InstructionPrinter ip(true, output());
 133 
 134   ValueStack* state = block->state();
 135   int index;
 136   Value value;
 137 
 138   for_each_state(state) {
 139     print_begin("locals");
 140     print("size %d", state->locals_size());
 141     print("method \"%s\"", method_name(state->scope()->method()));
 142 
 143     for_each_local_value(state, index, value) {
 144       ip.print_phi(index, value, block);
 145       print_operand(value);
 146       output()->cr();
 147     }
 148     print_end("locals");
 149 
 150     if (state->stack_size() > 0) {
 151       print_begin("stack");
 152       print("size %d", state->stack_size());
 153       print("method \"%s\"", method_name(state->scope()->method()));
 154 
 155       for_each_stack_value(state, index, value) {
 156         ip.print_phi(index, value, block);
 157         print_operand(value);
 158         output()->cr();
 159       }
 160 
 161       print_end("stack");
 162     }
 163 
 164     if (state->locks_size() > 0) {
 165       print_begin("locks");
 166       print("size %d", state->locks_size());
 167       print("method \"%s\"", method_name(state->scope()->method()));
 168 
 169       for_each_lock_value(state, index, value) {
 170         ip.print_phi(index, value, block);
 171         print_operand(value);
 172         output()->cr();
 173       }
 174       print_end("locks");
 175     }
 176   }
 177 
 178   print_end("states");
 179 }
 180 
 181 
 182 void CFGPrinterOutput::print_operand(Value instr) {
 183   if (instr->operand()->is_virtual()) {
 184     output()->print(" \"");
 185     instr->operand()->print(output());
 186     output()->print("\" ");
 187   }
 188 }
 189 
 190 void CFGPrinterOutput::print_HIR(Value instr) {
 191   InstructionPrinter ip(true, output());
 192 
 193   if (instr->is_pinned()) {
 194     output()->put('.');
 195   }
 196 
 197   output()->print("%d %d ", instr->printable_bci(), instr->use_count());
 198 
 199   print_operand(instr);
 200 
 201   ip.print_temp(instr);
 202   output()->print(" ");
 203   ip.print_instr(instr);
 204 
 205   output()->print_cr(" <|@");
 206 }
 207 
 208 void CFGPrinterOutput::print_HIR(BlockBegin* block) {
 209   print_begin("HIR");
 210 
 211   Value cur = block->next();
 212   while (cur != NULL) {
 213     print_HIR(cur);
 214     cur = cur->next();
 215   }
 216 
 217   print_end("HIR");
 218 }
 219 
 220 void CFGPrinterOutput::print_LIR(BlockBegin* block) {
 221   print_begin("LIR");
 222 
 223   for (int i = 0; i < block->lir()->length(); i++) {
 224     block->lir()->at(i)->print_on(output());
 225     output()->print_cr(" <|@ ");
 226   }
 227 
 228   print_end("LIR");
 229 }
 230 
 231 
 232 void CFGPrinterOutput::print_block(BlockBegin* block) {
 233   print_begin("block");
 234 
 235   print("name \"B%d\"", block->block_id());
 236 
 237   print("from_bci %d", block->bci());
 238   print("to_bci %d", (block->end() == NULL ? -1 : block->end()->printable_bci()));
 239 
 240   output()->indent();
 241   output()->print("predecessors ");
 242   int i;
 243   for (i = 0; i < block->number_of_preds(); i++) {
 244     output()->print("\"B%d\" ", block->pred_at(i)->block_id());
 245   }
 246   output()->cr();
 247 
 248   output()->indent();
 249   output()->print("successors ");
 250   for (i = 0; i < block->number_of_sux(); i++) {
 251     output()->print("\"B%d\" ", block->sux_at(i)->block_id());
 252   }
 253   output()->cr();
 254 
 255   output()->indent();
 256   output()->print("xhandlers");
 257   for (i = 0; i < block->number_of_exception_handlers(); i++) {
 258     output()->print("\"B%d\" ", block->exception_handler_at(i)->block_id());
 259   }
 260   output()->cr();
 261 
 262   output()->indent();
 263   output()->print("flags ");
 264   if (block->is_set(BlockBegin::std_entry_flag))                output()->print("\"std\" ");
 265   if (block->is_set(BlockBegin::osr_entry_flag))                output()->print("\"osr\" ");
 266   if (block->is_set(BlockBegin::exception_entry_flag))          output()->print("\"ex\" ");
 267   if (block->is_set(BlockBegin::subroutine_entry_flag))         output()->print("\"sr\" ");
 268   if (block->is_set(BlockBegin::backward_branch_target_flag))   output()->print("\"bb\" ");
 269   if (block->is_set(BlockBegin::parser_loop_header_flag))       output()->print("\"plh\" ");
 270   if (block->is_set(BlockBegin::critical_edge_split_flag))      output()->print("\"ces\" ");
 271   if (block->is_set(BlockBegin::linear_scan_loop_header_flag))  output()->print("\"llh\" ");
 272   if (block->is_set(BlockBegin::linear_scan_loop_end_flag))     output()->print("\"lle\" ");
 273   output()->cr();
 274 
 275   if (block->dominator() != NULL) {
 276     print("dominator \"B%d\"", block->dominator()->block_id());
 277   }
 278   if (block->loop_index() != -1) {
 279     print("loop_index %d", block->loop_index());
 280     print("loop_depth %d", block->loop_depth());
 281   }
 282 
 283   if (block->first_lir_instruction_id() != -1) {
 284     print("first_lir_id %d", block->first_lir_instruction_id());
 285     print("last_lir_id %d", block->last_lir_instruction_id());
 286   }
 287 
 288   if (_do_print_HIR) {
 289     print_state(block);
 290     print_HIR(block);
 291   }
 292 
 293   if (_do_print_LIR) {
 294     print_LIR(block);
 295   }
 296 
 297   print_end("block");
 298 }
 299 
 300 
 301 
 302 void CFGPrinterOutput::print_cfg(BlockList* blocks, const char* name) {
 303   print_begin("cfg");
 304   print("name \"%s\"", name);
 305 
 306   PrintBlockClosure print_block;
 307   blocks->iterate_forward(&print_block);
 308 
 309   print_end("cfg");
 310   output()->flush();
 311 }
 312 
 313 void CFGPrinterOutput::print_cfg(IR* blocks, const char* name) {
 314   print_begin("cfg");
 315   print("name \"%s\"", name);
 316 
 317   PrintBlockClosure print_block;
 318   blocks->iterate_preorder(&print_block);
 319 
 320   print_end("cfg");
 321   output()->flush();
 322 }
 323 
 324 
 325 
 326 
 327 void CFGPrinterOutput::print_intervals(IntervalList* intervals, const char* name) {
 328   print_begin("intervals");
 329   print("name \"%s\"", name);
 330 
 331   for (int i = 0; i < intervals->length(); i++) {
 332     if (intervals->at(i) != NULL) {
 333       intervals->at(i)->print(output());
 334     }
 335   }
 336 
 337   print_end("intervals");
 338   output()->flush();
 339 }
 340 
 341 
 342 #endif