duke@435: /* duke@435: * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: // Some fun naming (textual) substitutions: duke@435: // duke@435: // RegMask::get_low_elem() ==> RegMask::find_first_elem() duke@435: // RegMask::Special ==> RegMask::Empty duke@435: // RegMask::_flags ==> RegMask::is_AllStack() duke@435: // RegMask::operator<<=() ==> RegMask::Insert() duke@435: // RegMask::operator>>=() ==> RegMask::Remove() duke@435: // RegMask::Union() ==> RegMask::OR duke@435: // RegMask::Inter() ==> RegMask::AND duke@435: // duke@435: // OptoRegister::RegName ==> OptoReg::Name duke@435: // duke@435: // OptoReg::stack0() ==> _last_Mach_Reg or ZERO in core version duke@435: // duke@435: // numregs in chaitin ==> proper degree in chaitin duke@435: duke@435: //-------------Non-zero bit search methods used by RegMask--------------------- duke@435: // Find lowest 1, or return 32 if empty duke@435: int find_lowest_bit( uint32 mask ); duke@435: // Find highest 1, or return 32 if empty duke@435: int find_hihghest_bit( uint32 mask ); duke@435: duke@435: //------------------------------RegMask---------------------------------------- duke@435: // The ADL file describes how to print the machine-specific registers, as well duke@435: // as any notion of register classes. We provide a register mask, which is duke@435: // just a collection of Register numbers. duke@435: duke@435: // The ADLC defines 2 macros, RM_SIZE and FORALL_BODY. duke@435: // RM_SIZE is the size of a register mask in words. duke@435: // FORALL_BODY replicates a BODY macro once per word in the register mask. duke@435: // The usage is somewhat clumsy and limited to the regmask.[h,c]pp files. duke@435: // However, it means the ADLC can redefine the unroll macro and all loops duke@435: // over register masks will be unrolled by the correct amount. duke@435: duke@435: class RegMask VALUE_OBJ_CLASS_SPEC { duke@435: union { duke@435: double _dummy_force_double_alignment[RM_SIZE>>1]; duke@435: // Array of Register Mask bits. This array is large enough to cover duke@435: // all the machine registers and all parameters that need to be passed duke@435: // on the stack (stack registers) up to some interesting limit. Methods duke@435: // that need more parameters will NOT be compiled. On Intel, the limit duke@435: // is something like 90+ parameters. duke@435: int _A[RM_SIZE]; duke@435: }; duke@435: duke@435: enum { duke@435: _WordBits = BitsPerInt, duke@435: _LogWordBits = LogBitsPerInt, duke@435: _RM_SIZE = RM_SIZE // local constant, imported, then hidden by #undef duke@435: }; duke@435: duke@435: public: duke@435: enum { CHUNK_SIZE = RM_SIZE*_WordBits }; duke@435: duke@435: // SlotsPerLong is 2, since slots are 32 bits and longs are 64 bits. duke@435: // Also, consider the maximum alignment size for a normally allocated duke@435: // value. Since we allocate register pairs but not register quads (at duke@435: // present), this alignment is SlotsPerLong (== 2). A normally duke@435: // aligned allocated register is either a single register, or a pair duke@435: // of adjacent registers, the lower-numbered being even. duke@435: // See also is_aligned_Pairs() below, and the padding added before duke@435: // Matcher::_new_SP to keep allocated pairs aligned properly. duke@435: // If we ever go to quad-word allocations, SlotsPerQuad will become duke@435: // the controlling alignment constraint. Note that this alignment duke@435: // requirement is internal to the allocator, and independent of any duke@435: // particular platform. duke@435: enum { SlotsPerLong = 2 }; duke@435: duke@435: // A constructor only used by the ADLC output. All mask fields are filled duke@435: // in directly. Calls to this look something like RM(1,2,3,4); duke@435: RegMask( duke@435: # define BODY(I) int a##I, duke@435: FORALL_BODY duke@435: # undef BODY duke@435: int dummy = 0 ) { duke@435: # define BODY(I) _A[I] = a##I; duke@435: FORALL_BODY duke@435: # undef BODY duke@435: } duke@435: duke@435: // Handy copying constructor duke@435: RegMask( RegMask *rm ) { duke@435: # define BODY(I) _A[I] = rm->_A[I]; duke@435: FORALL_BODY duke@435: # undef BODY duke@435: } duke@435: duke@435: // Construct an empty mask duke@435: RegMask( ) { Clear(); } duke@435: duke@435: // Construct a mask with a single bit duke@435: RegMask( OptoReg::Name reg ) { Clear(); Insert(reg); } duke@435: duke@435: // Check for register being in mask duke@435: int Member( OptoReg::Name reg ) const { duke@435: assert( reg < CHUNK_SIZE, "" ); duke@435: return _A[reg>>_LogWordBits] & (1<<(reg&(_WordBits-1))); duke@435: } duke@435: duke@435: // The last bit in the register mask indicates that the mask should repeat duke@435: // indefinitely with ONE bits. Returns TRUE if mask is infinite or duke@435: // unbounded in size. Returns FALSE if mask is finite size. duke@435: int is_AllStack() const { return _A[RM_SIZE-1] >> (_WordBits-1); } duke@435: duke@435: // Work around an -xO3 optimization problme in WS6U1. The old way: duke@435: // void set_AllStack() { _A[RM_SIZE-1] |= (1<<(_WordBits-1)); } duke@435: // will cause _A[RM_SIZE-1] to be clobbered, not updated when set_AllStack() duke@435: // follows an Insert() loop, like the one found in init_spill_mask(). Using duke@435: // Insert() instead works because the index into _A in computed instead of duke@435: // constant. See bug 4665841. duke@435: void set_AllStack() { Insert(OptoReg::Name(CHUNK_SIZE-1)); } duke@435: duke@435: // Test for being a not-empty mask. duke@435: int is_NotEmpty( ) const { duke@435: int tmp = 0; duke@435: # define BODY(I) tmp |= _A[I]; duke@435: FORALL_BODY duke@435: # undef BODY duke@435: return tmp; duke@435: } duke@435: duke@435: // Find lowest-numbered register from mask, or BAD if mask is empty. duke@435: OptoReg::Name find_first_elem() const { duke@435: int base, bits; duke@435: # define BODY(I) if( (bits = _A[I]) != 0 ) base = I<<_LogWordBits; else duke@435: FORALL_BODY duke@435: # undef BODY duke@435: { base = OptoReg::Bad; bits = 1<<0; } duke@435: return OptoReg::Name(base + find_lowest_bit(bits)); duke@435: } duke@435: // Get highest-numbered register from mask, or BAD if mask is empty. duke@435: OptoReg::Name find_last_elem() const { duke@435: int base, bits; duke@435: # define BODY(I) if( (bits = _A[RM_SIZE-1-I]) != 0 ) base = (RM_SIZE-1-I)<<_LogWordBits; else duke@435: FORALL_BODY duke@435: # undef BODY duke@435: { base = OptoReg::Bad; bits = 1<<0; } duke@435: return OptoReg::Name(base + find_hihghest_bit(bits)); duke@435: } duke@435: duke@435: // Find the lowest-numbered register pair in the mask. Return the duke@435: // HIGHEST register number in the pair, or BAD if no pairs. duke@435: // Assert that the mask contains only bit pairs. duke@435: OptoReg::Name find_first_pair() const; duke@435: duke@435: // Clear out partial bits; leave only aligned adjacent bit pairs. duke@435: void ClearToPairs(); duke@435: // Smear out partial bits; leave only aligned adjacent bit pairs. duke@435: void SmearToPairs(); duke@435: // Verify that the mask contains only aligned adjacent bit pairs duke@435: void VerifyPairs() const { assert( is_aligned_Pairs(), "mask is not aligned, adjacent pairs" ); } duke@435: // Test that the mask contains only aligned adjacent bit pairs duke@435: bool is_aligned_Pairs() const; duke@435: duke@435: // mask is a pair of misaligned registers duke@435: bool is_misaligned_Pair() const { return Size()==2 && !is_aligned_Pairs();} duke@435: // Test for single register duke@435: int is_bound1() const; duke@435: // Test for a single adjacent pair duke@435: int is_bound2() const; duke@435: duke@435: // Fast overlap test. Non-zero if any registers in common. duke@435: int overlap( const RegMask &rm ) const { duke@435: return duke@435: # define BODY(I) (_A[I] & rm._A[I]) | duke@435: FORALL_BODY duke@435: # undef BODY duke@435: 0 ; duke@435: } duke@435: duke@435: // Special test for register pressure based splitting duke@435: // UP means register only, Register plus stack, or stack only is DOWN duke@435: bool is_UP() const; duke@435: duke@435: // Clear a register mask duke@435: void Clear( ) { duke@435: # define BODY(I) _A[I] = 0; duke@435: FORALL_BODY duke@435: # undef BODY duke@435: } duke@435: duke@435: // Fill a register mask with 1's duke@435: void Set_All( ) { duke@435: # define BODY(I) _A[I] = -1; duke@435: FORALL_BODY duke@435: # undef BODY duke@435: } duke@435: duke@435: // Insert register into mask duke@435: void Insert( OptoReg::Name reg ) { duke@435: assert( reg < CHUNK_SIZE, "" ); duke@435: _A[reg>>_LogWordBits] |= (1<<(reg&(_WordBits-1))); duke@435: } duke@435: duke@435: // Remove register from mask duke@435: void Remove( OptoReg::Name reg ) { duke@435: assert( reg < CHUNK_SIZE, "" ); duke@435: _A[reg>>_LogWordBits] &= ~(1<<(reg&(_WordBits-1))); duke@435: } duke@435: duke@435: // OR 'rm' into 'this' duke@435: void OR( const RegMask &rm ) { duke@435: # define BODY(I) this->_A[I] |= rm._A[I]; duke@435: FORALL_BODY duke@435: # undef BODY duke@435: } duke@435: duke@435: // AND 'rm' into 'this' duke@435: void AND( const RegMask &rm ) { duke@435: # define BODY(I) this->_A[I] &= rm._A[I]; duke@435: FORALL_BODY duke@435: # undef BODY duke@435: } duke@435: duke@435: // Subtract 'rm' from 'this' duke@435: void SUBTRACT( const RegMask &rm ) { duke@435: # define BODY(I) _A[I] &= ~rm._A[I]; duke@435: FORALL_BODY duke@435: # undef BODY duke@435: } duke@435: duke@435: // Compute size of register mask: number of bits duke@435: uint Size() const; duke@435: duke@435: #ifndef PRODUCT duke@435: void print() const { dump(); } duke@435: void dump() const; // Print a mask duke@435: #endif duke@435: duke@435: static const RegMask Empty; // Common empty mask duke@435: duke@435: static bool can_represent(OptoReg::Name reg) { duke@435: // NOTE: -1 in computation reflects the usage of the last duke@435: // bit of the regmask as an infinite stack flag. duke@435: return (int)reg < (int)(CHUNK_SIZE-1); duke@435: } duke@435: }; duke@435: duke@435: // Do not use this constant directly in client code! duke@435: #undef RM_SIZE