src/share/vm/compiler/methodLiveness.hpp

Fri, 29 Apr 2016 00:06:10 +0800

author
aoqi
date
Fri, 29 Apr 2016 00:06:10 +0800
changeset 1
2d8a650513c2
parent 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Added MIPS 64-bit port.

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #ifndef SHARE_VM_COMPILER_METHODLIVENESS_HPP
aoqi@0 26 #define SHARE_VM_COMPILER_METHODLIVENESS_HPP
aoqi@0 27
aoqi@0 28 #include "utilities/bitMap.hpp"
aoqi@0 29 #include "utilities/growableArray.hpp"
aoqi@0 30
aoqi@0 31 class ciMethod;
aoqi@0 32
aoqi@0 33 class MethodLivenessResult : public BitMap {
aoqi@0 34 private:
aoqi@0 35 bool _is_valid;
aoqi@0 36
aoqi@0 37 public:
aoqi@0 38 MethodLivenessResult(BitMap::bm_word_t* map, idx_t size_in_bits)
aoqi@0 39 : BitMap(map, size_in_bits)
aoqi@0 40 , _is_valid(false)
aoqi@0 41 {}
aoqi@0 42
aoqi@0 43 MethodLivenessResult(idx_t size_in_bits)
aoqi@0 44 : BitMap(size_in_bits)
aoqi@0 45 , _is_valid(false)
aoqi@0 46 {}
aoqi@0 47
aoqi@0 48 void set_is_valid() { _is_valid = true; }
aoqi@0 49 bool is_valid() { return _is_valid; }
aoqi@0 50 };
aoqi@0 51
aoqi@0 52 class MethodLiveness : public ResourceObj {
aoqi@0 53 public:
aoqi@0 54 // The BasicBlock class is used to represent a basic block in the
aoqi@0 55 // liveness analysis.
aoqi@0 56 class BasicBlock : public ResourceObj {
aoqi@0 57 private:
aoqi@0 58 // This class is only used by the MethodLiveness class.
aoqi@0 59 friend class MethodLiveness;
aoqi@0 60
aoqi@0 61 // The analyzer which created this basic block.
aoqi@0 62 MethodLiveness* _analyzer;
aoqi@0 63
aoqi@0 64 // The range of this basic block is [start_bci,limit_bci)
aoqi@0 65 int _start_bci;
aoqi@0 66 int _limit_bci;
aoqi@0 67
aoqi@0 68 // The liveness at the start of the block;
aoqi@0 69 BitMap _entry;
aoqi@0 70
aoqi@0 71 // The summarized liveness effects of our direct successors reached
aoqi@0 72 // by normal control flow
aoqi@0 73 BitMap _normal_exit;
aoqi@0 74
aoqi@0 75 // The summarized liveness effects of our direct successors reached
aoqi@0 76 // by exceptional control flow
aoqi@0 77 BitMap _exception_exit;
aoqi@0 78
aoqi@0 79 // These members hold the results of the last call to
aoqi@0 80 // compute_gen_kill_range(). _gen is the set of locals
aoqi@0 81 // used before they are defined in the range. _kill is the
aoqi@0 82 // set of locals defined before they are used.
aoqi@0 83 BitMap _gen;
aoqi@0 84 BitMap _kill;
aoqi@0 85 int _last_bci;
aoqi@0 86
aoqi@0 87 // A list of all blocks which could come directly before this one
aoqi@0 88 // in normal (non-exceptional) control flow. We propagate liveness
aoqi@0 89 // information to these blocks.
aoqi@0 90 GrowableArray<BasicBlock*>* _normal_predecessors;
aoqi@0 91
aoqi@0 92 // A list of all blocks which could come directly before this one
aoqi@0 93 // in exceptional control flow.
aoqi@0 94 GrowableArray<BasicBlock*>* _exception_predecessors;
aoqi@0 95
aoqi@0 96 // The following fields are used to manage a work list used in the
aoqi@0 97 // dataflow.
aoqi@0 98 BasicBlock *_next;
aoqi@0 99 bool _on_work_list;
aoqi@0 100
aoqi@0 101 // Our successors call this method to merge liveness information into
aoqi@0 102 // our _normal_exit member.
aoqi@0 103 bool merge_normal(BitMap other);
aoqi@0 104
aoqi@0 105 // Our successors call this method to merge liveness information into
aoqi@0 106 // our _exception_exit member.
aoqi@0 107 bool merge_exception(BitMap other);
aoqi@0 108
aoqi@0 109 // This helper routine is used to help compute the gen/kill pair for
aoqi@0 110 // the block. It is also used to answer queries.
aoqi@0 111 void compute_gen_kill_range(ciBytecodeStream *bytes);
aoqi@0 112
aoqi@0 113 // Compute the gen/kill effect of a single instruction.
aoqi@0 114 void compute_gen_kill_single(ciBytecodeStream *instruction);
aoqi@0 115
aoqi@0 116 // Helpers for compute_gen_kill_single.
aoqi@0 117 void load_one(int local);
aoqi@0 118 void load_two(int local);
aoqi@0 119 void store_one(int local);
aoqi@0 120 void store_two(int local);
aoqi@0 121
aoqi@0 122 BasicBlock(MethodLiveness *analyzer, int start, int limit);
aoqi@0 123
aoqi@0 124 // -- Accessors
aoqi@0 125
aoqi@0 126 int start_bci() const { return _start_bci; }
aoqi@0 127
aoqi@0 128 int limit_bci() const { return _limit_bci; }
aoqi@0 129 void set_limit_bci(int limit) { _limit_bci = limit; }
aoqi@0 130
aoqi@0 131 BasicBlock *next() const { return _next; }
aoqi@0 132 void set_next(BasicBlock *next) { _next = next; }
aoqi@0 133
aoqi@0 134 bool on_work_list() const { return _on_work_list; }
aoqi@0 135 void set_on_work_list(bool val) { _on_work_list = val; }
aoqi@0 136
aoqi@0 137 // -- Flow graph construction.
aoqi@0 138
aoqi@0 139 // Add a basic block to our list of normal predecessors.
aoqi@0 140 void add_normal_predecessor(BasicBlock *pred) {
aoqi@0 141 _normal_predecessors->append_if_missing(pred);
aoqi@0 142 }
aoqi@0 143
aoqi@0 144 // Add a basic block to our list of exceptional predecessors
aoqi@0 145 void add_exception_predecessor(BasicBlock *pred) {
aoqi@0 146 _exception_predecessors->append_if_missing(pred);
aoqi@0 147 }
aoqi@0 148
aoqi@0 149 // Split the basic block at splitBci. This basic block
aoqi@0 150 // becomes the second half. The first half is newly created.
aoqi@0 151 BasicBlock *split(int splitBci);
aoqi@0 152
aoqi@0 153 // -- Dataflow.
aoqi@0 154
aoqi@0 155 void compute_gen_kill(ciMethod* method);
aoqi@0 156
aoqi@0 157 // Propagate changes from this basic block
aoqi@0 158 void propagate(MethodLiveness *ml);
aoqi@0 159
aoqi@0 160 // -- Query.
aoqi@0 161
aoqi@0 162 MethodLivenessResult get_liveness_at(ciMethod* method, int bci);
aoqi@0 163
aoqi@0 164 // -- Debugging.
aoqi@0 165
aoqi@0 166 void print_on(outputStream *os) const PRODUCT_RETURN;
aoqi@0 167
aoqi@0 168 }; // End of MethodLiveness::BasicBlock
aoqi@0 169
aoqi@0 170 private:
aoqi@0 171 // The method we are analyzing.
aoqi@0 172 ciMethod* _method;
aoqi@0 173 ciMethod* method() const { return _method; }
aoqi@0 174
aoqi@0 175 // The arena for storing structures...
aoqi@0 176 Arena* _arena;
aoqi@0 177 Arena* arena() const { return _arena; }
aoqi@0 178
aoqi@0 179 // We cache the length of the method.
aoqi@0 180 int _code_size;
aoqi@0 181
aoqi@0 182 // The size of a BitMap.
aoqi@0 183 int _bit_map_size_bits;
aoqi@0 184 int _bit_map_size_words;
aoqi@0 185
aoqi@0 186 // A list of all BasicBlocks.
aoqi@0 187 BasicBlock **_block_list;
aoqi@0 188
aoqi@0 189 // number of blocks
aoqi@0 190 int _block_count;
aoqi@0 191
aoqi@0 192 // Keeps track of bci->block mapping. One entry for each bci. Only block starts are
aoqi@0 193 // recorded.
aoqi@0 194 GrowableArray<BasicBlock*>* _block_map;
aoqi@0 195
aoqi@0 196 // Our work list.
aoqi@0 197 BasicBlock *_work_list;
aoqi@0 198
aoqi@0 199 #ifdef COMPILER1
aoqi@0 200 // bcis where blocks start are marked
aoqi@0 201 BitMap _bci_block_start;
aoqi@0 202 #endif // COMPILER1
aoqi@0 203
aoqi@0 204 // -- Graph construction & Analysis
aoqi@0 205
aoqi@0 206 // Compute ranges and predecessors for basic blocks.
aoqi@0 207 void init_basic_blocks();
aoqi@0 208
aoqi@0 209 // Compute gen/kill information for all basic blocks.
aoqi@0 210 void init_gen_kill();
aoqi@0 211
aoqi@0 212 // Perform the dataflow.
aoqi@0 213 void propagate_liveness();
aoqi@0 214
aoqi@0 215 // The class MethodLiveness::BasicBlock needs special access to some
aoqi@0 216 // of our members.
aoqi@0 217 friend class MethodLiveness::BasicBlock;
aoqi@0 218
aoqi@0 219 // And accessors.
aoqi@0 220 int bit_map_size_bits() const { return _bit_map_size_bits; }
aoqi@0 221 int bit_map_size_words() const { return _bit_map_size_words; }
aoqi@0 222
aoqi@0 223 // Work list manipulation routines. Called internally by BasicBlock.
aoqi@0 224 BasicBlock *work_list_get();
aoqi@0 225 void work_list_add(BasicBlock *block);
aoqi@0 226
aoqi@0 227 // -- Timing and Statistics.
aoqi@0 228
aoqi@0 229
aoqi@0 230 // Timers
aoqi@0 231 static elapsedTimer _time_build_graph;
aoqi@0 232 static elapsedTimer _time_gen_kill;
aoqi@0 233 static elapsedTimer _time_flow;
aoqi@0 234 static elapsedTimer _time_query;
aoqi@0 235 static elapsedTimer _time_total;
aoqi@0 236
aoqi@0 237 #ifndef PRODUCT
aoqi@0 238
aoqi@0 239 // Counts
aoqi@0 240 static long _total_bytes;
aoqi@0 241 static int _total_methods;
aoqi@0 242
aoqi@0 243 static long _total_blocks;
aoqi@0 244 static int _max_method_blocks;
aoqi@0 245
aoqi@0 246 static long _total_edges;
aoqi@0 247 static int _max_block_edges;
aoqi@0 248
aoqi@0 249 static long _total_exc_edges;
aoqi@0 250 static int _max_block_exc_edges;
aoqi@0 251
aoqi@0 252 static long _total_method_locals;
aoqi@0 253 static int _max_method_locals;
aoqi@0 254
aoqi@0 255 static long _total_locals_queried;
aoqi@0 256 static long _total_live_locals_queried;
aoqi@0 257
aoqi@0 258 static long _total_visits;
aoqi@0 259
aoqi@0 260 #endif
aoqi@0 261
aoqi@0 262 public:
aoqi@0 263 // Create a liveness analyzer for a method
aoqi@0 264 MethodLiveness(Arena* arena, ciMethod* method);
aoqi@0 265
aoqi@0 266 // Compute liveness information for the method
aoqi@0 267 void compute_liveness();
aoqi@0 268
aoqi@0 269 // Find out which locals are live at a specific bci.
aoqi@0 270 MethodLivenessResult get_liveness_at(int bci);
aoqi@0 271
aoqi@0 272 #ifdef COMPILER1
aoqi@0 273 const BitMap get_bci_block_start() const { return _bci_block_start; }
aoqi@0 274 #endif // COMPILER1
aoqi@0 275
aoqi@0 276 static void print_times() PRODUCT_RETURN;
aoqi@0 277 };
aoqi@0 278
aoqi@0 279 #endif // SHARE_VM_COMPILER_METHODLIVENESS_HPP

mercurial