From 50a7c61d28b9885ff48f4fcd8bfd460b507bbcef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20H=C3=A4ssig?= Date: Mon, 19 May 2025 07:39:42 +0000 Subject: [PATCH] 8355970: C2: Add command line option to print the compile phases Reviewed-by: chagedorn, kvn, mchevalier --- .../share/compiler/compilerDirectives.hpp | 5 +-- src/hotspot/share/compiler/compilerOracle.hpp | 3 +- src/hotspot/share/opto/c2_globals.hpp | 9 +++++ src/hotspot/share/opto/compile.cpp | 35 +++++++++++-------- src/hotspot/share/opto/compile.hpp | 9 +++-- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp index 27c71b1723c..27aafe06919 100644 --- a/src/hotspot/share/compiler/compilerDirectives.hpp +++ b/src/hotspot/share/compiler/compilerDirectives.hpp @@ -83,7 +83,8 @@ NOT_PRODUCT(cflags(PrintIdeal, bool, PrintIdeal, PrintIdeal)) \ cflags(TraceSpilling, bool, TraceSpilling, TraceSpilling) \ cflags(Vectorize, bool, false, Vectorize) \ cflags(CloneMapDebug, bool, false, CloneMapDebug) \ -NOT_PRODUCT(cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel)) \ +NOT_PRODUCT(cflags(PhasePrintLevel, intx, PrintPhaseLevel, PhasePrintLevel)) \ +NOT_PRODUCT(cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel)) \ cflags(IncrementalInlineForceCleanup, bool, IncrementalInlineForceCleanup, IncrementalInlineForceCleanup) \ cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit) #define compilerdirectives_c2_string_flags(cflags) \ @@ -202,7 +203,7 @@ void set_##name(void* value) { \ void set_ideal_phase_name_set(const BitMap& set) { _ideal_phase_name_set.set_from(set); }; - bool should_print_phase(const CompilerPhaseType cpt) const { + bool should_print_ideal_phase(const CompilerPhaseType cpt) const { return _ideal_phase_name_set.at(cpt); }; void set_trace_auto_vectorization_tags(const CHeapBitMap& tags) { diff --git a/src/hotspot/share/compiler/compilerOracle.hpp b/src/hotspot/share/compiler/compilerOracle.hpp index 943cd2c9734..09984705792 100644 --- a/src/hotspot/share/compiler/compilerOracle.hpp +++ b/src/hotspot/share/compiler/compilerOracle.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -84,6 +84,7 @@ class methodHandle; NOT_PRODUCT(option(TraceEscapeAnalysis, "TraceEscapeAnalysis", Bool)) \ NOT_PRODUCT(option(PrintIdeal, "PrintIdeal", Bool)) \ NOT_PRODUCT(option(PrintIdealPhase, "PrintIdealPhase", Ccstrlist)) \ +NOT_PRODUCT(option(PhasePrintLevel, "PhasePrintLevel", Intx)) \ NOT_PRODUCT(option(IGVPrintLevel, "IGVPrintLevel", Intx)) \ NOT_PRODUCT(option(TraceAutoVectorization, "TraceAutoVectorization", Ccstrlist)) \ NOT_PRODUCT(option(TraceMergeStores, "TraceMergeStores", Ccstrlist)) \ diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index 66c9ecd2e0b..5ee0c82f3ec 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -386,6 +386,15 @@ "Limit of ops to make speculative when using CMOVE") \ range(0, max_jint) \ \ + develop(intx, PrintPhaseLevel, 0, \ + "Level of detail of the phase trace print. " \ + "System-wide value, -1=printing is disabled, " \ + "0=print nothing except PhasePrintLevel directives, " \ + "6=all details printed. " \ + "Level of detail of printouts can be set on a per-method level " \ + "as well by using CompileCommand=PrintPhaseLevel.") \ + range(-1, 6) \ + \ develop(bool, PrintIdealGraph, false, \ "Print ideal graph to XML file / network interface. " \ "By default attempts to connect to the visualizer on a socket.") \ diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index eb526fd01bd..a5023408cdf 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -33,6 +33,7 @@ #include "compiler/compilationMemoryStatistic.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compileLog.hpp" +#include "compiler/compilerDefinitions.hpp" #include "compiler/compilerOracle.hpp" #include "compiler/compiler_globals.hpp" #include "compiler/disassembler.hpp" @@ -576,6 +577,10 @@ void Compile::print_compile_messages() { } #ifndef PRODUCT +void Compile::print_phase(const char* phase_name) { + tty->print_cr("%u.\t%s", ++_phase_counter, phase_name); +} + void Compile::print_ideal_ir(const char* phase_name) { // keep the following output all in one block // This output goes directly to the tty, not the compiler log. @@ -1069,6 +1074,7 @@ void Compile::Init(bool aliasing) { set_decompile_count(0); #ifndef PRODUCT + _phase_counter = 0; Copy::zero_to_bytes(_igv_phase_iter, sizeof(_igv_phase_iter)); #endif @@ -5149,7 +5155,10 @@ void Compile::print_method(CompilerPhaseType cpt, int level, Node* n) { if (should_print_igv(level)) { _igv_printer->print_graph(name); } - if (should_print_phase(cpt)) { + if (should_print_phase(level)) { + print_phase(name); + } + if (should_print_ideal_phase(cpt)) { print_ideal_ir(CompilerPhaseTypeHelper::to_name(cpt)); } #endif @@ -5180,26 +5189,26 @@ void Compile::end_method() { #endif } -bool Compile::should_print_phase(CompilerPhaseType cpt) { #ifndef PRODUCT - if (_directive->should_print_phase(cpt)) { - return true; - } -#endif - return false; +bool Compile::should_print_phase(const int level) const { + return PrintPhaseLevel > 0 && directive()->PhasePrintLevelOption >= level && + _method != nullptr; // Do not print phases for stubs. +} + +bool Compile::should_print_ideal_phase(CompilerPhaseType cpt) const { + return _directive->should_print_ideal_phase(cpt); } -#ifndef PRODUCT void Compile::init_igv() { if (_igv_printer == nullptr) { _igv_printer = IdealGraphPrinter::printer(); _igv_printer->set_compile(this); } } -#endif bool Compile::should_print_igv(const int level) { -#ifndef PRODUCT + PRODUCT_RETURN_(return false;); + if (PrintIdealGraphLevel < 0) { // disabled by the user return false; } @@ -5209,12 +5218,8 @@ bool Compile::should_print_igv(const int level) { Compile::init_igv(); } return need; -#else - return false; -#endif } -#ifndef PRODUCT IdealGraphPrinter* Compile::_debug_file_printer = nullptr; IdealGraphPrinter* Compile::_debug_network_printer = nullptr; @@ -5303,7 +5308,7 @@ void Compile::igv_print_graph_to_network(const char* name, GrowableArrayprint_cr("Method printed over network stream to IGV"); _debug_network_printer->print(name, C->root(), visible_nodes, fr); } -#endif +#endif // !PRODUCT Node* Compile::narrow_value(BasicType bt, Node* value, const Type* type, PhaseGVN* phase, bool transform_res) { if (type != nullptr && phase->type(value)->higher_equal(type)) { diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index f67d2839611..9b6d8db05b0 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -347,6 +347,7 @@ class Compile : public Phase { bool _print_inlining; // True if we should print inlining for this compilation bool _print_intrinsics; // True if we should print intrinsics for this compilation #ifndef PRODUCT + uint _phase_counter; // Counter for the number of already printed phases uint _igv_idx; // Counter for IGV node identifiers uint _igv_phase_iter[PHASE_NUM_TYPES]; // Counters for IGV phase iterations bool _trace_opto_output; @@ -642,13 +643,14 @@ public: void set_has_scoped_access(bool v) { _has_scoped_access = v; } // check the CompilerOracle for special behaviours for this compile - bool method_has_option(CompileCommandEnum option) { + bool method_has_option(CompileCommandEnum option) const { return method() != nullptr && method()->has_option(option); } #ifndef PRODUCT uint next_igv_idx() { return _igv_idx++; } bool trace_opto_output() const { return _trace_opto_output; } + void print_phase(const char* phase_name); void print_ideal_ir(const char* phase_name); bool should_print_ideal() const { return _directive->PrintIdealOption; } bool parsed_irreducible_loop() const { return _parsed_irreducible_loop; } @@ -666,12 +668,13 @@ public: void begin_method(); void end_method(); - bool should_print_igv(int level); - bool should_print_phase(CompilerPhaseType cpt); void print_method(CompilerPhaseType cpt, int level, Node* n = nullptr); #ifndef PRODUCT + bool should_print_igv(int level); + bool should_print_phase(int level) const; + bool should_print_ideal_phase(CompilerPhaseType cpt) const; void init_igv(); void dump_igv(const char* graph_name, int level = 3) { if (should_print_igv(level)) {