src/hotspot/share/compiler/methodLiveness.cpp
changeset 53264 424e4908b4b8
parent 51333 f6641fcf7b7e
child 53265 febc37adfe80
equal deleted inserted replaced
53263:5d7e4d832868 53264:424e4908b4b8
     1 /*
     1 /*
     2  * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    29 #include "compiler/methodLiveness.hpp"
    29 #include "compiler/methodLiveness.hpp"
    30 #include "interpreter/bytecode.hpp"
    30 #include "interpreter/bytecode.hpp"
    31 #include "interpreter/bytecodes.hpp"
    31 #include "interpreter/bytecodes.hpp"
    32 #include "memory/allocation.inline.hpp"
    32 #include "memory/allocation.inline.hpp"
    33 #include "memory/resourceArea.hpp"
    33 #include "memory/resourceArea.hpp"
    34 #include "runtime/timerTrace.hpp"
       
    35 #include "utilities/bitMap.inline.hpp"
    34 #include "utilities/bitMap.inline.hpp"
    36 
    35 
    37 // The MethodLiveness class performs a simple liveness analysis on a method
    36 // The MethodLiveness class performs a simple liveness analysis on a method
    38 // in order to decide which locals are live (that is, will be used again) at
    37 // in order to decide which locals are live (that is, will be used again) at
    39 // a particular bytecode index (bci).
    38 // a particular bytecode index (bci).
    69 // 2. Instead of computing the effects of exceptions at every instruction, we
    68 // 2. Instead of computing the effects of exceptions at every instruction, we
    70 //    summarize the effects of all exceptional continuations from the block as
    69 //    summarize the effects of all exceptional continuations from the block as
    71 //    a single set (_exception_exit), losing some information but simplifying the
    70 //    a single set (_exception_exit), losing some information but simplifying the
    72 //    analysis.
    71 //    analysis.
    73 
    72 
    74 
       
    75 //--------------------------------------------------------------------------
       
    76 // The BitCounter class is used for counting the number of bits set in
       
    77 // some BitMap.  It is only used when collecting liveness statistics.
       
    78 
       
    79 #ifndef PRODUCT
       
    80 
       
    81 class BitCounter: public BitMapClosure {
       
    82  private:
       
    83   int _count;
       
    84  public:
       
    85   BitCounter() : _count(0) {}
       
    86 
       
    87   // Callback when bit in map is set
       
    88   virtual bool do_bit(size_t offset) {
       
    89     _count++;
       
    90     return true;
       
    91   }
       
    92 
       
    93   int count() {
       
    94     return _count;
       
    95   }
       
    96 };
       
    97 
       
    98 
       
    99 //--------------------------------------------------------------------------
       
   100 
       
   101 
       
   102 // Counts
       
   103 long MethodLiveness::_total_bytes = 0;
       
   104 int  MethodLiveness::_total_methods = 0;
       
   105 
       
   106 long MethodLiveness::_total_blocks = 0;
       
   107 int  MethodLiveness::_max_method_blocks = 0;
       
   108 
       
   109 long MethodLiveness::_total_edges = 0;
       
   110 int  MethodLiveness::_max_block_edges = 0;
       
   111 
       
   112 long MethodLiveness::_total_exc_edges = 0;
       
   113 int  MethodLiveness::_max_block_exc_edges = 0;
       
   114 
       
   115 long MethodLiveness::_total_method_locals = 0;
       
   116 int  MethodLiveness::_max_method_locals = 0;
       
   117 
       
   118 long MethodLiveness::_total_locals_queried = 0;
       
   119 long MethodLiveness::_total_live_locals_queried = 0;
       
   120 
       
   121 long MethodLiveness::_total_visits = 0;
       
   122 
       
   123 #endif
       
   124 
       
   125 // Timers
       
   126 elapsedTimer MethodLiveness::_time_build_graph;
       
   127 elapsedTimer MethodLiveness::_time_gen_kill;
       
   128 elapsedTimer MethodLiveness::_time_flow;
       
   129 elapsedTimer MethodLiveness::_time_query;
       
   130 elapsedTimer MethodLiveness::_time_total;
       
   131 
       
   132 MethodLiveness::MethodLiveness(Arena* arena, ciMethod* method)
    73 MethodLiveness::MethodLiveness(Arena* arena, ciMethod* method)
   133 #ifdef COMPILER1
    74 #ifdef COMPILER1
   134   : _bci_block_start(arena, method->code_size())
    75   : _bci_block_start(arena, method->code_size())
   135 #endif
    76 #endif
   136 {
    77 {
   144   if (TraceLivenessGen) {
    85   if (TraceLivenessGen) {
   145     tty->print_cr("################################################################");
    86     tty->print_cr("################################################################");
   146     tty->print("# Computing liveness information for ");
    87     tty->print("# Computing liveness information for ");
   147     method()->print_short_name();
    88     method()->print_short_name();
   148   }
    89   }
   149 
       
   150   if (TimeLivenessAnalysis) _time_total.start();
       
   151 #endif
    90 #endif
   152 
    91 
   153   {
    92   init_basic_blocks();
   154     TraceTime buildGraph(NULL, &_time_build_graph, TimeLivenessAnalysis);
    93   init_gen_kill();
   155     init_basic_blocks();
    94   propagate_liveness();
   156   }
       
   157   {
       
   158     TraceTime genKill(NULL, &_time_gen_kill, TimeLivenessAnalysis);
       
   159     init_gen_kill();
       
   160   }
       
   161   {
       
   162     TraceTime flow(NULL, &_time_flow, TimeLivenessAnalysis);
       
   163     propagate_liveness();
       
   164   }
       
   165 
       
   166 #ifndef PRODUCT
       
   167   if (TimeLivenessAnalysis) _time_total.stop();
       
   168 
       
   169   if (TimeLivenessAnalysis) {
       
   170     // Collect statistics
       
   171     _total_bytes += method()->code_size();
       
   172     _total_methods++;
       
   173 
       
   174     int num_blocks = _block_count;
       
   175     _total_blocks += num_blocks;
       
   176     _max_method_blocks = MAX2(num_blocks,_max_method_blocks);
       
   177 
       
   178     for (int i=0; i<num_blocks; i++) {
       
   179       BasicBlock *block = _block_list[i];
       
   180 
       
   181       int numEdges = block->_normal_predecessors->length();
       
   182       int numExcEdges = block->_exception_predecessors->length();
       
   183 
       
   184       _total_edges += numEdges;
       
   185       _total_exc_edges += numExcEdges;
       
   186       _max_block_edges = MAX2(numEdges,_max_block_edges);
       
   187       _max_block_exc_edges = MAX2(numExcEdges,_max_block_exc_edges);
       
   188     }
       
   189 
       
   190     int numLocals = _bit_map_size_bits;
       
   191     _total_method_locals += numLocals;
       
   192     _max_method_locals = MAX2(numLocals,_max_method_locals);
       
   193   }
       
   194 #endif
       
   195 }
    95 }
   196 
    96 
   197 
    97 
   198 void MethodLiveness::init_basic_blocks() {
    98 void MethodLiveness::init_basic_blocks() {
   199   bool bailout = false;
    99   bool bailout = false;
   471   }
   371   }
   472 
   372 
   473   MethodLivenessResult answer;
   373   MethodLivenessResult answer;
   474 
   374 
   475   if (_block_count > 0) {
   375   if (_block_count > 0) {
   476     if (TimeLivenessAnalysis) _time_total.start();
       
   477     if (TimeLivenessAnalysis) _time_query.start();
       
   478 
   376 
   479     assert( 0 <= bci && bci < method()->code_size(), "bci out of range" );
   377     assert( 0 <= bci && bci < method()->code_size(), "bci out of range" );
   480     BasicBlock *block = _block_map->at(bci);
   378     BasicBlock *block = _block_map->at(bci);
   481     // We may not be at the block start, so search backwards to find the block
   379     // We may not be at the block start, so search backwards to find the block
   482     // containing bci.
   380     // containing bci.
   499       tty->print("Liveness query of ");
   397       tty->print("Liveness query of ");
   500       method()->print_short_name();
   398       method()->print_short_name();
   501       tty->print(" @ %d : result is ", bci);
   399       tty->print(" @ %d : result is ", bci);
   502       answer.print_on(tty);
   400       answer.print_on(tty);
   503     }
   401     }
   504 
       
   505     if (TimeLivenessAnalysis) _time_query.stop();
       
   506     if (TimeLivenessAnalysis) _time_total.stop();
       
   507 #endif
   402 #endif
   508   }
   403   }
   509 
   404 
   510 #ifndef PRODUCT
       
   511   if (TimeLivenessAnalysis) {
       
   512     // Collect statistics.
       
   513     _total_locals_queried += _bit_map_size_bits;
       
   514     BitCounter counter;
       
   515     answer.iterate(&counter);
       
   516     _total_live_locals_queried += counter.count();
       
   517   }
       
   518 #endif
       
   519 
       
   520   return answer;
   405   return answer;
   521 }
   406 }
   522 
       
   523 
       
   524 #ifndef PRODUCT
       
   525 
       
   526 void MethodLiveness::print_times() {
       
   527   tty->print_cr ("Accumulated liveness analysis times/statistics:");
       
   528   tty->print_cr ("-----------------------------------------------");
       
   529   tty->print_cr ("  Total         : %3.3f sec.", _time_total.seconds());
       
   530   tty->print_cr ("    Build graph : %3.3f sec. (%2.2f%%)", _time_build_graph.seconds(),
       
   531                  _time_build_graph.seconds() * 100 / _time_total.seconds());
       
   532   tty->print_cr ("    Gen / Kill  : %3.3f sec. (%2.2f%%)", _time_gen_kill.seconds(),
       
   533                  _time_gen_kill.seconds() * 100 / _time_total.seconds());
       
   534   tty->print_cr ("    Dataflow    : %3.3f sec. (%2.2f%%)", _time_flow.seconds(),
       
   535                  _time_flow.seconds() * 100 / _time_total.seconds());
       
   536   tty->print_cr ("    Query       : %3.3f sec. (%2.2f%%)", _time_query.seconds(),
       
   537                  _time_query.seconds() * 100 / _time_total.seconds());
       
   538   tty->print_cr ("  #bytes   : %8ld (%3.0f bytes per sec)",
       
   539                  _total_bytes,
       
   540                  _total_bytes / _time_total.seconds());
       
   541   tty->print_cr ("  #methods : %8d (%3.0f methods per sec)",
       
   542                  _total_methods,
       
   543                  _total_methods / _time_total.seconds());
       
   544   tty->print_cr ("    avg locals : %3.3f    max locals : %3d",
       
   545                  (float)_total_method_locals / _total_methods,
       
   546                  _max_method_locals);
       
   547   tty->print_cr ("    avg blocks : %3.3f    max blocks : %3d",
       
   548                  (float)_total_blocks / _total_methods,
       
   549                  _max_method_blocks);
       
   550   tty->print_cr ("    avg bytes  : %3.3f",
       
   551                  (float)_total_bytes / _total_methods);
       
   552   tty->print_cr ("  #blocks  : %8ld",
       
   553                  _total_blocks);
       
   554   tty->print_cr ("    avg normal predecessors    : %3.3f  max normal predecessors    : %3d",
       
   555                  (float)_total_edges / _total_blocks,
       
   556                  _max_block_edges);
       
   557   tty->print_cr ("    avg exception predecessors : %3.3f  max exception predecessors : %3d",
       
   558                  (float)_total_exc_edges / _total_blocks,
       
   559                  _max_block_exc_edges);
       
   560   tty->print_cr ("    avg visits                 : %3.3f",
       
   561                  (float)_total_visits / _total_blocks);
       
   562   tty->print_cr ("  #locals queried : %8ld    #live : %8ld   %%live : %2.2f%%",
       
   563                  _total_locals_queried,
       
   564                  _total_live_locals_queried,
       
   565                  100.0 * _total_live_locals_queried / _total_locals_queried);
       
   566 }
       
   567 
       
   568 #endif
       
   569 
       
   570 
   407 
   571 MethodLiveness::BasicBlock::BasicBlock(MethodLiveness *analyzer, int start, int limit) :
   408 MethodLiveness::BasicBlock::BasicBlock(MethodLiveness *analyzer, int start, int limit) :
   572          _entry(analyzer->arena(),          analyzer->bit_map_size_bits()),
   409          _entry(analyzer->arena(),          analyzer->bit_map_size_bits()),
   573          _normal_exit(analyzer->arena(),    analyzer->bit_map_size_bits()),
   410          _normal_exit(analyzer->arena(),    analyzer->bit_map_size_bits()),
   574          _exception_exit(analyzer->arena(), analyzer->bit_map_size_bits()),
   411          _exception_exit(analyzer->arena(), analyzer->bit_map_size_bits()),