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