Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 33 additions & 14 deletions src/hotspot/share/opto/chaitin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,41 +220,60 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher, bool sc
_high_frequency_lrg = MIN2(double(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency());

// Build a list of basic blocks, sorted by frequency
_blks = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());
// Experiment with sorting strategies to speed compilation
uint nr_blocks = _cfg.number_of_blocks();
double cutoff = BLOCK_FREQUENCY(1.0); // Cutoff for high frequency bucket
Block **buckets[NUMBUCKS]; // Array of buckets
uint buckcnt[NUMBUCKS]; // Array of bucket counters
double buckval[NUMBUCKS]; // Array of bucket value cutoffs

// The space which our buckets point into.
Block** start = NEW_RESOURCE_ARRAY(Block *, nr_blocks*NUMBUCKS);

for (uint i = 0; i < NUMBUCKS; i++) {
buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());
buckets[i] = &start[i*nr_blocks];
buckcnt[i] = 0;
// Bump by three orders of magnitude each time
cutoff *= 0.001;
buckval[i] = cutoff;
for (uint j = 0; j < _cfg.number_of_blocks(); j++) {
buckets[i][j] = nullptr;
}
}

// Sort blocks into buckets
for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
for (uint i = 0; i < nr_blocks; i++) {
for (uint j = 0; j < NUMBUCKS; j++) {
if ((j == NUMBUCKS - 1) || (_cfg.get_block(i)->_freq > buckval[j])) {
double bval = buckval[j];
Block* blk = _cfg.get_block(i);
if (j == NUMBUCKS - 1 || blk->_freq > bval) {
uint cnt = buckcnt[j];
// Assign block to end of list for appropriate bucket
buckets[j][buckcnt[j]++] = _cfg.get_block(i);
buckets[j][cnt] = blk;
buckcnt[j] = cnt+1;
break; // kick out of inner loop
}
}
}
// Dump buckets into final block array

// Squash the partially filled buckets together into the first one.
static_assert(NUMBUCKS >= 2, "must"); // If this isn't true then it'll mess up the squashing.
Block** offset = &buckets[0][buckcnt[0]];
for (int i = 1; i < NUMBUCKS; i++) {
::memmove(offset, buckets[i], buckcnt[i]*sizeof(Block*));
offset += buckcnt[i];
}
assert((&buckets[0][0] + nr_blocks) == offset, "should be");

// Free the now unused memory
FREE_RESOURCE_ARRAY(Block*, buckets[1], (NUMBUCKS-1)*nr_blocks);
// Finally, point the _blks to our memory
_blks = buckets[0];

#ifdef ASSERT
uint blkcnt = 0;
for (uint i = 0; i < NUMBUCKS; i++) {
for (uint j = 0; j < buckcnt[i]; j++) {
_blks[blkcnt++] = buckets[i][j];
}
blkcnt += buckcnt[i];
}

assert(blkcnt == _cfg.number_of_blocks(), "Block array not totally filled");
assert(blkcnt == nr_blocks, "Block array not totally filled");
#endif
}

// union 2 sets together.
Expand Down