提交 6ea208d0 编写于 作者: N neliasso

Merge

...@@ -187,7 +187,7 @@ Src_Dirs/ZERO := $(CORE_PATHS) ...@@ -187,7 +187,7 @@ Src_Dirs/ZERO := $(CORE_PATHS)
Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS) Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS)
Src_Dirs := $(Src_Dirs/$(TYPE)) Src_Dirs := $(Src_Dirs/$(TYPE))
COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\* COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
COMPILER1_SPECIFIC_FILES := c1_\* COMPILER1_SPECIFIC_FILES := c1_\*
SHARK_SPECIFIC_FILES := shark SHARK_SPECIFIC_FILES := shark
ZERO_SPECIFIC_FILES := zero ZERO_SPECIFIC_FILES := zero
......
...@@ -189,7 +189,7 @@ Src_Dirs/ZERO := $(CORE_PATHS) ...@@ -189,7 +189,7 @@ Src_Dirs/ZERO := $(CORE_PATHS)
Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS) Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS)
Src_Dirs := $(Src_Dirs/$(TYPE)) Src_Dirs := $(Src_Dirs/$(TYPE))
COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\* COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
COMPILER1_SPECIFIC_FILES := c1_\* COMPILER1_SPECIFIC_FILES := c1_\*
SHARK_SPECIFIC_FILES := shark SHARK_SPECIFIC_FILES := shark
ZERO_SPECIFIC_FILES := zero ZERO_SPECIFIC_FILES := zero
......
...@@ -202,7 +202,7 @@ Src_Dirs/ZERO := $(CORE_PATHS) ...@@ -202,7 +202,7 @@ Src_Dirs/ZERO := $(CORE_PATHS)
Src_Dirs/SHARK := $(CORE_PATHS) Src_Dirs/SHARK := $(CORE_PATHS)
Src_Dirs := $(Src_Dirs/$(TYPE)) Src_Dirs := $(Src_Dirs/$(TYPE))
COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\* COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
COMPILER1_SPECIFIC_FILES := c1_\* COMPILER1_SPECIFIC_FILES := c1_\*
SHARK_SPECIFIC_FILES := shark SHARK_SPECIFIC_FILES := shark
ZERO_SPECIFIC_FILES := zero ZERO_SPECIFIC_FILES := zero
......
...@@ -114,7 +114,7 @@ case "${TYPE}" in ...@@ -114,7 +114,7 @@ case "${TYPE}" in
"shark") Src_Dirs="${CORE_PATHS}" ;; "shark") Src_Dirs="${CORE_PATHS}" ;;
esac esac
COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp chaitin* c2_* runtime_*" COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp c2_* runtime_*"
COMPILER1_SPECIFIC_FILES="c1_*" COMPILER1_SPECIFIC_FILES="c1_*"
SHARK_SPECIFIC_FILES="shark" SHARK_SPECIFIC_FILES="shark"
ZERO_SPECIFIC_FILES="zero" ZERO_SPECIFIC_FILES="zero"
......
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "opto/chaitin.hpp"
#include "opto/machnode.hpp"
void PhaseRegAlloc::pd_preallocate_hook() {
// no action
}
#ifdef ASSERT
void PhaseRegAlloc::pd_postallocate_verify_hook() {
// no action
}
#endif
// Reconciliation History
// chaitin_solaris.cpp 1.7 99/07/12 23:54:22
// End
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "opto/chaitin.hpp"
#include "opto/machnode.hpp"
void PhaseRegAlloc::pd_preallocate_hook() {
// no action
}
#ifdef ASSERT
void PhaseRegAlloc::pd_postallocate_verify_hook() {
// no action
}
#endif
// Reconciliation History
// chaitin_solaris.cpp 1.7 99/07/12 23:54:22
// End
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "opto/chaitin.hpp"
#include "opto/machnode.hpp"
void PhaseRegAlloc::pd_preallocate_hook() {
// no action
}
#ifdef ASSERT
void PhaseRegAlloc::pd_postallocate_verify_hook() {
// no action
}
#endif
//Reconciliation History
// 1.1 99/02/12 15:35:26 chaitin_win32.cpp
// 1.2 99/02/18 15:38:56 chaitin_win32.cpp
// 1.4 99/03/09 10:37:48 chaitin_win32.cpp
// 1.6 99/03/25 11:07:44 chaitin_win32.cpp
// 1.8 99/06/22 16:38:58 chaitin_win32.cpp
//End
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "opto/chaitin.hpp"
#include "opto/machnode.hpp"
// Disallow the use of the frame pointer (EBP) for implicit null exceptions
// on win95/98. If we do not do this, the OS gets confused and gives a stack
// error.
void PhaseRegAlloc::pd_preallocate_hook() {
#ifndef _WIN64
if (ImplicitNullChecks && !os::win32::is_nt()) {
for (uint block_num=1; block_num<_cfg._num_blocks; block_num++) {
Block *block = _cfg._blocks[block_num];
Node *block_end = block->end();
if (block_end->is_MachNullCheck() &&
block_end->as_Mach()->ideal_Opcode() != Op_Con) {
// The last instruction in the block is an implicit null check.
// Fix its input so that it does not load into the frame pointer.
_matcher.pd_implicit_null_fixup(block_end->in(1)->as_Mach(),
block_end->as_MachNullCheck()->_vidx);
}
}
}
#else
// WIN64==itanium on XP
#endif
}
#ifdef ASSERT
// Verify that no implicit null check uses the frame pointer (EBP) as
// its register on win95/98. Use of the frame pointer in an implicit
// null check confuses the OS, yielding a stack error.
void PhaseRegAlloc::pd_postallocate_verify_hook() {
#ifndef _WIN64
if (ImplicitNullChecks && !os::win32::is_nt()) {
for (uint block_num=1; block_num<_cfg._num_blocks; block_num++) {
Block *block = _cfg._blocks[block_num];
Node *block_end = block->_nodes[block->_nodes.size()-1];
if (block_end->is_MachNullCheck() && block_end->as_Mach()->ideal_Opcode() != Op_Con) {
// The last instruction in the block is an implicit
// null check. Verify that this instruction does not
// use the frame pointer.
int reg = get_reg_first(block_end->in(1)->in(block_end->as_MachNullCheck()->_vidx));
assert(reg != EBP_num,
"implicit null check using frame pointer on win95/98");
}
}
}
#else
// WIN64==itanium on XP
#endif
}
#endif
此差异已折叠。
...@@ -265,18 +265,118 @@ public: ...@@ -265,18 +265,118 @@ public:
int effective_degree( uint lidx ) const; int effective_degree( uint lidx ) const;
}; };
// TEMPORARILY REPLACED WITH COMMAND LINE FLAG // The LiveRangeMap class is responsible for storing node to live range id mapping.
// Each node is mapped to a live range id (a virtual register). Nodes that are
//// !!!!! Magic Constants need to move into ad file // not considered for register allocation are given live range id 0.
#ifdef SPARC class LiveRangeMap VALUE_OBJ_CLASS_SPEC {
//#define FLOAT_PRESSURE 30 /* SFLT_REG_mask.Size() - 1 */
//#define INT_PRESSURE 23 /* NOTEMP_I_REG_mask.Size() - 1 */ private:
#define FLOAT_INCREMENT(regs) regs
#else uint _max_lrg_id;
//#define FLOAT_PRESSURE 6
//#define INT_PRESSURE 6 // Union-find map. Declared as a short for speed.
#define FLOAT_INCREMENT(regs) 1 // Indexed by live-range number, it returns the compacted live-range number
#endif LRG_List _uf_map;
// Map from Nodes to live ranges
LRG_List _names;
// Straight out of Tarjan's union-find algorithm
uint find_compress(const Node *node) {
uint lrg_id = find_compress(_names[node->_idx]);
_names.map(node->_idx, lrg_id);
return lrg_id;
}
uint find_compress(uint lrg);
public:
const LRG_List& names() {
return _names;
}
uint max_lrg_id() const {
return _max_lrg_id;
}
void set_max_lrg_id(uint max_lrg_id) {
_max_lrg_id = max_lrg_id;
}
uint size() const {
return _names.Size();
}
uint live_range_id(uint idx) const {
return _names[idx];
}
uint live_range_id(const Node *node) const {
return _names[node->_idx];
}
uint uf_live_range_id(uint lrg_id) const {
return _uf_map[lrg_id];
}
void map(uint idx, uint lrg_id) {
_names.map(idx, lrg_id);
}
void uf_map(uint dst_lrg_id, uint src_lrg_id) {
_uf_map.map(dst_lrg_id, src_lrg_id);
}
void extend(uint idx, uint lrg_id) {
_names.extend(idx, lrg_id);
}
void uf_extend(uint dst_lrg_id, uint src_lrg_id) {
_uf_map.extend(dst_lrg_id, src_lrg_id);
}
LiveRangeMap(uint unique)
: _names(unique)
, _uf_map(unique)
, _max_lrg_id(0) {}
uint find_id( const Node *n ) {
uint retval = live_range_id(n);
assert(retval == find(n),"Invalid node to lidx mapping");
return retval;
}
// Reset the Union-Find map to identity
void reset_uf_map(uint max_lrg_id);
// Make all Nodes map directly to their final live range; no need for
// the Union-Find mapping after this call.
void compress_uf_map_for_nodes();
uint find(uint lidx) {
uint uf_lidx = _uf_map[lidx];
return (uf_lidx == lidx) ? uf_lidx : find_compress(lidx);
}
// Convert a Node into a Live Range Index - a lidx
uint find(const Node *node) {
uint lidx = live_range_id(node);
uint uf_lidx = _uf_map[lidx];
return (uf_lidx == lidx) ? uf_lidx : find_compress(node);
}
// Like Find above, but no path compress, so bad asymptotic behavior
uint find_const(uint lrg) const;
// Like Find above, but no path compress, so bad asymptotic behavior
uint find_const(const Node *node) const {
if(node->_idx >= _names.Size()) {
return 0; // not mapped, usual for debug dump
}
return find_const(_names[node->_idx]);
}
};
//------------------------------Chaitin---------------------------------------- //------------------------------Chaitin----------------------------------------
// Briggs-Chaitin style allocation, mostly. // Briggs-Chaitin style allocation, mostly.
...@@ -286,7 +386,6 @@ class PhaseChaitin : public PhaseRegAlloc { ...@@ -286,7 +386,6 @@ class PhaseChaitin : public PhaseRegAlloc {
int _trip_cnt; int _trip_cnt;
int _alternate; int _alternate;
uint _maxlrg; // Max live range number
LRG &lrgs(uint idx) const { return _ifg->lrgs(idx); } LRG &lrgs(uint idx) const { return _ifg->lrgs(idx); }
PhaseLive *_live; // Liveness, used in the interference graph PhaseLive *_live; // Liveness, used in the interference graph
PhaseIFG *_ifg; // Interference graph (for original chunk) PhaseIFG *_ifg; // Interference graph (for original chunk)
...@@ -294,16 +393,6 @@ class PhaseChaitin : public PhaseRegAlloc { ...@@ -294,16 +393,6 @@ class PhaseChaitin : public PhaseRegAlloc {
VectorSet _spilled_once; // Nodes that have been spilled VectorSet _spilled_once; // Nodes that have been spilled
VectorSet _spilled_twice; // Nodes that have been spilled twice VectorSet _spilled_twice; // Nodes that have been spilled twice
LRG_List _names; // Map from Nodes to Live RanGes
// Union-find map. Declared as a short for speed.
// Indexed by live-range number, it returns the compacted live-range number
LRG_List _uf_map;
// Reset the Union-Find map to identity
void reset_uf_map( uint maxlrg );
// Remove the need for the Union-Find mapping
void compress_uf_map_for_nodes( );
// Combine the Live Range Indices for these 2 Nodes into a single live // Combine the Live Range Indices for these 2 Nodes into a single live
// range. Future requests for any Node in either live range will // range. Future requests for any Node in either live range will
// return the live range index for the combined live range. // return the live range index for the combined live range.
...@@ -322,7 +411,34 @@ class PhaseChaitin : public PhaseRegAlloc { ...@@ -322,7 +411,34 @@ class PhaseChaitin : public PhaseRegAlloc {
// Helper functions for Split() // Helper functions for Split()
uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx ); uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx );
uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx ); uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx );
int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg );
bool clone_projs(Block *b, uint idx, Node *con, Node *copy, LiveRangeMap &lrg_map) {
bool found_projs = clone_projs_shared(b, idx, con, copy, lrg_map.max_lrg_id());
if(found_projs) {
uint max_lrg_id = lrg_map.max_lrg_id();
lrg_map.set_max_lrg_id(max_lrg_id + 1);
}
return found_projs;
}
//------------------------------clone_projs------------------------------------
// After cloning some rematerialized instruction, clone any MachProj's that
// follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants
// use G3 as an address temp.
bool clone_projs(Block *b, uint idx, Node *con, Node *copy, uint &max_lrg_id) {
bool found_projs = clone_projs_shared(b, idx, con, copy, max_lrg_id);
if(found_projs) {
max_lrg_id++;
}
return found_projs;
}
bool clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id);
Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits, Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits,
int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
// True if lidx is used before any real register is def'd in the block // True if lidx is used before any real register is def'd in the block
...@@ -349,20 +465,11 @@ public: ...@@ -349,20 +465,11 @@ public:
PhaseChaitin( uint unique, PhaseCFG &cfg, Matcher &matcher ); PhaseChaitin( uint unique, PhaseCFG &cfg, Matcher &matcher );
~PhaseChaitin() {} ~PhaseChaitin() {}
// Convert a Node into a Live Range Index - a lidx LiveRangeMap _lrg_map;
uint Find( const Node *n ) {
uint lidx = n2lidx(n);
uint uf_lidx = _uf_map[lidx];
return (uf_lidx == lidx) ? uf_lidx : Find_compress(n);
}
uint Find_const( uint lrg ) const;
uint Find_const( const Node *n ) const;
// Do all the real work of allocate // Do all the real work of allocate
void Register_Allocate(); void Register_Allocate();
uint n2lidx( const Node *n ) const { return _names[n->_idx]; }
float high_frequency_lrg() const { return _high_frequency_lrg; } float high_frequency_lrg() const { return _high_frequency_lrg; }
#ifndef PRODUCT #ifndef PRODUCT
...@@ -374,18 +481,6 @@ private: ...@@ -374,18 +481,6 @@ private:
// all inputs to a PhiNode, effectively coalescing live ranges. Insert // all inputs to a PhiNode, effectively coalescing live ranges. Insert
// copies as needed. // copies as needed.
void de_ssa(); void de_ssa();
uint Find_compress( const Node *n );
uint Find( uint lidx ) {
uint uf_lidx = _uf_map[lidx];
return (uf_lidx == lidx) ? uf_lidx : Find_compress(lidx);
}
uint Find_compress( uint lidx );
uint Find_id( const Node *n ) {
uint retval = n2lidx(n);
assert(retval == Find(n),"Invalid node to lidx mapping");
return retval;
}
// Add edge between reg and everything in the vector. // Add edge between reg and everything in the vector.
// Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask // Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask
......
此差异已折叠。
...@@ -41,23 +41,25 @@ protected: ...@@ -41,23 +41,25 @@ protected:
public: public:
// Coalesce copies // Coalesce copies
PhaseCoalesce( PhaseChaitin &chaitin ) : Phase(Coalesce), _phc(chaitin) { } PhaseCoalesce(PhaseChaitin &phc)
: Phase(Coalesce)
, _phc(phc) {}
virtual void verify() = 0; virtual void verify() = 0;
// Coalesce copies // Coalesce copies
void coalesce_driver( ); void coalesce_driver();
// Coalesce copies in this block // Coalesce copies in this block
virtual void coalesce( Block *b ) = 0; virtual void coalesce(Block *b) = 0;
// Attempt to coalesce live ranges defined by these 2 // Attempt to coalesce live ranges defined by these 2
void combine_these_two( Node *n1, Node *n2 ); void combine_these_two(Node *n1, Node *n2);
LRG &lrgs( uint lidx ) { return _phc.lrgs(lidx); } LRG &lrgs(uint lidx) { return _phc.lrgs(lidx); }
#ifndef PRODUCT #ifndef PRODUCT
// Dump internally name // Dump internally name
void dump( Node *n ) const; void dump(Node *n) const;
// Dump whole shebang // Dump whole shebang
void dump() const; void dump() const;
#endif #endif
......
...@@ -2127,22 +2127,19 @@ void Compile::Code_Gen() { ...@@ -2127,22 +2127,19 @@ void Compile::Code_Gen() {
} }
NOT_PRODUCT( verify_graph_edges(); ) NOT_PRODUCT( verify_graph_edges(); )
PhaseChaitin regalloc(unique(),cfg,m); PhaseChaitin regalloc(unique(), cfg, m);
_regalloc = &regalloc; _regalloc = &regalloc;
{ {
TracePhase t2("regalloc", &_t_registerAllocation, true); TracePhase t2("regalloc", &_t_registerAllocation, true);
// Perform any platform dependent preallocation actions. This is used,
// for example, to avoid taking an implicit null pointer exception
// using the frame pointer on win95.
_regalloc->pd_preallocate_hook();
// Perform register allocation. After Chaitin, use-def chains are // Perform register allocation. After Chaitin, use-def chains are
// no longer accurate (at spill code) and so must be ignored. // no longer accurate (at spill code) and so must be ignored.
// Node->LRG->reg mappings are still accurate. // Node->LRG->reg mappings are still accurate.
_regalloc->Register_Allocate(); _regalloc->Register_Allocate();
// Bail out if the allocator builds too many nodes // Bail out if the allocator builds too many nodes
if (failing()) return; if (failing()) {
return;
}
} }
// Prior to register allocation we kept empty basic blocks in case the // Prior to register allocation we kept empty basic blocks in case the
...@@ -2160,9 +2157,6 @@ void Compile::Code_Gen() { ...@@ -2160,9 +2157,6 @@ void Compile::Code_Gen() {
cfg.fixup_flow(); cfg.fixup_flow();
} }
// Perform any platform dependent postallocation verifications.
debug_only( _regalloc->pd_postallocate_verify_hook(); )
// Apply peephole optimizations // Apply peephole optimizations
if( OptoPeephole ) { if( OptoPeephole ) {
NOT_PRODUCT( TracePhase t2("peephole", &_t_peephole, TimeCompiler); ) NOT_PRODUCT( TracePhase t2("peephole", &_t_peephole, TimeCompiler); )
......
...@@ -616,7 +616,7 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) { ...@@ -616,7 +616,7 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
buffer[0] = 0; buffer[0] = 0;
_chaitin->dump_register(node, buffer); _chaitin->dump_register(node, buffer);
print_prop("reg", buffer); print_prop("reg", buffer);
print_prop("lrg", _chaitin->n2lidx(node)); print_prop("lrg", _chaitin->_lrg_map.live_range_id(node));
} }
node->_in_dump_cnt--; node->_in_dump_cnt--;
......
...@@ -286,15 +286,14 @@ void PhaseIFG::verify( const PhaseChaitin *pc ) const { ...@@ -286,15 +286,14 @@ void PhaseIFG::verify( const PhaseChaitin *pc ) const {
uint idx; uint idx;
uint last = 0; uint last = 0;
while ((idx = elements.next()) != 0) { while ((idx = elements.next()) != 0) {
assert( idx != i, "Must have empty diagonal"); assert(idx != i, "Must have empty diagonal");
assert( pc->Find_const(idx) == idx, "Must not need Find" ); assert(pc->_lrg_map.find_const(idx) == idx, "Must not need Find");
assert( _adjs[idx].member(i), "IFG not square" ); assert(_adjs[idx].member(i), "IFG not square");
assert( !(*_yanked)[idx], "No yanked neighbors" ); assert(!(*_yanked)[idx], "No yanked neighbors");
assert( last < idx, "not sorted increasing"); assert(last < idx, "not sorted increasing");
last = idx; last = idx;
} }
assert( !lrgs(i)._degree_valid || assert(!lrgs(i)._degree_valid || effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong");
effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong" );
} }
} }
#endif #endif
...@@ -342,10 +341,10 @@ void PhaseChaitin::build_ifg_virtual( ) { ...@@ -342,10 +341,10 @@ void PhaseChaitin::build_ifg_virtual( ) {
Node *n = b->_nodes[j-1]; Node *n = b->_nodes[j-1];
// Get value being defined // Get value being defined
uint r = n2lidx(n); uint r = _lrg_map.live_range_id(n);
// Some special values do not allocate // Some special values do not allocate
if( r ) { if (r) {
// Remove from live-out set // Remove from live-out set
liveout->remove(r); liveout->remove(r);
...@@ -353,16 +352,19 @@ void PhaseChaitin::build_ifg_virtual( ) { ...@@ -353,16 +352,19 @@ void PhaseChaitin::build_ifg_virtual( ) {
// Copies do not define a new value and so do not interfere. // Copies do not define a new value and so do not interfere.
// Remove the copies source from the liveout set before interfering. // Remove the copies source from the liveout set before interfering.
uint idx = n->is_Copy(); uint idx = n->is_Copy();
if( idx ) liveout->remove( n2lidx(n->in(idx)) ); if (idx) {
liveout->remove(_lrg_map.live_range_id(n->in(idx)));
}
// Interfere with everything live // Interfere with everything live
interfere_with_live( r, liveout ); interfere_with_live(r, liveout);
} }
// Make all inputs live // Make all inputs live
if( !n->is_Phi() ) { // Phi function uses come from prior block if (!n->is_Phi()) { // Phi function uses come from prior block
for( uint k = 1; k < n->req(); k++ ) for(uint k = 1; k < n->req(); k++) {
liveout->insert( n2lidx(n->in(k)) ); liveout->insert(_lrg_map.live_range_id(n->in(k)));
}
} }
// 2-address instructions always have the defined value live // 2-address instructions always have the defined value live
...@@ -394,11 +396,12 @@ void PhaseChaitin::build_ifg_virtual( ) { ...@@ -394,11 +396,12 @@ void PhaseChaitin::build_ifg_virtual( ) {
n->set_req( 2, tmp ); n->set_req( 2, tmp );
} }
// Defined value interferes with all inputs // Defined value interferes with all inputs
uint lidx = n2lidx(n->in(idx)); uint lidx = _lrg_map.live_range_id(n->in(idx));
for( uint k = 1; k < n->req(); k++ ) { for (uint k = 1; k < n->req(); k++) {
uint kidx = n2lidx(n->in(k)); uint kidx = _lrg_map.live_range_id(n->in(k));
if( kidx != lidx ) if (kidx != lidx) {
_ifg->add_edge( r, kidx ); _ifg->add_edge(r, kidx);
}
} }
} }
} // End of forall instructions in block } // End of forall instructions in block
...@@ -542,10 +545,10 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { ...@@ -542,10 +545,10 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
Node *n = b->_nodes[j - 1]; Node *n = b->_nodes[j - 1];
// Get value being defined // Get value being defined
uint r = n2lidx(n); uint r = _lrg_map.live_range_id(n);
// Some special values do not allocate // Some special values do not allocate
if( r ) { if(r) {
// A DEF normally costs block frequency; rematerialized values are // A DEF normally costs block frequency; rematerialized values are
// removed from the DEF sight, so LOWER costs here. // removed from the DEF sight, so LOWER costs here.
lrgs(r)._cost += n->rematerialize() ? 0 : b->_freq; lrgs(r)._cost += n->rematerialize() ? 0 : b->_freq;
...@@ -556,9 +559,11 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { ...@@ -556,9 +559,11 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
Node *def = n->in(0); Node *def = n->in(0);
if( !n->is_Proj() || if( !n->is_Proj() ||
// Could also be a flags-projection of a dead ADD or such. // Could also be a flags-projection of a dead ADD or such.
(n2lidx(def) && !liveout.member(n2lidx(def)) ) ) { (_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) {
b->_nodes.remove(j - 1); b->_nodes.remove(j - 1);
if( lrgs(r)._def == n ) lrgs(r)._def = 0; if (lrgs(r)._def == n) {
lrgs(r)._def = 0;
}
n->disconnect_inputs(NULL, C); n->disconnect_inputs(NULL, C);
_cfg._bbs.map(n->_idx,NULL); _cfg._bbs.map(n->_idx,NULL);
n->replace_by(C->top()); n->replace_by(C->top());
...@@ -570,7 +575,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { ...@@ -570,7 +575,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
// Fat-projections kill many registers which cannot be used to // Fat-projections kill many registers which cannot be used to
// hold live ranges. // hold live ranges.
if( lrgs(r)._fat_proj ) { if (lrgs(r)._fat_proj) {
// Count the int-only registers // Count the int-only registers
RegMask itmp = lrgs(r).mask(); RegMask itmp = lrgs(r).mask();
itmp.AND(*Matcher::idealreg2regmask[Op_RegI]); itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
...@@ -636,12 +641,12 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { ...@@ -636,12 +641,12 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
// Copies do not define a new value and so do not interfere. // Copies do not define a new value and so do not interfere.
// Remove the copies source from the liveout set before interfering. // Remove the copies source from the liveout set before interfering.
uint idx = n->is_Copy(); uint idx = n->is_Copy();
if( idx ) { if (idx) {
uint x = n2lidx(n->in(idx)); uint x = _lrg_map.live_range_id(n->in(idx));
if( liveout.remove( x ) ) { if (liveout.remove(x)) {
lrgs(x)._area -= cost; lrgs(x)._area -= cost;
// Adjust register pressure. // Adjust register pressure.
lower_pressure( &lrgs(x), j-1, b, pressure, hrp_index ); lower_pressure(&lrgs(x), j-1, b, pressure, hrp_index);
assert( pressure[0] == count_int_pressure (&liveout), "" ); assert( pressure[0] == count_int_pressure (&liveout), "" );
assert( pressure[1] == count_float_pressure(&liveout), "" ); assert( pressure[1] == count_float_pressure(&liveout), "" );
} }
...@@ -727,18 +732,21 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { ...@@ -727,18 +732,21 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
// the flags and assumes it's dead. This keeps the (useless) // the flags and assumes it's dead. This keeps the (useless)
// flag-setting behavior alive while also keeping the (useful) // flag-setting behavior alive while also keeping the (useful)
// memory update effect. // memory update effect.
for( uint k = ((n->Opcode() == Op_SCMemProj) ? 0:1); k < n->req(); k++ ) { for (uint k = ((n->Opcode() == Op_SCMemProj) ? 0:1); k < n->req(); k++) {
Node *def = n->in(k); Node *def = n->in(k);
uint x = n2lidx(def); uint x = _lrg_map.live_range_id(def);
if( !x ) continue; if (!x) {
continue;
}
LRG &lrg = lrgs(x); LRG &lrg = lrgs(x);
// No use-side cost for spilling debug info // No use-side cost for spilling debug info
if( k < debug_start ) if (k < debug_start) {
// A USE costs twice block frequency (once for the Load, once // A USE costs twice block frequency (once for the Load, once
// for a Load-delay). Rematerialized uses only cost once. // for a Load-delay). Rematerialized uses only cost once.
lrg._cost += (def->rematerialize() ? b->_freq : (b->_freq + b->_freq)); lrg._cost += (def->rematerialize() ? b->_freq : (b->_freq + b->_freq));
}
// It is live now // It is live now
if( liveout.insert( x ) ) { if (liveout.insert(x)) {
// Newly live things assumed live from here to top of block // Newly live things assumed live from here to top of block
lrg._area += cost; lrg._area += cost;
// Adjust register pressure // Adjust register pressure
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
// block is put on the worklist. // block is put on the worklist.
// The locally live-in stuff is computed once and added to predecessor // The locally live-in stuff is computed once and added to predecessor
// live-out sets. This separate compilation is done in the outer loop below. // live-out sets. This separate compilation is done in the outer loop below.
PhaseLive::PhaseLive( const PhaseCFG &cfg, LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) { PhaseLive::PhaseLive( const PhaseCFG &cfg, const LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) {
} }
void PhaseLive::compute(uint maxlrg) { void PhaseLive::compute(uint maxlrg) {
......
...@@ -80,7 +80,7 @@ class PhaseLive : public Phase { ...@@ -80,7 +80,7 @@ class PhaseLive : public Phase {
Block_List *_worklist; // Worklist for iterative solution Block_List *_worklist; // Worklist for iterative solution
const PhaseCFG &_cfg; // Basic blocks const PhaseCFG &_cfg; // Basic blocks
LRG_List &_names; // Mapping from Nodes to live ranges const LRG_List &_names; // Mapping from Nodes to live ranges
uint _maxlrg; // Largest live-range number uint _maxlrg; // Largest live-range number
Arena *_arena; Arena *_arena;
...@@ -91,7 +91,7 @@ class PhaseLive : public Phase { ...@@ -91,7 +91,7 @@ class PhaseLive : public Phase {
void add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ); void add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass );
public: public:
PhaseLive( const PhaseCFG &cfg, LRG_List &names, Arena *arena ); PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena);
~PhaseLive() {} ~PhaseLive() {}
// Compute liveness info // Compute liveness info
void compute(uint maxlrg); void compute(uint maxlrg);
......
...@@ -56,7 +56,7 @@ bool PhaseChaitin::may_be_copy_of_callee( Node *def ) const { ...@@ -56,7 +56,7 @@ bool PhaseChaitin::may_be_copy_of_callee( Node *def ) const {
int i; int i;
for( i=0; i < limit; i++ ) { for( i=0; i < limit; i++ ) {
if( def->is_Proj() && def->in(0)->is_Start() && if( def->is_Proj() && def->in(0)->is_Start() &&
_matcher.is_save_on_entry(lrgs(n2lidx(def)).reg()) ) _matcher.is_save_on_entry(lrgs(_lrg_map.live_range_id(def)).reg()))
return true; // Direct use of callee-save proj return true; // Direct use of callee-save proj
if( def->is_Copy() ) // Copies carry value through if( def->is_Copy() ) // Copies carry value through
def = def->in(def->is_Copy()); def = def->in(def->is_Copy());
...@@ -83,7 +83,7 @@ int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_ ...@@ -83,7 +83,7 @@ int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_
// Count 1 if deleting an instruction from the current block // Count 1 if deleting an instruction from the current block
if( oldb == current_block ) blk_adjust++; if( oldb == current_block ) blk_adjust++;
_cfg._bbs.map(old->_idx,NULL); _cfg._bbs.map(old->_idx,NULL);
OptoReg::Name old_reg = lrgs(n2lidx(old)).reg(); OptoReg::Name old_reg = lrgs(_lrg_map.live_range_id(old)).reg();
if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available? if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
value->map(old_reg,NULL); // Yank from value/regnd maps value->map(old_reg,NULL); // Yank from value/regnd maps
regnd->map(old_reg,NULL); // This register's value is now unknown regnd->map(old_reg,NULL); // This register's value is now unknown
...@@ -164,7 +164,7 @@ int PhaseChaitin::use_prior_register( Node *n, uint idx, Node *def, Block *curre ...@@ -164,7 +164,7 @@ int PhaseChaitin::use_prior_register( Node *n, uint idx, Node *def, Block *curre
// Not every pair of physical registers are assignment compatible, // Not every pair of physical registers are assignment compatible,
// e.g. on sparc floating point registers are not assignable to integer // e.g. on sparc floating point registers are not assignable to integer
// registers. // registers.
const LRG &def_lrg = lrgs(n2lidx(def)); const LRG &def_lrg = lrgs(_lrg_map.live_range_id(def));
OptoReg::Name def_reg = def_lrg.reg(); OptoReg::Name def_reg = def_lrg.reg();
const RegMask &use_mask = n->in_RegMask(idx); const RegMask &use_mask = n->in_RegMask(idx);
bool can_use = ( RegMask::can_represent(def_reg) ? (use_mask.Member(def_reg) != 0) bool can_use = ( RegMask::can_represent(def_reg) ? (use_mask.Member(def_reg) != 0)
...@@ -209,11 +209,12 @@ int PhaseChaitin::use_prior_register( Node *n, uint idx, Node *def, Block *curre ...@@ -209,11 +209,12 @@ int PhaseChaitin::use_prior_register( Node *n, uint idx, Node *def, Block *curre
// Skip through any number of copies (that don't mod oop-i-ness) // Skip through any number of copies (that don't mod oop-i-ness)
Node *PhaseChaitin::skip_copies( Node *c ) { Node *PhaseChaitin::skip_copies( Node *c ) {
int idx = c->is_Copy(); int idx = c->is_Copy();
uint is_oop = lrgs(n2lidx(c))._is_oop; uint is_oop = lrgs(_lrg_map.live_range_id(c))._is_oop;
while (idx != 0) { while (idx != 0) {
guarantee(c->in(idx) != NULL, "must not resurrect dead copy"); guarantee(c->in(idx) != NULL, "must not resurrect dead copy");
if (lrgs(n2lidx(c->in(idx)))._is_oop != is_oop) if (lrgs(_lrg_map.live_range_id(c->in(idx)))._is_oop != is_oop) {
break; // casting copy, not the same value break; // casting copy, not the same value
}
c = c->in(idx); c = c->in(idx);
idx = c->is_Copy(); idx = c->is_Copy();
} }
...@@ -225,8 +226,8 @@ Node *PhaseChaitin::skip_copies( Node *c ) { ...@@ -225,8 +226,8 @@ Node *PhaseChaitin::skip_copies( Node *c ) {
int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs ) { int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs ) {
int blk_adjust = 0; int blk_adjust = 0;
uint nk_idx = n2lidx(n->in(k)); uint nk_idx = _lrg_map.live_range_id(n->in(k));
OptoReg::Name nk_reg = lrgs(nk_idx ).reg(); OptoReg::Name nk_reg = lrgs(nk_idx).reg();
// Remove obvious same-register copies // Remove obvious same-register copies
Node *x = n->in(k); Node *x = n->in(k);
...@@ -234,9 +235,13 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v ...@@ -234,9 +235,13 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v
while( (idx=x->is_Copy()) != 0 ) { while( (idx=x->is_Copy()) != 0 ) {
Node *copy = x->in(idx); Node *copy = x->in(idx);
guarantee(copy != NULL, "must not resurrect dead copy"); guarantee(copy != NULL, "must not resurrect dead copy");
if( lrgs(n2lidx(copy)).reg() != nk_reg ) break; if(lrgs(_lrg_map.live_range_id(copy)).reg() != nk_reg) {
break;
}
blk_adjust += use_prior_register(n,k,copy,current_block,value,regnd); blk_adjust += use_prior_register(n,k,copy,current_block,value,regnd);
if( n->in(k) != copy ) break; // Failed for some cutout? if (n->in(k) != copy) {
break; // Failed for some cutout?
}
x = copy; // Progress, try again x = copy; // Progress, try again
} }
...@@ -256,7 +261,7 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v ...@@ -256,7 +261,7 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v
if (val == x && nk_idx != 0 && if (val == x && nk_idx != 0 &&
regnd[nk_reg] != NULL && regnd[nk_reg] != x && regnd[nk_reg] != NULL && regnd[nk_reg] != x &&
n2lidx(x) == n2lidx(regnd[nk_reg])) { _lrg_map.live_range_id(x) == _lrg_map.live_range_id(regnd[nk_reg])) {
// When rematerialzing nodes and stretching lifetimes, the // When rematerialzing nodes and stretching lifetimes, the
// allocator will reuse the original def for multidef LRG instead // allocator will reuse the original def for multidef LRG instead
// of the current reaching def because it can't know it's safe to // of the current reaching def because it can't know it's safe to
...@@ -270,7 +275,7 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v ...@@ -270,7 +275,7 @@ int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &v
if (val == x) return blk_adjust; // No progress? if (val == x) return blk_adjust; // No progress?
int n_regs = RegMask::num_registers(val->ideal_reg()); int n_regs = RegMask::num_registers(val->ideal_reg());
uint val_idx = n2lidx(val); uint val_idx = _lrg_map.live_range_id(val);
OptoReg::Name val_reg = lrgs(val_idx).reg(); OptoReg::Name val_reg = lrgs(val_idx).reg();
// See if it happens to already be in the correct register! // See if it happens to already be in the correct register!
...@@ -499,12 +504,12 @@ void PhaseChaitin::post_allocate_copy_removal() { ...@@ -499,12 +504,12 @@ void PhaseChaitin::post_allocate_copy_removal() {
for( j = 1; j < phi_dex; j++ ) { for( j = 1; j < phi_dex; j++ ) {
uint k; uint k;
Node *phi = b->_nodes[j]; Node *phi = b->_nodes[j];
uint pidx = n2lidx(phi); uint pidx = _lrg_map.live_range_id(phi);
OptoReg::Name preg = lrgs(n2lidx(phi)).reg(); OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg();
// Remove copies remaining on edges. Check for junk phi. // Remove copies remaining on edges. Check for junk phi.
Node *u = NULL; Node *u = NULL;
for( k=1; k<phi->req(); k++ ) { for (k = 1; k < phi->req(); k++) {
Node *x = phi->in(k); Node *x = phi->in(k);
if( phi != x && u != x ) // Found a different input if( phi != x && u != x ) // Found a different input
u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input
...@@ -555,10 +560,10 @@ void PhaseChaitin::post_allocate_copy_removal() { ...@@ -555,10 +560,10 @@ void PhaseChaitin::post_allocate_copy_removal() {
// alive and well at the use (or else the allocator fubar'd). Take // alive and well at the use (or else the allocator fubar'd). Take
// advantage of this info to set a reaching def for the use-reg. // advantage of this info to set a reaching def for the use-reg.
uint k; uint k;
for( k = 1; k < n->req(); k++ ) { for (k = 1; k < n->req(); k++) {
Node *def = n->in(k); // n->in(k) is a USE; def is the DEF for this USE Node *def = n->in(k); // n->in(k) is a USE; def is the DEF for this USE
guarantee(def != NULL, "no disconnected nodes at this point"); guarantee(def != NULL, "no disconnected nodes at this point");
uint useidx = n2lidx(def); // useidx is the live range index for this USE uint useidx = _lrg_map.live_range_id(def); // useidx is the live range index for this USE
if( useidx ) { if( useidx ) {
OptoReg::Name ureg = lrgs(useidx).reg(); OptoReg::Name ureg = lrgs(useidx).reg();
...@@ -566,7 +571,7 @@ void PhaseChaitin::post_allocate_copy_removal() { ...@@ -566,7 +571,7 @@ void PhaseChaitin::post_allocate_copy_removal() {
int idx; // Skip occasional useless copy int idx; // Skip occasional useless copy
while( (idx=def->is_Copy()) != 0 && while( (idx=def->is_Copy()) != 0 &&
def->in(idx) != NULL && // NULL should not happen def->in(idx) != NULL && // NULL should not happen
ureg == lrgs(n2lidx(def->in(idx))).reg() ) ureg == lrgs(_lrg_map.live_range_id(def->in(idx))).reg())
def = def->in(idx); def = def->in(idx);
Node *valdef = skip_copies(def); // tighten up val through non-useless copies Node *valdef = skip_copies(def); // tighten up val through non-useless copies
value.map(ureg,valdef); // record improved reaching-def info value.map(ureg,valdef); // record improved reaching-def info
...@@ -594,8 +599,10 @@ void PhaseChaitin::post_allocate_copy_removal() { ...@@ -594,8 +599,10 @@ void PhaseChaitin::post_allocate_copy_removal() {
j -= elide_copy( n, k, b, value, regnd, two_adr!=k ); j -= elide_copy( n, k, b, value, regnd, two_adr!=k );
// Unallocated Nodes define no registers // Unallocated Nodes define no registers
uint lidx = n2lidx(n); uint lidx = _lrg_map.live_range_id(n);
if( !lidx ) continue; if (!lidx) {
continue;
}
// Update the register defined by this instruction // Update the register defined by this instruction
OptoReg::Name nreg = lrgs(lidx).reg(); OptoReg::Name nreg = lrgs(lidx).reg();
......
...@@ -318,9 +318,13 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint ...@@ -318,9 +318,13 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint
for( uint i = 1; i < def->req(); i++ ) { for( uint i = 1; i < def->req(); i++ ) {
Node *in = def->in(i); Node *in = def->in(i);
// Check for single-def (LRG cannot redefined) // Check for single-def (LRG cannot redefined)
uint lidx = n2lidx(in); uint lidx = _lrg_map.live_range_id(in);
if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy if (lidx >= _lrg_map.max_lrg_id()) {
if (lrgs(lidx).is_singledef()) continue; continue; // Value is a recent spill-copy
}
if (lrgs(lidx).is_singledef()) {
continue;
}
Block *b_def = _cfg._bbs[def->_idx]; Block *b_def = _cfg._bbs[def->_idx];
int idx_def = b_def->find_node(def); int idx_def = b_def->find_node(def);
...@@ -344,26 +348,28 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint ...@@ -344,26 +348,28 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint
if( spill->req() > 1 ) { if( spill->req() > 1 ) {
for( uint i = 1; i < spill->req(); i++ ) { for( uint i = 1; i < spill->req(); i++ ) {
Node *in = spill->in(i); Node *in = spill->in(i);
uint lidx = Find_id(in); uint lidx = _lrg_map.find_id(in);
// Walk backwards thru spill copy node intermediates // Walk backwards thru spill copy node intermediates
if (walkThru) { if (walkThru) {
while ( in->is_SpillCopy() && lidx >= _maxlrg ) { while (in->is_SpillCopy() && lidx >= _lrg_map.max_lrg_id()) {
in = in->in(1); in = in->in(1);
lidx = Find_id(in); lidx = _lrg_map.find_id(in);
} }
if (lidx < _maxlrg && lrgs(lidx).is_multidef()) { if (lidx < _lrg_map.max_lrg_id() && lrgs(lidx).is_multidef()) {
// walkThru found a multidef LRG, which is unsafe to use, so // walkThru found a multidef LRG, which is unsafe to use, so
// just keep the original def used in the clone. // just keep the original def used in the clone.
in = spill->in(i); in = spill->in(i);
lidx = Find_id(in); lidx = _lrg_map.find_id(in);
} }
} }
if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) { if (lidx < _lrg_map.max_lrg_id() && lrgs(lidx).reg() >= LRG::SPILL_REG) {
Node *rdef = Reachblock[lrg2reach[lidx]]; Node *rdef = Reachblock[lrg2reach[lidx]];
if( rdef ) spill->set_req(i,rdef); if (rdef) {
spill->set_req(i, rdef);
}
} }
} }
} }
...@@ -382,7 +388,7 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint ...@@ -382,7 +388,7 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint
#endif #endif
// See if the cloned def kills any flags, and copy those kills as well // See if the cloned def kills any flags, and copy those kills as well
uint i = insidx+1; uint i = insidx+1;
if( clone_projs( b, i, def, spill, maxlrg ) ) { if( clone_projs( b, i, def, spill, maxlrg) ) {
// Adjust the point where we go hi-pressure // Adjust the point where we go hi-pressure
if( i <= b->_ihrp_index ) b->_ihrp_index++; if( i <= b->_ihrp_index ) b->_ihrp_index++;
if( i <= b->_fhrp_index ) b->_fhrp_index++; if( i <= b->_fhrp_index ) b->_fhrp_index++;
...@@ -424,17 +430,25 @@ bool PhaseChaitin::is_high_pressure( Block *b, LRG *lrg, uint insidx ) { ...@@ -424,17 +430,25 @@ bool PhaseChaitin::is_high_pressure( Block *b, LRG *lrg, uint insidx ) {
//------------------------------prompt_use--------------------------------- //------------------------------prompt_use---------------------------------
// True if lidx is used before any real register is def'd in the block // True if lidx is used before any real register is def'd in the block
bool PhaseChaitin::prompt_use( Block *b, uint lidx ) { bool PhaseChaitin::prompt_use( Block *b, uint lidx ) {
if( lrgs(lidx)._was_spilled2 ) return false; if (lrgs(lidx)._was_spilled2) {
return false;
}
// Scan block for 1st use. // Scan block for 1st use.
for( uint i = 1; i <= b->end_idx(); i++ ) { for( uint i = 1; i <= b->end_idx(); i++ ) {
Node *n = b->_nodes[i]; Node *n = b->_nodes[i];
// Ignore PHI use, these can be up or down // Ignore PHI use, these can be up or down
if( n->is_Phi() ) continue; if (n->is_Phi()) {
for( uint j = 1; j < n->req(); j++ ) continue;
if( Find_id(n->in(j)) == lidx ) }
for (uint j = 1; j < n->req(); j++) {
if (_lrg_map.find_id(n->in(j)) == lidx) {
return true; // Found 1st use! return true; // Found 1st use!
if( n->out_RegMask().is_NotEmpty() ) return false; }
}
if (n->out_RegMask().is_NotEmpty()) {
return false;
}
} }
return false; return false;
} }
...@@ -464,23 +478,23 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -464,23 +478,23 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
bool u1, u2, u3; bool u1, u2, u3;
Block *b, *pred; Block *b, *pred;
PhiNode *phi; PhiNode *phi;
GrowableArray<uint> lidxs(split_arena, _maxlrg, 0, 0); GrowableArray<uint> lidxs(split_arena, maxlrg, 0, 0);
// Array of counters to count splits per live range // Array of counters to count splits per live range
GrowableArray<uint> splits(split_arena, _maxlrg, 0, 0); GrowableArray<uint> splits(split_arena, maxlrg, 0, 0);
#define NEW_SPLIT_ARRAY(type, size)\ #define NEW_SPLIT_ARRAY(type, size)\
(type*) split_arena->allocate_bytes((size) * sizeof(type)) (type*) split_arena->allocate_bytes((size) * sizeof(type))
//----------Setup Code---------- //----------Setup Code----------
// Create a convenient mapping from lrg numbers to reaches/leaves indices // Create a convenient mapping from lrg numbers to reaches/leaves indices
uint *lrg2reach = NEW_SPLIT_ARRAY( uint, _maxlrg ); uint *lrg2reach = NEW_SPLIT_ARRAY(uint, maxlrg);
// Keep track of DEFS & Phis for later passes // Keep track of DEFS & Phis for later passes
defs = new Node_List(); defs = new Node_List();
phis = new Node_List(); phis = new Node_List();
// Gather info on which LRG's are spilling, and build maps // Gather info on which LRG's are spilling, and build maps
for( bidx = 1; bidx < _maxlrg; bidx++ ) { for (bidx = 1; bidx < maxlrg; bidx++) {
if( lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG ) { if (lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG) {
assert(!lrgs(bidx).mask().is_AllStack(),"AllStack should color"); assert(!lrgs(bidx).mask().is_AllStack(),"AllStack should color");
lrg2reach[bidx] = spill_cnt; lrg2reach[bidx] = spill_cnt;
spill_cnt++; spill_cnt++;
...@@ -629,7 +643,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -629,7 +643,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
break; break;
} }
// must be looking at a phi // must be looking at a phi
if( Find_id(n1) == lidxs.at(slidx) ) { if (_lrg_map.find_id(n1) == lidxs.at(slidx)) {
// found the necessary phi // found the necessary phi
needs_phi = false; needs_phi = false;
has_phi = true; has_phi = true;
...@@ -651,11 +665,11 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -651,11 +665,11 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
Reachblock[slidx] = phi; Reachblock[slidx] = phi;
// add node to block & node_to_block mapping // add node to block & node_to_block mapping
insert_proj( b, insidx++, phi, maxlrg++ ); insert_proj(b, insidx++, phi, maxlrg++);
non_phi++; non_phi++;
// Reset new phi's mapping to be the spilling live range // Reset new phi's mapping to be the spilling live range
_names.map(phi->_idx, lidx); _lrg_map.map(phi->_idx, lidx);
assert(Find_id(phi) == lidx,"Bad update on Union-Find mapping"); assert(_lrg_map.find_id(phi) == lidx, "Bad update on Union-Find mapping");
} // end if not found correct phi } // end if not found correct phi
// Here you have either found or created the Phi, so record it // Here you have either found or created the Phi, so record it
assert(phi != NULL,"Must have a Phi Node here"); assert(phi != NULL,"Must have a Phi Node here");
...@@ -721,12 +735,12 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -721,12 +735,12 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
Node *n = b->_nodes[insidx]; Node *n = b->_nodes[insidx];
// Find the defining Node's live range index // Find the defining Node's live range index
uint defidx = Find_id(n); uint defidx = _lrg_map.find_id(n);
uint cnt = n->req(); uint cnt = n->req();
if( n->is_Phi() ) { if (n->is_Phi()) {
// Skip phi nodes after removing dead copies. // Skip phi nodes after removing dead copies.
if( defidx < _maxlrg ) { if (defidx < _lrg_map.max_lrg_id()) {
// Check for useless Phis. These appear if we spill, then // Check for useless Phis. These appear if we spill, then
// coalesce away copies. Dont touch Phis in spilling live // coalesce away copies. Dont touch Phis in spilling live
// ranges; they are busy getting modifed in this pass. // ranges; they are busy getting modifed in this pass.
...@@ -744,8 +758,8 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -744,8 +758,8 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
} }
} }
assert( u, "at least 1 valid input expected" ); assert( u, "at least 1 valid input expected" );
if( i >= cnt ) { // Found one unique input if (i >= cnt) { // Found one unique input
assert(Find_id(n) == Find_id(u), "should be the same lrg"); assert(_lrg_map.find_id(n) == _lrg_map.find_id(u), "should be the same lrg");
n->replace_by(u); // Then replace with unique input n->replace_by(u); // Then replace with unique input
n->disconnect_inputs(NULL, C); n->disconnect_inputs(NULL, C);
b->_nodes.remove(insidx); b->_nodes.remove(insidx);
...@@ -793,16 +807,24 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -793,16 +807,24 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
while( insert_point > 0 ) { while( insert_point > 0 ) {
Node *n = b->_nodes[insert_point]; Node *n = b->_nodes[insert_point];
// Hit top of block? Quit going backwards // Hit top of block? Quit going backwards
if( n->is_Phi() ) break; if (n->is_Phi()) {
break;
}
// Found a def? Better split after it. // Found a def? Better split after it.
if( n2lidx(n) == lidx ) break; if (_lrg_map.live_range_id(n) == lidx) {
break;
}
// Look for a use // Look for a use
uint i; uint i;
for( i = 1; i < n->req(); i++ ) for( i = 1; i < n->req(); i++ ) {
if( n2lidx(n->in(i)) == lidx ) if (_lrg_map.live_range_id(n->in(i)) == lidx) {
break; break;
}
}
// Found a use? Better split after it. // Found a use? Better split after it.
if( i < n->req() ) break; if (i < n->req()) {
break;
}
insert_point--; insert_point--;
} }
uint orig_eidx = b->end_idx(); uint orig_eidx = b->end_idx();
...@@ -812,8 +834,9 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -812,8 +834,9 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
return 0; return 0;
} }
// Spill of NULL check mem op goes into the following block. // Spill of NULL check mem op goes into the following block.
if (b->end_idx() > orig_eidx) if (b->end_idx() > orig_eidx) {
insidx++; insidx++;
}
} }
// This is a new DEF, so update UP // This is a new DEF, so update UP
UPblock[slidx] = false; UPblock[slidx] = false;
...@@ -832,13 +855,13 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -832,13 +855,13 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
} // end if crossing HRP Boundry } // end if crossing HRP Boundry
// If the LRG index is oob, then this is a new spillcopy, skip it. // If the LRG index is oob, then this is a new spillcopy, skip it.
if( defidx >= _maxlrg ) { if (defidx >= _lrg_map.max_lrg_id()) {
continue; continue;
} }
LRG &deflrg = lrgs(defidx); LRG &deflrg = lrgs(defidx);
uint copyidx = n->is_Copy(); uint copyidx = n->is_Copy();
// Remove coalesced copy from CFG // Remove coalesced copy from CFG
if( copyidx && defidx == n2lidx(n->in(copyidx)) ) { if (copyidx && defidx == _lrg_map.live_range_id(n->in(copyidx))) {
n->replace_by( n->in(copyidx) ); n->replace_by( n->in(copyidx) );
n->set_req( copyidx, NULL ); n->set_req( copyidx, NULL );
b->_nodes.remove(insidx--); b->_nodes.remove(insidx--);
...@@ -864,13 +887,13 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -864,13 +887,13 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
// If inpidx > old_last, then one of these new inputs is being // If inpidx > old_last, then one of these new inputs is being
// handled. Skip the derived part of the pair, but process // handled. Skip the derived part of the pair, but process
// the base like any other input. // the base like any other input.
if( inpidx > old_last && ((inpidx - oopoff) & 1) == DERIVED ) { if (inpidx > old_last && ((inpidx - oopoff) & 1) == DERIVED) {
continue; // skip derived_debug added below continue; // skip derived_debug added below
} }
// Get lidx of input // Get lidx of input
uint useidx = Find_id(n->in(inpidx)); uint useidx = _lrg_map.find_id(n->in(inpidx));
// Not a brand-new split, and it is a spill use // Not a brand-new split, and it is a spill use
if( useidx < _maxlrg && lrgs(useidx).reg() >= LRG::SPILL_REG ) { if (useidx < _lrg_map.max_lrg_id() && lrgs(useidx).reg() >= LRG::SPILL_REG) {
// Check for valid reaching DEF // Check for valid reaching DEF
slidx = lrg2reach[useidx]; slidx = lrg2reach[useidx];
Node *def = Reachblock[slidx]; Node *def = Reachblock[slidx];
...@@ -886,7 +909,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -886,7 +909,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
if (def == NULL || C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { if (def == NULL || C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) {
return 0; return 0;
} }
_names.extend(def->_idx,0); _lrg_map.extend(def->_idx, 0);
_cfg._bbs.map(def->_idx,b); _cfg._bbs.map(def->_idx,b);
n->set_req(inpidx, def); n->set_req(inpidx, def);
continue; continue;
...@@ -1186,10 +1209,10 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -1186,10 +1209,10 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
// ********** Split Left Over Mem-Mem Moves ********** // ********** Split Left Over Mem-Mem Moves **********
// Check for mem-mem copies and split them now. Do not do this // Check for mem-mem copies and split them now. Do not do this
// to copies about to be spilled; they will be Split shortly. // to copies about to be spilled; they will be Split shortly.
if( copyidx ) { if (copyidx) {
Node *use = n->in(copyidx); Node *use = n->in(copyidx);
uint useidx = Find_id(use); uint useidx = _lrg_map.find_id(use);
if( useidx < _maxlrg && // This is not a new split if (useidx < _lrg_map.max_lrg_id() && // This is not a new split
OptoReg::is_stack(deflrg.reg()) && OptoReg::is_stack(deflrg.reg()) &&
deflrg.reg() < LRG::SPILL_REG ) { // And DEF is from stack deflrg.reg() < LRG::SPILL_REG ) { // And DEF is from stack
LRG &uselrg = lrgs(useidx); LRG &uselrg = lrgs(useidx);
...@@ -1228,7 +1251,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -1228,7 +1251,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
uint member; uint member;
IndexSetIterator isi(liveout); IndexSetIterator isi(liveout);
while ((member = isi.next()) != 0) { while ((member = isi.next()) != 0) {
assert(defidx != Find_const(member), "Live out member has not been compressed"); assert(defidx != _lrg_map.find_const(member), "Live out member has not been compressed");
} }
#endif #endif
Reachblock[slidx] = NULL; Reachblock[slidx] = NULL;
...@@ -1261,7 +1284,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -1261,7 +1284,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
assert(phi->is_Phi(),"This list must only contain Phi Nodes"); assert(phi->is_Phi(),"This list must only contain Phi Nodes");
Block *b = _cfg._bbs[phi->_idx]; Block *b = _cfg._bbs[phi->_idx];
// Grab the live range number // Grab the live range number
uint lidx = Find_id(phi); uint lidx = _lrg_map.find_id(phi);
uint slidx = lrg2reach[lidx]; uint slidx = lrg2reach[lidx];
// Update node to lidx map // Update node to lidx map
new_lrg(phi, maxlrg++); new_lrg(phi, maxlrg++);
...@@ -1296,11 +1319,13 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -1296,11 +1319,13 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
int insert = pred->end_idx(); int insert = pred->end_idx();
while (insert >= 1 && while (insert >= 1 &&
pred->_nodes[insert - 1]->is_SpillCopy() && pred->_nodes[insert - 1]->is_SpillCopy() &&
Find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) { _lrg_map.find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) {
insert--; insert--;
} }
def = split_Rematerialize( def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false ); def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false);
if( !def ) return 0; // Bail out if (!def) {
return 0; // Bail out
}
} }
// Update the Phi's input edge array // Update the Phi's input edge array
phi->set_req(i,def); phi->set_req(i,def);
...@@ -1316,7 +1341,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -1316,7 +1341,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
} // End for all inputs to the Phi } // End for all inputs to the Phi
} // End for all Phi Nodes } // End for all Phi Nodes
// Update _maxlrg to save Union asserts // Update _maxlrg to save Union asserts
_maxlrg = maxlrg; _lrg_map.set_max_lrg_id(maxlrg);
//----------PASS 3---------- //----------PASS 3----------
...@@ -1328,47 +1353,51 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { ...@@ -1328,47 +1353,51 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
for( uint i = 1; i < phi->req(); i++ ) { for( uint i = 1; i < phi->req(); i++ ) {
// Grab the input node // Grab the input node
Node *n = phi->in(i); Node *n = phi->in(i);
assert( n, "" ); assert(n, "node should exist");
uint lidx = Find(n); uint lidx = _lrg_map.find(n);
uint pidx = Find(phi); uint pidx = _lrg_map.find(phi);
if( lidx < pidx ) if (lidx < pidx) {
Union(n, phi); Union(n, phi);
else if( lidx > pidx ) }
else if(lidx > pidx) {
Union(phi, n); Union(phi, n);
}
} // End for all inputs to the Phi Node } // End for all inputs to the Phi Node
} // End for all Phi Nodes } // End for all Phi Nodes
// Now union all two address instructions // Now union all two address instructions
for( insidx = 0; insidx < defs->size(); insidx++ ) { for (insidx = 0; insidx < defs->size(); insidx++) {
// Grab the def // Grab the def
n1 = defs->at(insidx); n1 = defs->at(insidx);
// Set new lidx for DEF & handle 2-addr instructions // Set new lidx for DEF & handle 2-addr instructions
if( n1->is_Mach() && ((twoidx = n1->as_Mach()->two_adr()) != 0) ) { if (n1->is_Mach() && ((twoidx = n1->as_Mach()->two_adr()) != 0)) {
assert( Find(n1->in(twoidx)) < maxlrg,"Assigning bad live range index"); assert(_lrg_map.find(n1->in(twoidx)) < maxlrg,"Assigning bad live range index");
// Union the input and output live ranges // Union the input and output live ranges
uint lr1 = Find(n1); uint lr1 = _lrg_map.find(n1);
uint lr2 = Find(n1->in(twoidx)); uint lr2 = _lrg_map.find(n1->in(twoidx));
if( lr1 < lr2 ) if (lr1 < lr2) {
Union(n1, n1->in(twoidx)); Union(n1, n1->in(twoidx));
else if( lr1 > lr2 ) }
else if (lr1 > lr2) {
Union(n1->in(twoidx), n1); Union(n1->in(twoidx), n1);
}
} // End if two address } // End if two address
} // End for all defs } // End for all defs
// DEBUG // DEBUG
#ifdef ASSERT #ifdef ASSERT
// Validate all live range index assignments // Validate all live range index assignments
for( bidx = 0; bidx < _cfg._num_blocks; bidx++ ) { for (bidx = 0; bidx < _cfg._num_blocks; bidx++) {
b = _cfg._blocks[bidx]; b = _cfg._blocks[bidx];
for( insidx = 0; insidx <= b->end_idx(); insidx++ ) { for (insidx = 0; insidx <= b->end_idx(); insidx++) {
Node *n = b->_nodes[insidx]; Node *n = b->_nodes[insidx];
uint defidx = Find(n); uint defidx = _lrg_map.find(n);
assert(defidx < _maxlrg,"Bad live range index in Split"); assert(defidx < _lrg_map.max_lrg_id(), "Bad live range index in Split");
assert(defidx < maxlrg,"Bad live range index in Split"); assert(defidx < maxlrg,"Bad live range index in Split");
} }
} }
// Issue a warning if splitting made no progress // Issue a warning if splitting made no progress
int noprogress = 0; int noprogress = 0;
for( slidx = 0; slidx < spill_cnt; slidx++ ) { for (slidx = 0; slidx < spill_cnt; slidx++) {
if( PrintOpto && WizardMode && splits.at(slidx) == 0 ) { if (PrintOpto && WizardMode && splits.at(slidx) == 0) {
tty->print_cr("Failed to split live range %d", lidxs.at(slidx)); tty->print_cr("Failed to split live range %d", lidxs.at(slidx));
//BREAKPOINT; //BREAKPOINT;
} }
......
...@@ -113,7 +113,7 @@ public: ...@@ -113,7 +113,7 @@ public:
OptoReg::Name offset2reg( int stk_offset ) const; OptoReg::Name offset2reg( int stk_offset ) const;
// Get the register encoding associated with the Node // Get the register encoding associated with the Node
int get_encode( const Node *n ) const { int get_encode(const Node *n) const {
assert( n->_idx < _node_regs_max_index, "Exceeded _node_regs array"); assert( n->_idx < _node_regs_max_index, "Exceeded _node_regs array");
OptoReg::Name first = _node_regs[n->_idx].first(); OptoReg::Name first = _node_regs[n->_idx].first();
OptoReg::Name second = _node_regs[n->_idx].second(); OptoReg::Name second = _node_regs[n->_idx].second();
...@@ -122,15 +122,6 @@ public: ...@@ -122,15 +122,6 @@ public:
return Matcher::_regEncode[first]; return Matcher::_regEncode[first];
} }
// Platform dependent hook for actions prior to allocation
void pd_preallocate_hook();
#ifdef ASSERT
// Platform dependent hook for verification after allocation. Will
// only get called when compiling with asserts.
void pd_postallocate_verify_hook();
#endif
#ifndef PRODUCT #ifndef PRODUCT
static int _total_framesize; static int _total_framesize;
static int _max_framesize; static int _max_framesize;
......
...@@ -1115,7 +1115,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary; ...@@ -1115,7 +1115,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
c2_nonstatic_field(PhaseChaitin, _lo_stk_degree, uint) \ c2_nonstatic_field(PhaseChaitin, _lo_stk_degree, uint) \
c2_nonstatic_field(PhaseChaitin, _hi_degree, uint) \ c2_nonstatic_field(PhaseChaitin, _hi_degree, uint) \
c2_nonstatic_field(PhaseChaitin, _simplified, uint) \ c2_nonstatic_field(PhaseChaitin, _simplified, uint) \
c2_nonstatic_field(PhaseChaitin, _maxlrg, uint) \
\ \
c2_nonstatic_field(Block, _nodes, Node_List) \ c2_nonstatic_field(Block, _nodes, Node_List) \
c2_nonstatic_field(Block, _succs, Block_Array) \ c2_nonstatic_field(Block, _succs, Block_Array) \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册