8256827: C2: Avoid reallocations by pre-sizing lists in post_allocate_copy_removal
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
c0689d25fb
commit
b450e7c1c5
@ -2281,11 +2281,6 @@ const RegMask &Node::in_RegMask(uint) const {
|
||||
return RegMask::Empty;
|
||||
}
|
||||
|
||||
// Clear all entries in _nodes to NULL but keep storage
|
||||
void Node_Array::clear() {
|
||||
Copy::zero_to_bytes( _nodes, _max*sizeof(Node*) );
|
||||
}
|
||||
|
||||
void Node_Array::grow(uint i) {
|
||||
assert(_max > 0, "invariant");
|
||||
uint old = _max;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "libadt/vectset.hpp"
|
||||
#include "opto/compile.hpp"
|
||||
#include "opto/type.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
|
||||
// Portions of code courtesy of Clifford Click
|
||||
|
||||
@ -1477,11 +1478,9 @@ protected:
|
||||
Node** _nodes;
|
||||
void grow( uint i ); // Grow array node to fit
|
||||
public:
|
||||
Node_Array(Arena* a) : _a(a), _max(OptoNodeListSize) {
|
||||
_nodes = NEW_ARENA_ARRAY(a, Node*, OptoNodeListSize);
|
||||
for (int i = 0; i < OptoNodeListSize; i++) {
|
||||
_nodes[i] = NULL;
|
||||
}
|
||||
Node_Array(Arena* a, uint max = OptoNodeListSize) : _a(a), _max(max) {
|
||||
_nodes = NEW_ARENA_ARRAY(a, Node*, max);
|
||||
clear();
|
||||
}
|
||||
|
||||
Node_Array(Node_Array* na) : _a(na->_a), _max(na->_max), _nodes(na->_nodes) {}
|
||||
@ -1493,7 +1492,11 @@ public:
|
||||
void map( uint i, Node *n ) { if( i>=_max ) grow(i); _nodes[i] = n; }
|
||||
void insert( uint i, Node *n );
|
||||
void remove( uint i ); // Remove, preserving order
|
||||
void clear(); // Set all entries to NULL, keep storage
|
||||
// Clear all entries in _nodes to NULL but keep storage
|
||||
void clear() {
|
||||
Copy::zero_to_bytes(_nodes, _max * sizeof(Node*));
|
||||
}
|
||||
|
||||
uint Size() const { return _max; }
|
||||
void dump() const;
|
||||
};
|
||||
@ -1502,8 +1505,8 @@ class Node_List : public Node_Array {
|
||||
friend class VMStructs;
|
||||
uint _cnt;
|
||||
public:
|
||||
Node_List() : Node_Array(Thread::current()->resource_area()), _cnt(0) {}
|
||||
Node_List(Arena *a) : Node_Array(a), _cnt(0) {}
|
||||
Node_List(uint max = OptoNodeListSize) : Node_Array(Thread::current()->resource_area(), max), _cnt(0) {}
|
||||
Node_List(Arena *a, uint max = OptoNodeListSize) : Node_Array(a, max), _cnt(0) {}
|
||||
bool contains(const Node* n) const {
|
||||
for (uint e = 0; e < size(); e++) {
|
||||
if (at(e) == n) return true;
|
||||
@ -1516,6 +1519,14 @@ public:
|
||||
void yank( Node *n ); // Find and remove
|
||||
Node *pop() { return _nodes[--_cnt]; }
|
||||
void clear() { _cnt = 0; Node_Array::clear(); } // retain storage
|
||||
void copy(const Node_List& from) {
|
||||
if (from._max > _max) {
|
||||
grow(from._max);
|
||||
}
|
||||
_cnt = from._cnt;
|
||||
Copy::conjoint_words_to_higher((HeapWord*)&from._nodes[0], (HeapWord*)&_nodes[0], from._max * sizeof(Node*));
|
||||
}
|
||||
|
||||
uint size() const { return _cnt; }
|
||||
void dump() const;
|
||||
void dump_simple() const;
|
||||
|
@ -558,35 +558,28 @@ void PhaseChaitin::post_allocate_copy_removal() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Extract Node_List mappings. If 'freed' is non-zero, we just popped
|
||||
// 'freed's blocks off the list
|
||||
Node_List ®nd = *(free_list.is_empty() ? new Node_List() : free_list.pop());
|
||||
Node_List &value = *(free_list.is_empty() ? new Node_List() : free_list.pop());
|
||||
Node_List ®nd = *(free_list.is_empty() ? new Node_List(_max_reg) : free_list.pop());
|
||||
Node_List &value = *(free_list.is_empty() ? new Node_List(_max_reg) : free_list.pop());
|
||||
assert( !freed || blk2value[freed->_pre_order] == &value, "" );
|
||||
value.map(_max_reg,NULL);
|
||||
regnd.map(_max_reg,NULL);
|
||||
// Set mappings as OUR mappings
|
||||
blk2value[block->_pre_order] = &value;
|
||||
blk2regnd[block->_pre_order] = ®nd;
|
||||
|
||||
// Initialize value & regnd for this block
|
||||
if (missing_some_inputs) {
|
||||
// Some predecessor has not yet been visited; zap map to empty
|
||||
for (uint k = 0; k < (uint)_max_reg; k++) {
|
||||
value.map(k,NULL);
|
||||
regnd.map(k,NULL);
|
||||
// Some predecessor has not yet been visited; zap map to empty if necessary
|
||||
if (freed) {
|
||||
value.clear();
|
||||
regnd.clear();
|
||||
}
|
||||
} else {
|
||||
if( !freed ) { // Didn't get a freebie prior block
|
||||
if (!freed) { // Didn't get a freebie prior block
|
||||
// Must clone some data
|
||||
freed = _cfg.get_block_for_node(block->pred(1));
|
||||
Node_List &f_value = *blk2value[freed->_pre_order];
|
||||
Node_List &f_regnd = *blk2regnd[freed->_pre_order];
|
||||
for( uint k = 0; k < (uint)_max_reg; k++ ) {
|
||||
value.map(k,f_value[k]);
|
||||
regnd.map(k,f_regnd[k]);
|
||||
}
|
||||
value.copy(*blk2value[freed->_pre_order]);
|
||||
regnd.copy(*blk2regnd[freed->_pre_order]);
|
||||
}
|
||||
// Merge all inputs together, setting to NULL any conflicts.
|
||||
for (j = 1; j < block->num_preds(); j++) {
|
||||
@ -595,10 +588,10 @@ void PhaseChaitin::post_allocate_copy_removal() {
|
||||
continue; // Did self already via freelist
|
||||
}
|
||||
Node_List &p_regnd = *blk2regnd[pb->_pre_order];
|
||||
for( uint k = 0; k < (uint)_max_reg; k++ ) {
|
||||
if( regnd[k] != p_regnd[k] ) { // Conflict on reaching defs?
|
||||
value.map(k,NULL); // Then no value handy
|
||||
regnd.map(k,NULL);
|
||||
for (uint k = 0; k < (uint)_max_reg; k++) {
|
||||
if (regnd[k] != p_regnd[k]) { // Conflict on reaching defs?
|
||||
value.map(k, NULL); // Then no value handy
|
||||
regnd.map(k, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -634,14 +627,14 @@ void PhaseChaitin::post_allocate_copy_removal() {
|
||||
// can lead to situations where some uses are from the old and some from
|
||||
// the new values. Not illegal by itself but throws the over-strong
|
||||
// assert in scheduling.
|
||||
if( pidx ) {
|
||||
value.map(preg,phi);
|
||||
regnd.map(preg,phi);
|
||||
if (pidx) {
|
||||
value.map(preg, phi);
|
||||
regnd.map(preg, phi);
|
||||
int n_regs = RegMask::num_registers(phi->ideal_reg(), lrgs(pidx));
|
||||
for (int l = 1; l < n_regs; l++) {
|
||||
OptoReg::Name preg_lo = OptoReg::add(preg,-l);
|
||||
value.map(preg_lo,phi);
|
||||
regnd.map(preg_lo,phi);
|
||||
value.map(preg_lo, phi);
|
||||
regnd.map(preg_lo, phi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user