1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/opto/output.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,215 @@ 1.4 +/* 1.5 + * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +class Arena; 1.29 +class Bundle; 1.30 +class Block; 1.31 +class Block_Array; 1.32 +class Node; 1.33 +class Node_Array; 1.34 +class Node_List; 1.35 +class PhaseCFG; 1.36 +class PhaseChaitin; 1.37 +class Pipeline_Use_Element; 1.38 +class Pipeline_Use; 1.39 + 1.40 +#ifndef PRODUCT 1.41 +#define DEBUG_ARG(x) , x 1.42 +#else 1.43 +#define DEBUG_ARG(x) 1.44 +#endif 1.45 + 1.46 +// Define the initial sizes for allocation of the resizable code buffer 1.47 +enum { 1.48 + initial_code_capacity = 16 * 1024, 1.49 + initial_stub_capacity = 4 * 1024, 1.50 + initial_const_capacity = 4 * 1024, 1.51 + initial_locs_capacity = 3 * 1024 1.52 +}; 1.53 + 1.54 +//------------------------------Scheduling---------------------------------- 1.55 +// This class contains all the information necessary to implement instruction 1.56 +// scheduling and bundling. 1.57 +class Scheduling { 1.58 + 1.59 +private: 1.60 + // Arena to use 1.61 + Arena *_arena; 1.62 + 1.63 + // Control-Flow Graph info 1.64 + PhaseCFG *_cfg; 1.65 + 1.66 + // Register Allocation info 1.67 + PhaseRegAlloc *_regalloc; 1.68 + 1.69 + // Number of nodes in the method 1.70 + uint _node_bundling_limit; 1.71 + 1.72 + // List of scheduled nodes. Generated in reverse order 1.73 + Node_List _scheduled; 1.74 + 1.75 + // List of nodes currently available for choosing for scheduling 1.76 + Node_List _available; 1.77 + 1.78 + // Mapping from node (index) to basic block 1.79 + Block_Array& _bbs; 1.80 + 1.81 + // For each instruction beginning a bundle, the number of following 1.82 + // nodes to be bundled with it. 1.83 + Bundle *_node_bundling_base; 1.84 + 1.85 + // Mapping from register to Node 1.86 + Node_List _reg_node; 1.87 + 1.88 + // Free list for pinch nodes. 1.89 + Node_List _pinch_free_list; 1.90 + 1.91 + // Latency from the beginning of the containing basic block (base 1) 1.92 + // for each node. 1.93 + unsigned short *_node_latency; 1.94 + 1.95 + // Number of uses of this node within the containing basic block. 1.96 + short *_uses; 1.97 + 1.98 + // Schedulable portion of current block. Skips Region/Phi/CreateEx up 1.99 + // front, branch+proj at end. Also skips Catch/CProj (same as 1.100 + // branch-at-end), plus just-prior exception-throwing call. 1.101 + uint _bb_start, _bb_end; 1.102 + 1.103 + // Latency from the end of the basic block as scheduled 1.104 + unsigned short *_current_latency; 1.105 + 1.106 + // Remember the next node 1.107 + Node *_next_node; 1.108 + 1.109 + // Use this for an unconditional branch delay slot 1.110 + Node *_unconditional_delay_slot; 1.111 + 1.112 + // Pointer to a Nop 1.113 + MachNopNode *_nop; 1.114 + 1.115 + // Length of the current bundle, in instructions 1.116 + uint _bundle_instr_count; 1.117 + 1.118 + // Current Cycle number, for computing latencies and bundling 1.119 + uint _bundle_cycle_number; 1.120 + 1.121 + // Bundle information 1.122 + Pipeline_Use_Element _bundle_use_elements[resource_count]; 1.123 + Pipeline_Use _bundle_use; 1.124 + 1.125 + // Dump the available list 1.126 + void dump_available() const; 1.127 + 1.128 +public: 1.129 + Scheduling(Arena *arena, Compile &compile); 1.130 + 1.131 + // Destructor 1.132 + NOT_PRODUCT( ~Scheduling(); ) 1.133 + 1.134 + // Step ahead "i" cycles 1.135 + void step(uint i); 1.136 + 1.137 + // Step ahead 1 cycle, and clear the bundle state (for example, 1.138 + // at a branch target) 1.139 + void step_and_clear(); 1.140 + 1.141 + Bundle* node_bundling(const Node *n) { 1.142 + assert(valid_bundle_info(n), "oob"); 1.143 + return (&_node_bundling_base[n->_idx]); 1.144 + } 1.145 + 1.146 + bool valid_bundle_info(const Node *n) const { 1.147 + return (_node_bundling_limit > n->_idx); 1.148 + } 1.149 + 1.150 + bool starts_bundle(const Node *n) const { 1.151 + return (_node_bundling_limit > n->_idx && _node_bundling_base[n->_idx].starts_bundle()); 1.152 + } 1.153 + 1.154 + // Do the scheduling 1.155 + void DoScheduling(); 1.156 + 1.157 + // Compute the local latencies walking forward over the list of 1.158 + // nodes for a basic block 1.159 + void ComputeLocalLatenciesForward(const Block *bb); 1.160 + 1.161 + // Compute the register antidependencies within a basic block 1.162 + void ComputeRegisterAntidependencies(Block *bb); 1.163 + void verify_do_def( Node *n, OptoReg::Name def, const char *msg ); 1.164 + void verify_good_schedule( Block *b, const char *msg ); 1.165 + void anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is_def ); 1.166 + void anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ); 1.167 + 1.168 + // Add a node to the current bundle 1.169 + void AddNodeToBundle(Node *n, const Block *bb); 1.170 + 1.171 + // Add a node to the list of available nodes 1.172 + void AddNodeToAvailableList(Node *n); 1.173 + 1.174 + // Compute the local use count for the nodes in a block, and compute 1.175 + // the list of instructions with no uses in the block as available 1.176 + void ComputeUseCount(const Block *bb); 1.177 + 1.178 + // Choose an instruction from the available list to add to the bundle 1.179 + Node * ChooseNodeToBundle(); 1.180 + 1.181 + // See if this Node fits into the currently accumulating bundle 1.182 + bool NodeFitsInBundle(Node *n); 1.183 + 1.184 + // Decrement the use count for a node 1.185 + void DecrementUseCounts(Node *n, const Block *bb); 1.186 + 1.187 + // Garbage collect pinch nodes for reuse by other blocks. 1.188 + void garbage_collect_pinch_nodes(); 1.189 + // Clean up a pinch node for reuse (helper for above). 1.190 + void cleanup_pinch( Node *pinch ); 1.191 + 1.192 + // Information for statistics gathering 1.193 +#ifndef PRODUCT 1.194 +private: 1.195 + // Gather information on size of nops relative to total 1.196 + uint _branches, _unconditional_delays; 1.197 + 1.198 + static uint _total_nop_size, _total_method_size; 1.199 + static uint _total_branches, _total_unconditional_delays; 1.200 + static uint _total_instructions_per_bundle[Pipeline::_max_instrs_per_cycle+1]; 1.201 + 1.202 +public: 1.203 + static void print_statistics(); 1.204 + 1.205 + static void increment_instructions_per_bundle(uint i) { 1.206 + _total_instructions_per_bundle[i]++; 1.207 + } 1.208 + 1.209 + static void increment_nop_size(uint s) { 1.210 + _total_nop_size += s; 1.211 + } 1.212 + 1.213 + static void increment_method_size(uint s) { 1.214 + _total_method_size += s; 1.215 + } 1.216 +#endif 1.217 + 1.218 +};