1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/opto/optoreg.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,194 @@ 1.4 +/* 1.5 + * Copyright 2006-2007 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 +//------------------------------OptoReg---------------------------------------- 1.29 +// We eventually need Registers for the Real World. Registers are essentially 1.30 +// non-SSA names. A Register is represented as a number. Non-regular values 1.31 +// (e.g., Control, Memory, I/O) use the Special register. The actual machine 1.32 +// registers (as described in the ADL file for a machine) start at zero. 1.33 +// Stack-slots (spill locations) start at the nest Chunk past the last machine 1.34 +// register. 1.35 +// 1.36 +// Note that stack spill-slots are treated as a very large register set. 1.37 +// They have all the correct properties for a Register: not aliased (unique 1.38 +// named). There is some simple mapping from a stack-slot register number 1.39 +// to the actual location on the stack; this mapping depends on the calling 1.40 +// conventions and is described in the ADL. 1.41 +// 1.42 +// Note that Name is not enum. C++ standard defines that the range of enum 1.43 +// is the range of smallest bit-field that can represent all enumerators 1.44 +// declared in the enum. The result of assigning a value to enum is undefined 1.45 +// if the value is outside the enumeration's valid range. OptoReg::Name is 1.46 +// typedef'ed as int, because it needs to be able to represent spill-slots. 1.47 +// 1.48 +class OptoReg VALUE_OBJ_CLASS_SPEC { 1.49 + 1.50 + friend class C2Compiler; 1.51 + public: 1.52 + typedef int Name; 1.53 + enum { 1.54 + // Chunk 0 1.55 + Physical = AdlcVMDeps::Physical, // Start of physical regs 1.56 + // A few oddballs at the edge of the world 1.57 + Special = -2, // All special (not allocated) values 1.58 + Bad = -1 // Not a register 1.59 + }; 1.60 + 1.61 + private: 1.62 + 1.63 + static const VMReg opto2vm[REG_COUNT]; 1.64 + static Name vm2opto[ConcreteRegisterImpl::number_of_registers]; 1.65 + 1.66 + public: 1.67 + 1.68 + // Stack pointer register 1.69 + static OptoReg::Name c_frame_pointer; 1.70 + 1.71 + 1.72 + 1.73 + // Increment a register number. As in: 1.74 + // "for ( OptoReg::Name i; i=Control; i = add(i,1) ) ..." 1.75 + static Name add( Name x, int y ) { return Name(x+y); } 1.76 + 1.77 + // (We would like to have an operator+ for RegName, but it is not 1.78 + // a class, so this would be illegal in C++.) 1.79 + 1.80 + static void dump( int ); 1.81 + 1.82 + // Get the stack slot number of an OptoReg::Name 1.83 + static unsigned int reg2stack( OptoReg::Name r) { 1.84 + assert( r >= stack0(), " must be"); 1.85 + return r - stack0(); 1.86 + } 1.87 + 1.88 + // convert a stack slot number into an OptoReg::Name 1.89 + static OptoReg::Name stack2reg( int idx) { 1.90 + return Name(stack0() + idx); 1.91 + } 1.92 + 1.93 + static bool is_stack(Name n) { 1.94 + return n >= stack0(); 1.95 + } 1.96 + 1.97 + static bool is_valid(Name n) { 1.98 + return (n != Bad); 1.99 + } 1.100 + 1.101 + static bool is_reg(Name n) { 1.102 + return is_valid(n) && !is_stack(n); 1.103 + } 1.104 + 1.105 + static VMReg as_VMReg(OptoReg::Name n) { 1.106 + if (is_reg(n)) { 1.107 + // Must use table, it'd be nice if Bad was indexable... 1.108 + return opto2vm[n]; 1.109 + } else { 1.110 + assert(!is_stack(n), "must un warp"); 1.111 + return VMRegImpl::Bad(); 1.112 + } 1.113 + } 1.114 + 1.115 + // Can un-warp a stack slot or convert a register or Bad 1.116 + static VMReg as_VMReg(OptoReg::Name n, int frame_size, int arg_count) { 1.117 + if (is_reg(n)) { 1.118 + // Must use table, it'd be nice if Bad was indexable... 1.119 + return opto2vm[n]; 1.120 + } else if (is_stack(n)) { 1.121 + int stack_slot = reg2stack(n); 1.122 + if (stack_slot < arg_count) { 1.123 + return VMRegImpl::stack2reg(stack_slot + frame_size); 1.124 + } 1.125 + return VMRegImpl::stack2reg(stack_slot - arg_count); 1.126 + // return return VMRegImpl::stack2reg(reg2stack(OptoReg::add(n, -arg_count))); 1.127 + } else { 1.128 + return VMRegImpl::Bad(); 1.129 + } 1.130 + } 1.131 + 1.132 + static OptoReg::Name as_OptoReg(VMReg r) { 1.133 + if (r->is_stack()) { 1.134 + assert(false, "must warp"); 1.135 + return stack2reg(r->reg2stack()); 1.136 + } else if (r->is_valid()) { 1.137 + // Must use table, it'd be nice if Bad was indexable... 1.138 + return vm2opto[r->value()]; 1.139 + } else { 1.140 + return Bad; 1.141 + } 1.142 + } 1.143 + 1.144 + static OptoReg::Name stack0() { 1.145 + return VMRegImpl::stack0->value(); 1.146 + } 1.147 + 1.148 + static const char* regname(OptoReg::Name n) { 1.149 + return as_VMReg(n)->name(); 1.150 + } 1.151 + 1.152 +}; 1.153 + 1.154 +//---------------------------OptoRegPair------------------------------------------- 1.155 +// Pairs of 32-bit registers for the allocator. 1.156 +// This is a very similar class to VMRegPair. C2 only interfaces with VMRegPair 1.157 +// via the calling convention code which is shared between the compilers. 1.158 +// Since C2 uses OptoRegs for register allocation it is more efficient to use 1.159 +// VMRegPair internally for nodes that can contain a pair of OptoRegs rather 1.160 +// than use VMRegPair and continually be converting back and forth. So normally 1.161 +// C2 will take in a VMRegPair from the calling convention code and immediately 1.162 +// convert them to an OptoRegPair and stay in the OptoReg world. The only over 1.163 +// conversion between OptoRegs and VMRegs is for debug info and oopMaps. This 1.164 +// is not a high bandwidth spot and so it is not an issue. 1.165 +// Note that onde other consequence of staying in the OptoReg world with OptoRegPairs 1.166 +// is that there are "physical" OptoRegs that are not representable in the VMReg 1.167 +// world, notably flags. [ But by design there is "space" in the VMReg world 1.168 +// for such registers they just may not be concrete ]. So if we were to use VMRegPair 1.169 +// then the VMReg world would have to have a representation for these registers 1.170 +// so that a OptoReg->VMReg->OptoReg would reproduce ther original OptoReg. As it 1.171 +// stands if you convert a flag (condition code) to a VMReg you will get VMRegImpl::Bad 1.172 +// and converting that will return OptoReg::Bad losing the identity of the OptoReg. 1.173 + 1.174 +class OptoRegPair { 1.175 +private: 1.176 + short _second; 1.177 + short _first; 1.178 +public: 1.179 + void set_bad ( ) { _second = OptoReg::Bad; _first = OptoReg::Bad; } 1.180 + void set1 ( OptoReg::Name n ) { _second = OptoReg::Bad; _first = n; } 1.181 + void set2 ( OptoReg::Name n ) { _second = n + 1; _first = n; } 1.182 + void set_pair( OptoReg::Name second, OptoReg::Name first ) { _second= second; _first= first; } 1.183 + void set_ptr ( OptoReg::Name ptr ) { 1.184 +#ifdef _LP64 1.185 + _second = ptr+1; 1.186 +#else 1.187 + _second = OptoReg::Bad; 1.188 +#endif 1.189 + _first = ptr; 1.190 + } 1.191 + 1.192 + OptoReg::Name second() const { return _second; } 1.193 + OptoReg::Name first() const { return _first; } 1.194 + OptoRegPair(OptoReg::Name second, OptoReg::Name first) { _second = second; _first = first; } 1.195 + OptoRegPair(OptoReg::Name f) { _second = OptoReg::Bad; _first = f; } 1.196 + OptoRegPair() { _second = OptoReg::Bad; _first = OptoReg::Bad; } 1.197 +};