src/share/vm/compiler/methodLiveness.hpp

Wed, 11 Aug 2010 05:51:21 -0700

author
twisti
date
Wed, 11 Aug 2010 05:51:21 -0700
changeset 2047
d2ede61b7a12
parent 1907
c18cbe5936b8
child 2314
f95d63e2154a
permissions
-rw-r--r--

6976186: integrate Shark HotSpot changes
Summary: Shark is a JIT compiler for Zero that uses the LLVM compiler infrastructure.
Reviewed-by: kvn, twisti
Contributed-by: Gary Benson <gbenson@redhat.com>

     1 /*
     2  * Copyright (c) 1998, 2006, 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 class ciMethod;
    27 class MethodLivenessResult : public BitMap {
    28  private:
    29   bool _is_valid;
    31  public:
    32   MethodLivenessResult(BitMap::bm_word_t* map, idx_t size_in_bits)
    33     : BitMap(map, size_in_bits)
    34     , _is_valid(false)
    35   {}
    37   MethodLivenessResult(idx_t size_in_bits)
    38     : BitMap(size_in_bits)
    39     , _is_valid(false)
    40   {}
    42   void set_is_valid() { _is_valid = true; }
    43   bool is_valid() { return _is_valid; }
    44 };
    46 class MethodLiveness : public ResourceObj {
    47  public:
    48   // The BasicBlock class is used to represent a basic block in the
    49   // liveness analysis.
    50   class BasicBlock : public ResourceObj {
    51    private:
    52     // This class is only used by the MethodLiveness class.
    53     friend class MethodLiveness;
    55     // The analyzer which created this basic block.
    56     MethodLiveness* _analyzer;
    58     // The range of this basic block is [start_bci,limit_bci)
    59     int _start_bci;
    60     int _limit_bci;
    62     // The liveness at the start of the block;
    63     BitMap _entry;
    65     // The summarized liveness effects of our direct successors reached
    66     // by normal control flow
    67     BitMap _normal_exit;
    69     // The summarized liveness effects of our direct successors reached
    70     // by exceptional control flow
    71     BitMap _exception_exit;
    73     // These members hold the results of the last call to
    74     // compute_gen_kill_range().  _gen is the set of locals
    75     // used before they are defined in the range.  _kill is the
    76     // set of locals defined before they are used.
    77     BitMap _gen;
    78     BitMap _kill;
    79     int    _last_bci;
    81     // A list of all blocks which could come directly before this one
    82     // in normal (non-exceptional) control flow.  We propagate liveness
    83     // information to these blocks.
    84     GrowableArray<BasicBlock*>* _normal_predecessors;
    86     // A list of all blocks which could come directly before this one
    87     // in exceptional control flow.
    88     GrowableArray<BasicBlock*>* _exception_predecessors;
    90     // The following fields are used to manage a work list used in the
    91     // dataflow.
    92     BasicBlock *_next;
    93     bool _on_work_list;
    95     // Our successors call this method to merge liveness information into
    96     // our _normal_exit member.
    97     bool merge_normal(BitMap other);
    99     // Our successors call this method to merge liveness information into
   100     // our _exception_exit member.
   101     bool merge_exception(BitMap other);
   103     // This helper routine is used to help compute the gen/kill pair for
   104     // the block.  It is also used to answer queries.
   105     void compute_gen_kill_range(ciBytecodeStream *bytes);
   107     // Compute the gen/kill effect of a single instruction.
   108     void compute_gen_kill_single(ciBytecodeStream *instruction);
   110     // Helpers for compute_gen_kill_single.
   111     void load_one(int local);
   112     void load_two(int local);
   113     void store_one(int local);
   114     void store_two(int local);
   116     BasicBlock(MethodLiveness *analyzer, int start, int limit);
   118     // -- Accessors
   120     int start_bci() const { return _start_bci; }
   122     int limit_bci() const { return _limit_bci; }
   123     void set_limit_bci(int limit) { _limit_bci = limit; }
   125     BasicBlock *next() const { return _next; }
   126     void set_next(BasicBlock *next) { _next = next; }
   128     bool on_work_list() const { return _on_work_list; }
   129     void set_on_work_list(bool val) { _on_work_list = val; }
   131     // -- Flow graph construction.
   133     // Add a basic block to our list of normal predecessors.
   134     void add_normal_predecessor(BasicBlock *pred) {
   135       _normal_predecessors->append_if_missing(pred);
   136     }
   138     // Add a basic block to our list of exceptional predecessors
   139     void add_exception_predecessor(BasicBlock *pred) {
   140       _exception_predecessors->append_if_missing(pred);
   141     }
   143     // Split the basic block at splitBci.  This basic block
   144     // becomes the second half.  The first half is newly created.
   145     BasicBlock *split(int splitBci);
   147     // -- Dataflow.
   149     void compute_gen_kill(ciMethod* method);
   151     // Propagate changes from this basic block
   152     void propagate(MethodLiveness *ml);
   154     // -- Query.
   156     MethodLivenessResult get_liveness_at(ciMethod* method, int bci);
   158     // -- Debugging.
   160     void print_on(outputStream *os) const PRODUCT_RETURN;
   162   }; // End of MethodLiveness::BasicBlock
   164  private:
   165   // The method we are analyzing.
   166   ciMethod* _method;
   167   ciMethod* method() const { return _method; }
   169   // The arena for storing structures...
   170   Arena*       _arena;
   171   Arena*       arena() const { return _arena; }
   173   // We cache the length of the method.
   174   int _code_size;
   176   // The size of a BitMap.
   177   int _bit_map_size_bits;
   178   int _bit_map_size_words;
   180   // A list of all BasicBlocks.
   181   BasicBlock **_block_list;
   183   // number of blocks
   184   int  _block_count;
   186   // Keeps track of bci->block mapping.  One entry for each bci.  Only block starts are
   187   // recorded.
   188   GrowableArray<BasicBlock*>* _block_map;
   190   // Our work list.
   191   BasicBlock *_work_list;
   193 #ifdef COMPILER1
   194   // bcis where blocks start are marked
   195   BitMap _bci_block_start;
   196 #endif // COMPILER1
   198   // -- Graph construction & Analysis
   200   // Compute ranges and predecessors for basic blocks.
   201   void init_basic_blocks();
   203   // Compute gen/kill information for all basic blocks.
   204   void init_gen_kill();
   206   // Perform the dataflow.
   207   void propagate_liveness();
   209  // The class MethodLiveness::BasicBlock needs special access to some
   210  // of our members.
   211  friend class MethodLiveness::BasicBlock;
   213   // And accessors.
   214   int bit_map_size_bits() const { return _bit_map_size_bits; }
   215   int bit_map_size_words() const { return _bit_map_size_words; }
   217   // Work list manipulation routines.  Called internally by BasicBlock.
   218   BasicBlock *work_list_get();
   219   void work_list_add(BasicBlock *block);
   221   // -- Timing and Statistics.
   224   // Timers
   225   static elapsedTimer _time_build_graph;
   226   static elapsedTimer _time_gen_kill;
   227   static elapsedTimer _time_flow;
   228   static elapsedTimer _time_query;
   229   static elapsedTimer _time_total;
   231 #ifndef PRODUCT
   233   // Counts
   234   static long _total_bytes;
   235   static int  _total_methods;
   237   static long _total_blocks;
   238   static int  _max_method_blocks;
   240   static long _total_edges;
   241   static int  _max_block_edges;
   243   static long _total_exc_edges;
   244   static int  _max_block_exc_edges;
   246   static long _total_method_locals;
   247   static int  _max_method_locals;
   249   static long _total_locals_queried;
   250   static long _total_live_locals_queried;
   252   static long _total_visits;
   254 #endif
   256  public:
   257   // Create a liveness analyzer for a method
   258   MethodLiveness(Arena* arena, ciMethod* method);
   260   // Compute liveness information for the method
   261   void compute_liveness();
   263   // Find out which locals are live at a specific bci.
   264   MethodLivenessResult get_liveness_at(int bci);
   266 #ifdef COMPILER1
   267   const BitMap get_bci_block_start() const { return _bci_block_start; }
   268 #endif // COMPILER1
   270   static void print_times() PRODUCT_RETURN;
   271 };

mercurial