Skip to content

Commit b450e7c

Browse files
committed
8256827: C2: Avoid reallocations by pre-sizing lists in post_allocate_copy_removal
Reviewed-by: kvn, thartmann
1 parent c0689d2 commit b450e7c

File tree

3 files changed

+37
-38
lines changed

3 files changed

+37
-38
lines changed

src/hotspot/share/opto/node.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,11 +2281,6 @@ const RegMask &Node::in_RegMask(uint) const {
22812281
return RegMask::Empty;
22822282
}
22832283

2284-
// Clear all entries in _nodes to NULL but keep storage
2285-
void Node_Array::clear() {
2286-
Copy::zero_to_bytes( _nodes, _max*sizeof(Node*) );
2287-
}
2288-
22892284
void Node_Array::grow(uint i) {
22902285
assert(_max > 0, "invariant");
22912286
uint old = _max;

src/hotspot/share/opto/node.hpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "libadt/vectset.hpp"
2929
#include "opto/compile.hpp"
3030
#include "opto/type.hpp"
31+
#include "utilities/copy.hpp"
3132

3233
// Portions of code courtesy of Clifford Click
3334

@@ -1477,11 +1478,9 @@ class Node_Array : public ResourceObj {
14771478
Node** _nodes;
14781479
void grow( uint i ); // Grow array node to fit
14791480
public:
1480-
Node_Array(Arena* a) : _a(a), _max(OptoNodeListSize) {
1481-
_nodes = NEW_ARENA_ARRAY(a, Node*, OptoNodeListSize);
1482-
for (int i = 0; i < OptoNodeListSize; i++) {
1483-
_nodes[i] = NULL;
1484-
}
1481+
Node_Array(Arena* a, uint max = OptoNodeListSize) : _a(a), _max(max) {
1482+
_nodes = NEW_ARENA_ARRAY(a, Node*, max);
1483+
clear();
14851484
}
14861485

14871486
Node_Array(Node_Array* na) : _a(na->_a), _max(na->_max), _nodes(na->_nodes) {}
@@ -1493,7 +1492,11 @@ class Node_Array : public ResourceObj {
14931492
void map( uint i, Node *n ) { if( i>=_max ) grow(i); _nodes[i] = n; }
14941493
void insert( uint i, Node *n );
14951494
void remove( uint i ); // Remove, preserving order
1496-
void clear(); // Set all entries to NULL, keep storage
1495+
// Clear all entries in _nodes to NULL but keep storage
1496+
void clear() {
1497+
Copy::zero_to_bytes(_nodes, _max * sizeof(Node*));
1498+
}
1499+
14971500
uint Size() const { return _max; }
14981501
void dump() const;
14991502
};
@@ -1502,8 +1505,8 @@ class Node_List : public Node_Array {
15021505
friend class VMStructs;
15031506
uint _cnt;
15041507
public:
1505-
Node_List() : Node_Array(Thread::current()->resource_area()), _cnt(0) {}
1506-
Node_List(Arena *a) : Node_Array(a), _cnt(0) {}
1508+
Node_List(uint max = OptoNodeListSize) : Node_Array(Thread::current()->resource_area(), max), _cnt(0) {}
1509+
Node_List(Arena *a, uint max = OptoNodeListSize) : Node_Array(a, max), _cnt(0) {}
15071510
bool contains(const Node* n) const {
15081511
for (uint e = 0; e < size(); e++) {
15091512
if (at(e) == n) return true;
@@ -1516,6 +1519,14 @@ class Node_List : public Node_Array {
15161519
void yank( Node *n ); // Find and remove
15171520
Node *pop() { return _nodes[--_cnt]; }
15181521
void clear() { _cnt = 0; Node_Array::clear(); } // retain storage
1522+
void copy(const Node_List& from) {
1523+
if (from._max > _max) {
1524+
grow(from._max);
1525+
}
1526+
_cnt = from._cnt;
1527+
Copy::conjoint_words_to_higher((HeapWord*)&from._nodes[0], (HeapWord*)&_nodes[0], from._max * sizeof(Node*));
1528+
}
1529+
15191530
uint size() const { return _cnt; }
15201531
void dump() const;
15211532
void dump_simple() const;

src/hotspot/share/opto/postaloc.cpp

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -558,35 +558,28 @@ void PhaseChaitin::post_allocate_copy_removal() {
558558
}
559559
}
560560

561-
562561
// Extract Node_List mappings. If 'freed' is non-zero, we just popped
563562
// 'freed's blocks off the list
564-
Node_List &regnd = *(free_list.is_empty() ? new Node_List() : free_list.pop());
565-
Node_List &value = *(free_list.is_empty() ? new Node_List() : free_list.pop());
563+
Node_List &regnd = *(free_list.is_empty() ? new Node_List(_max_reg) : free_list.pop());
564+
Node_List &value = *(free_list.is_empty() ? new Node_List(_max_reg) : free_list.pop());
566565
assert( !freed || blk2value[freed->_pre_order] == &value, "" );
567-
value.map(_max_reg,NULL);
568-
regnd.map(_max_reg,NULL);
569566
// Set mappings as OUR mappings
570567
blk2value[block->_pre_order] = &value;
571568
blk2regnd[block->_pre_order] = &regnd;
572569

573570
// Initialize value & regnd for this block
574571
if (missing_some_inputs) {
575-
// Some predecessor has not yet been visited; zap map to empty
576-
for (uint k = 0; k < (uint)_max_reg; k++) {
577-
value.map(k,NULL);
578-
regnd.map(k,NULL);
572+
// Some predecessor has not yet been visited; zap map to empty if necessary
573+
if (freed) {
574+
value.clear();
575+
regnd.clear();
579576
}
580577
} else {
581-
if( !freed ) { // Didn't get a freebie prior block
578+
if (!freed) { // Didn't get a freebie prior block
582579
// Must clone some data
583580
freed = _cfg.get_block_for_node(block->pred(1));
584-
Node_List &f_value = *blk2value[freed->_pre_order];
585-
Node_List &f_regnd = *blk2regnd[freed->_pre_order];
586-
for( uint k = 0; k < (uint)_max_reg; k++ ) {
587-
value.map(k,f_value[k]);
588-
regnd.map(k,f_regnd[k]);
589-
}
581+
value.copy(*blk2value[freed->_pre_order]);
582+
regnd.copy(*blk2regnd[freed->_pre_order]);
590583
}
591584
// Merge all inputs together, setting to NULL any conflicts.
592585
for (j = 1; j < block->num_preds(); j++) {
@@ -595,10 +588,10 @@ void PhaseChaitin::post_allocate_copy_removal() {
595588
continue; // Did self already via freelist
596589
}
597590
Node_List &p_regnd = *blk2regnd[pb->_pre_order];
598-
for( uint k = 0; k < (uint)_max_reg; k++ ) {
599-
if( regnd[k] != p_regnd[k] ) { // Conflict on reaching defs?
600-
value.map(k,NULL); // Then no value handy
601-
regnd.map(k,NULL);
591+
for (uint k = 0; k < (uint)_max_reg; k++) {
592+
if (regnd[k] != p_regnd[k]) { // Conflict on reaching defs?
593+
value.map(k, NULL); // Then no value handy
594+
regnd.map(k, NULL);
602595
}
603596
}
604597
}
@@ -634,14 +627,14 @@ void PhaseChaitin::post_allocate_copy_removal() {
634627
// can lead to situations where some uses are from the old and some from
635628
// the new values. Not illegal by itself but throws the over-strong
636629
// assert in scheduling.
637-
if( pidx ) {
638-
value.map(preg,phi);
639-
regnd.map(preg,phi);
630+
if (pidx) {
631+
value.map(preg, phi);
632+
regnd.map(preg, phi);
640633
int n_regs = RegMask::num_registers(phi->ideal_reg(), lrgs(pidx));
641634
for (int l = 1; l < n_regs; l++) {
642635
OptoReg::Name preg_lo = OptoReg::add(preg,-l);
643-
value.map(preg_lo,phi);
644-
regnd.map(preg_lo,phi);
636+
value.map(preg_lo, phi);
637+
regnd.map(preg_lo, phi);
645638
}
646639
}
647640
}

0 commit comments

Comments
 (0)