regalloc.cpp revision 5776:de6a9e811145
133965Sjdp/*
278828Sobrien * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
3130561Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
433965Sjdp *
533965Sjdp * This code is free software; you can redistribute it and/or modify it
633965Sjdp * under the terms of the GNU General Public License version 2 only, as
733965Sjdp * published by the Free Software Foundation.
833965Sjdp *
933965Sjdp * This code is distributed in the hope that it will be useful, but WITHOUT
1033965Sjdp * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1133965Sjdp * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1233965Sjdp * version 2 for more details (a copy is included in the LICENSE file that
1333965Sjdp * accompanied this code).
1433965Sjdp *
1533965Sjdp * You should have received a copy of the GNU General Public License version
1633965Sjdp * 2 along with this work; if not, write to the Free Software Foundation,
1733965Sjdp * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1833965Sjdp *
1933965Sjdp * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2033965Sjdp * or visit www.oracle.com if you need additional information or have any
2133965Sjdp * questions.
2233965Sjdp *
23130561Sobrien */
2433965Sjdp
2533965Sjdp#include "precompiled.hpp"
2633965Sjdp#include "opto/regalloc.hpp"
2733965Sjdp
2833965Sjdpstatic const int NodeRegsOverflowSize = 200;
2933965Sjdp
30130561Sobrienvoid (*PhaseRegAlloc::_alloc_statistics[MAX_REG_ALLOCATORS])();
3133965Sjdpint PhaseRegAlloc::_num_allocators = 0;
3233965Sjdp#ifndef PRODUCT
3333965Sjdpint PhaseRegAlloc::_total_framesize = 0;
3433965Sjdpint PhaseRegAlloc::_max_framesize = 0;
3533965Sjdp#endif
3633965Sjdp
3733965SjdpPhaseRegAlloc::PhaseRegAlloc( uint unique, PhaseCFG &cfg,
3860484Sobrien                              Matcher &matcher,
3933965Sjdp                              void (*pr_stats)() ):
4033965Sjdp               Phase(Register_Allocation), _cfg(cfg), _matcher(matcher),
4133965Sjdp               _node_oops(Thread::current()->resource_area()),
4233965Sjdp               _node_regs(0),
4333965Sjdp               _node_regs_max_index(0),
4433965Sjdp               _framesize(0xdeadbeef)
4533965Sjdp{
4633965Sjdp    int i;
47104834Sobrien
48104834Sobrien    for (i=0; i < _num_allocators; i++) {
49104834Sobrien        if (_alloc_statistics[i] == pr_stats)
5033965Sjdp            return;
5160484Sobrien    }
5277298Sobrien    assert((_num_allocators + 1) < MAX_REG_ALLOCATORS, "too many register allocators");
5360484Sobrien    _alloc_statistics[_num_allocators++] = pr_stats;
5460484Sobrien}
5560484Sobrien
5660484Sobrien
5760484Sobrien//------------------------------reg2offset-------------------------------------
5833965Sjdpint PhaseRegAlloc::reg2offset_unchecked( OptoReg::Name reg ) const {
5933965Sjdp  // Slots below _max_in_arg_stack_reg are offset by the entire frame.
6033965Sjdp  // Slots above _max_in_arg_stack_reg are frame_slots and are not offset.
6133965Sjdp  int slot = (reg < _matcher._new_SP)
6233965Sjdp    ? reg - OptoReg::stack0() + _framesize
6333965Sjdp    : reg - _matcher._new_SP;
6433965Sjdp  // Note:  We use the direct formula (reg - SharedInfo::stack0) instead of
6533965Sjdp  // OptoReg::reg2stack(reg), in order to avoid asserts in the latter
6633965Sjdp  // function.  This routine must remain unchecked, so that dump_frame()
6733965Sjdp  // can do its work undisturbed.
6833965Sjdp  // %%% not really clear why reg2stack would assert here
6933965Sjdp
7033965Sjdp  return slot*VMRegImpl::stack_slot_size;
7133965Sjdp}
7238889Sjdp
7338889Sjdpint PhaseRegAlloc::reg2offset( OptoReg::Name reg ) const {
7438889Sjdp
7538889Sjdp  // Not allowed in the out-preserve area.
7660484Sobrien  // In-preserve area is allowed so Intel can fetch the return pc out.
7760484Sobrien  assert( reg <  _matcher._old_SP ||
7860484Sobrien          (reg >= OptoReg::add(_matcher._old_SP,C->out_preserve_stack_slots()) &&
7938889Sjdp           reg <  _matcher._in_arg_limit) ||
8038889Sjdp          reg >=  OptoReg::add(_matcher._new_SP,C->out_preserve_stack_slots()),
8189857Sobrien          "register allocated in a preserve area" );
8233965Sjdp  return reg2offset_unchecked( reg );
8333965Sjdp}
8433965Sjdp
8589857Sobrien//------------------------------offset2reg-------------------------------------
8633965SjdpOptoReg::Name PhaseRegAlloc::offset2reg(int stk_offset) const {
8733965Sjdp  int slot = stk_offset / jintSize;
8833965Sjdp  int reg = (slot < (int) _framesize)
8933965Sjdp    ? slot + _matcher._new_SP
90130561Sobrien    : OptoReg::stack2reg(slot) - _framesize;
9133965Sjdp  assert(stk_offset == reg2offset((OptoReg::Name) reg),
9233965Sjdp         "offset2reg does not invert properly");
9333965Sjdp  return (OptoReg::Name) reg;
9477298Sobrien}
9533965Sjdp
9677298Sobrien//------------------------------set_oop----------------------------------------
97130561Sobrienvoid PhaseRegAlloc::set_oop( const Node *n, bool is_an_oop ) {
9833965Sjdp  if( is_an_oop ) {
9933965Sjdp    _node_oops.set(n->_idx);
10060484Sobrien  }
10133965Sjdp}
10233965Sjdp
10333965Sjdp//------------------------------is_oop-----------------------------------------
10438889Sjdpbool PhaseRegAlloc::is_oop( const Node *n ) const {
10533965Sjdp  return _node_oops.test(n->_idx) != 0;
10633965Sjdp}
10733965Sjdp
10860484Sobrien// Allocate _node_regs table with at least "size" elements
10960484Sobrienvoid PhaseRegAlloc::alloc_node_regs(int size) {
11060484Sobrien  _node_regs_max_index = size + (size >> 1) + NodeRegsOverflowSize;
11133965Sjdp  _node_regs = NEW_RESOURCE_ARRAY( OptoRegPair, _node_regs_max_index );
11260484Sobrien  // We assume our caller will fill in all elements up to size-1, so
11333965Sjdp  // only the extra space we allocate is initialized here.
11433965Sjdp  for( uint i = size; i < _node_regs_max_index; ++i )
11533965Sjdp    _node_regs[i].set_bad();
11660484Sobrien}
117130561Sobrien
11833965Sjdp#ifndef PRODUCT
11933965Sjdpvoid
12033965SjdpPhaseRegAlloc::print_statistics() {
12133965Sjdp  tty->print_cr("Total frameslots = %d, Max frameslots = %d", _total_framesize, _max_framesize);
12233965Sjdp  int i;
12333965Sjdp
12433965Sjdp  for (i=0; i < _num_allocators; i++) {
12533965Sjdp    _alloc_statistics[i]();
12633965Sjdp  }
12733965Sjdp}
12833965Sjdp#endif
12933965Sjdp