< prev index next >
src/hotspot/share/opto/compile.cpp
Print this page
rev 54960 : 8213084: Rework and enhance Print[Opto]Assembly output
Reviewed-by: kvn, thartmann
*** 1,7 ****
/*
! * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 711,730 ****
tty->print(" ");
}
TraceTime t1("Total compilation time", &_t_totalCompilation, CITime, CITimeVerbose);
TraceTime t2(NULL, &_t_methodCompilation, CITime, false);
! #ifndef PRODUCT
bool print_opto_assembly = directive->PrintOptoAssemblyOption;
! if (!print_opto_assembly) {
bool print_assembly = directive->PrintAssemblyOption;
! if (print_assembly && !Disassembler::can_decode()) {
! tty->print_cr("PrintAssembly request changed to PrintOptoAssembly");
! print_opto_assembly = true;
! }
! }
! set_print_assembly(print_opto_assembly);
set_parsed_irreducible_loop(false);
if (directive->ReplayInlineOption) {
_replay_inline_data = ciReplay::load_inline_data(method(), entry_bci(), ci_env->comp_level());
}
--- 711,733 ----
tty->print(" ");
}
TraceTime t1("Total compilation time", &_t_totalCompilation, CITime, CITimeVerbose);
TraceTime t2(NULL, &_t_methodCompilation, CITime, false);
! #if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
bool print_opto_assembly = directive->PrintOptoAssemblyOption;
! // We can always print a disassembly, either abstract (hex dump) or
! // with the help of a suitable hsdis library. Thus, we should not
! // couple print_assembly and print_opto_assembly controls.
! // But: always print opto and regular assembly on compile command 'print'.
bool print_assembly = directive->PrintAssemblyOption;
! set_print_assembly(print_opto_assembly || print_assembly);
! #else
! set_print_assembly(false); // must initialize.
! #endif
!
! #ifndef PRODUCT
set_parsed_irreducible_loop(false);
if (directive->ReplayInlineOption) {
_replay_inline_data = ciReplay::load_inline_data(method(), entry_bci(), ci_env->comp_level());
}
*** 1025,1034 ****
--- 1028,1039 ----
TraceTime t2(NULL, &_t_stubCompilation, CITime, false);
#ifndef PRODUCT
set_print_assembly(PrintFrameConverterAssembly);
set_parsed_irreducible_loop(false);
+ #else
+ set_print_assembly(false); // Must initialize.
#endif
set_has_irreducible_loop(false); // no loops
CompileWrapper cw(this);
Init(/*AliasLevel=*/ 0);
*** 2550,2565 ****
}
//------------------------------dump_asm---------------------------------------
// Dump formatted assembly
! #ifndef PRODUCT
! void Compile::dump_asm(int *pcs, uint pc_limit) {
bool cut_short = false;
! tty->print_cr("#");
! tty->print("# "); _tf->dump(); tty->cr();
! tty->print_cr("#");
// For all blocks
int pc = 0x0; // Program counter
char starts_bundle = ' ';
_regalloc->dump_frame();
--- 2555,2583 ----
}
//------------------------------dump_asm---------------------------------------
// Dump formatted assembly
! #if defined(SUPPORT_OPTO_ASSEMBLY)
! void Compile::dump_asm_on(outputStream* st, int* pcs, uint pc_limit) {
!
! int pc_digits = 3; // #chars required for pc
! int sb_chars = 3; // #chars for "start bundle" indicator
! int tab_size = 8;
! if (pcs != NULL) {
! int max_pc = 0;
! for (uint i = 0; i < pc_limit; i++) {
! max_pc = (max_pc < pcs[i]) ? pcs[i] : max_pc;
! }
! pc_digits = ((max_pc < 4096) ? 3 : ((max_pc < 65536) ? 4 : ((max_pc < 65536*256) ? 6 : 8))); // #chars required for pc
! }
! int prefix_len = ((pc_digits + sb_chars + tab_size - 1)/tab_size)*tab_size;
!
bool cut_short = false;
! st->print_cr("#");
! st->print("# "); _tf->dump_on(st); st->cr();
! st->print_cr("#");
// For all blocks
int pc = 0x0; // Program counter
char starts_bundle = ' ';
_regalloc->dump_frame();
*** 2573,2592 ****
Block* block = _cfg->get_block(i);
if (block->is_connector() && !Verbose) {
continue;
}
n = block->head();
! if (pcs && n->_idx < pc_limit) {
! tty->print("%3.3x ", pcs[n->_idx]);
! } else {
! tty->print(" ");
}
! block->dump_head(_cfg);
if (block->is_connector()) {
! tty->print_cr(" # Empty connector block");
} else if (block->num_preds() == 2 && block->pred(1)->is_CatchProj() && block->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) {
! tty->print_cr(" # Block is sole successor of call");
}
// For all instructions
Node *delay = NULL;
for (uint j = 0; j < block->number_of_nodes(); j++) {
--- 2591,2612 ----
Block* block = _cfg->get_block(i);
if (block->is_connector() && !Verbose) {
continue;
}
n = block->head();
! if ((pcs != NULL) && (n->_idx < pc_limit)) {
! pc = pcs[n->_idx];
! st->print("%*.*x", pc_digits, pc_digits, pc);
}
! st->fill_to(prefix_len);
! block->dump_head(_cfg, st);
if (block->is_connector()) {
! st->fill_to(prefix_len);
! st->print_cr("# Empty connector block");
} else if (block->num_preds() == 2 && block->pred(1)->is_CatchProj() && block->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) {
! st->fill_to(prefix_len);
! st->print_cr("# Block is sole successor of call");
}
// For all instructions
Node *delay = NULL;
for (uint j = 0; j < block->number_of_nodes(); j++) {
*** 2618,2676 ****
!n->is_Catch() && // Would be nice to print exception table targets
!n->is_MergeMem() && // Not very interesting
!n->is_top() && // Debug info table constants
!(n->is_Con() && !n->is_Mach())// Debug info table constants
) {
! if (pcs && n->_idx < pc_limit)
! tty->print("%3.3x", pcs[n->_idx]);
! else
! tty->print(" ");
! tty->print(" %c ", starts_bundle);
starts_bundle = ' ';
! tty->print("\t");
! n->format(_regalloc, tty);
! tty->cr();
}
// If we have an instruction with a delay slot, and have seen a delay,
// then back up and print it
if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) {
! assert(delay != NULL, "no unconditional delay instruction");
if (WizardMode) delay->dump();
if (node_bundling(delay)->starts_bundle())
starts_bundle = '+';
! if (pcs && n->_idx < pc_limit)
! tty->print("%3.3x", pcs[n->_idx]);
! else
! tty->print(" ");
! tty->print(" %c ", starts_bundle);
starts_bundle = ' ';
! tty->print("\t");
! delay->format(_regalloc, tty);
! tty->cr();
delay = NULL;
}
// Dump the exception table as well
if( n->is_Catch() && (Verbose || WizardMode) ) {
// Print the exception table for this offset
_handler_table.print_subtable_for(pc);
}
}
!
! if (pcs && n->_idx < pc_limit)
! tty->print_cr("%3.3x", pcs[n->_idx]);
! else
! tty->cr();
!
assert(cut_short || delay == NULL, "no unconditional delay branch");
-
} // End of per-block dump
- tty->cr();
! if (cut_short) tty->print_cr("*** disassembly is cut short ***");
}
#endif
//------------------------------Final_Reshape_Counts---------------------------
// This class defines counters to help identify when a method
--- 2638,2695 ----
!n->is_Catch() && // Would be nice to print exception table targets
!n->is_MergeMem() && // Not very interesting
!n->is_top() && // Debug info table constants
!(n->is_Con() && !n->is_Mach())// Debug info table constants
) {
! if ((pcs != NULL) && (n->_idx < pc_limit)) {
! pc = pcs[n->_idx];
! st->print("%*.*x", pc_digits, pc_digits, pc);
! } else {
! st->fill_to(pc_digits);
! }
! st->print(" %c ", starts_bundle);
starts_bundle = ' ';
! st->fill_to(prefix_len);
! n->format(_regalloc, st);
! st->cr();
}
// If we have an instruction with a delay slot, and have seen a delay,
// then back up and print it
if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) {
! // Coverity finding - Explicit null dereferenced.
! guarantee(delay != NULL, "no unconditional delay instruction");
if (WizardMode) delay->dump();
if (node_bundling(delay)->starts_bundle())
starts_bundle = '+';
! if ((pcs != NULL) && (n->_idx < pc_limit)) {
! pc = pcs[n->_idx];
! st->print("%*.*x", pc_digits, pc_digits, pc);
! } else {
! st->fill_to(pc_digits);
! }
! st->print(" %c ", starts_bundle);
starts_bundle = ' ';
! st->fill_to(prefix_len);
! delay->format(_regalloc, st);
! st->cr();
delay = NULL;
}
// Dump the exception table as well
if( n->is_Catch() && (Verbose || WizardMode) ) {
// Print the exception table for this offset
_handler_table.print_subtable_for(pc);
}
+ st->bol(); // Make sure we start on a new line
}
! st->cr(); // one empty line between blocks
assert(cut_short || delay == NULL, "no unconditional delay branch");
} // End of per-block dump
! if (cut_short) st->print_cr("*** disassembly is cut short ***");
}
#endif
//------------------------------Final_Reshape_Counts---------------------------
// This class defines counters to help identify when a method
< prev index next >