Skip to content

Commit 8d190dd

Browse files
LudwikJaniukNils Eliasson
authored andcommitted
8277496: Remove duplication in c1 Block successor lists
Reviewed-by: neliasso, kvn
1 parent 194cdf4 commit 8d190dd

File tree

8 files changed

+121
-105
lines changed

8 files changed

+121
-105
lines changed

src/hotspot/share/c1/c1_CFGPrinter.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,7 @@ void CFGPrinterOutput::print_LIR(BlockBegin* block) {
231231

232232
void CFGPrinterOutput::print_block(BlockBegin* block) {
233233
print_begin("block");
234-
235234
print("name \"B%d\"", block->block_id());
236-
237235
print("from_bci %d", block->bci());
238236
print("to_bci %d", (block->end() == NULL ? -1 : block->end()->printable_bci()));
239237

@@ -246,9 +244,13 @@ void CFGPrinterOutput::print_block(BlockBegin* block) {
246244
output()->cr();
247245

248246
output()->indent();
249-
output()->print("successors ");
250-
for (i = 0; i < block->number_of_sux(); i++) {
251-
output()->print("\"B%d\" ", block->sux_at(i)->block_id());
247+
if (block->end() != NULL) {
248+
output()->print("successors ");
249+
for (i = 0; i < block->number_of_sux(); i++) {
250+
output()->print("\"B%d\" ", block->sux_at(i)->block_id());
251+
}
252+
} else {
253+
output()->print("(block has no end, cannot print successors)");
252254
}
253255
output()->cr();
254256

src/hotspot/share/c1/c1_GraphBuilder.cpp

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class BlockListBuilder {
5353

5454
BlockList _blocks; // internal list of all blocks
5555
BlockList* _bci2block; // mapping from bci to blocks for GraphBuilder
56+
GrowableArray<BlockList> _bci2block_successors; // Mapping bcis to their blocks successors while we dont have a blockend
5657

5758
// fields used by mark_loops
5859
ResourceBitMap _active; // for iteration of control flow graph
@@ -89,6 +90,11 @@ class BlockListBuilder {
8990
void print();
9091
#endif
9192

93+
int number_of_successors(BlockBegin* block);
94+
BlockBegin* successor_at(BlockBegin* block, int i);
95+
void add_successor(BlockBegin* block, BlockBegin* sux);
96+
bool is_successor(BlockBegin* block, BlockBegin* sux);
97+
9298
public:
9399
// creation
94100
BlockListBuilder(Compilation* compilation, IRScope* scope, int osr_bci);
@@ -105,6 +111,7 @@ BlockListBuilder::BlockListBuilder(Compilation* compilation, IRScope* scope, int
105111
, _scope(scope)
106112
, _blocks(16)
107113
, _bci2block(new BlockList(scope->method()->code_size(), NULL))
114+
, _bci2block_successors(scope->method()->code_size())
108115
, _active() // size not known yet
109116
, _visited() // size not known yet
110117
, _loop_map() // size not known yet
@@ -118,6 +125,8 @@ BlockListBuilder::BlockListBuilder(Compilation* compilation, IRScope* scope, int
118125
mark_loops();
119126
NOT_PRODUCT(if (PrintInitialBlockList) print());
120127

128+
// _bci2block still contains blocks with _end == null and > 0 sux in _bci2block_successors.
129+
121130
#ifndef PRODUCT
122131
if (PrintCFGToFile) {
123132
stringStream title;
@@ -160,6 +169,7 @@ BlockBegin* BlockListBuilder::make_block_at(int cur_bci, BlockBegin* predecessor
160169
block = new BlockBegin(cur_bci);
161170
block->init_stores_to_locals(method()->max_locals());
162171
_bci2block->at_put(cur_bci, block);
172+
_bci2block_successors.at_put_grow(cur_bci, BlockList());
163173
_blocks.append(block);
164174

165175
assert(predecessor == NULL || predecessor->bci() < cur_bci, "targets for backward branches must already exist");
@@ -170,7 +180,7 @@ BlockBegin* BlockListBuilder::make_block_at(int cur_bci, BlockBegin* predecessor
170180
BAILOUT_("Exception handler can be reached by both normal and exceptional control flow", block);
171181
}
172182

173-
predecessor->add_successor(block);
183+
add_successor(predecessor, block);
174184
block->increment_total_preds();
175185
}
176186

@@ -201,8 +211,8 @@ void BlockListBuilder::handle_exceptions(BlockBegin* current, int cur_bci) {
201211
assert(entry->is_set(BlockBegin::exception_entry_flag), "flag must be set");
202212

203213
// add each exception handler only once
204-
if (!current->is_successor(entry)) {
205-
current->add_successor(entry);
214+
if(!is_successor(current, entry)) {
215+
add_successor(current, entry);
206216
entry->increment_total_preds();
207217
}
208218

@@ -418,9 +428,9 @@ int BlockListBuilder::mark_loops(BlockBegin* block, bool in_subroutine) {
418428
_active.set_bit(block_id);
419429

420430
intptr_t loop_state = 0;
421-
for (int i = block->number_of_sux() - 1; i >= 0; i--) {
431+
for (int i = number_of_successors(block) - 1; i >= 0; i--) {
422432
// recursively process all successors
423-
loop_state |= mark_loops(block->sux_at(i), in_subroutine);
433+
loop_state |= mark_loops(successor_at(block, i), in_subroutine);
424434
}
425435

426436
// clear active-bit after all successors are processed
@@ -452,6 +462,28 @@ int BlockListBuilder::mark_loops(BlockBegin* block, bool in_subroutine) {
452462
return loop_state;
453463
}
454464

465+
inline int BlockListBuilder::number_of_successors(BlockBegin* block)
466+
{
467+
assert(_bci2block_successors.length() > block->bci(), "sux must exist");
468+
return _bci2block_successors.at(block->bci()).length();
469+
}
470+
471+
inline BlockBegin* BlockListBuilder::successor_at(BlockBegin* block, int i)
472+
{
473+
assert(_bci2block_successors.length() > block->bci(), "sux must exist");
474+
return _bci2block_successors.at(block->bci()).at(i);
475+
}
476+
477+
inline void BlockListBuilder::add_successor(BlockBegin* block, BlockBegin* sux)
478+
{
479+
assert(_bci2block_successors.length() > block->bci(), "sux must exist");
480+
_bci2block_successors.at(block->bci()).append(sux);
481+
}
482+
483+
inline bool BlockListBuilder::is_successor(BlockBegin* block, BlockBegin* sux) {
484+
assert(_bci2block_successors.length() > block->bci(), "sux must exist");
485+
return _bci2block_successors.at(block->bci()).contains(sux);
486+
}
455487

456488
#ifndef PRODUCT
457489

@@ -477,10 +509,10 @@ void BlockListBuilder::print() {
477509
tty->print(cur->is_set(BlockBegin::subroutine_entry_flag) ? " sr" : " ");
478510
tty->print(cur->is_set(BlockBegin::parser_loop_header_flag) ? " lh" : " ");
479511

480-
if (cur->number_of_sux() > 0) {
512+
if (number_of_successors(cur) > 0) {
481513
tty->print(" sux: ");
482-
for (int j = 0; j < cur->number_of_sux(); j++) {
483-
BlockBegin* sux = cur->sux_at(j);
514+
for (int j = 0; j < number_of_successors(cur); j++) {
515+
BlockBegin* sux = successor_at(cur, j);
484516
tty->print("B%d ", sux->block_id());
485517
}
486518
}
@@ -3230,6 +3262,8 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
32303262
_initial_state = state_at_entry();
32313263
start_block->merge(_initial_state);
32323264

3265+
// End nulls still exist here
3266+
32333267
// complete graph
32343268
_vmap = new ValueMap();
32353269
switch (scope->method()->intrinsic_id()) {
@@ -3333,6 +3367,27 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
33333367
}
33343368
CHECK_BAILOUT();
33353369

3370+
# ifdef ASSERT
3371+
//All blocks reachable from start_block have _end != NULL
3372+
{
3373+
BlockList processed;
3374+
BlockList to_go;
3375+
to_go.append(start_block);
3376+
while(to_go.length() > 0) {
3377+
BlockBegin* current = to_go.pop();
3378+
assert(current != NULL, "Should not happen.");
3379+
assert(current->end() != NULL, "All blocks reachable from start_block should have end() != NULL.");
3380+
processed.append(current);
3381+
for(int i = 0; i < current->number_of_sux(); i++) {
3382+
BlockBegin* s = current->sux_at(i);
3383+
if (!processed.contains(s)) {
3384+
to_go.append(s);
3385+
}
3386+
}
3387+
}
3388+
}
3389+
#endif // ASSERT
3390+
33363391
_start = setup_start_block(osr_bci, start_block, _osr_entry, _initial_state);
33373392

33383393
eliminate_redundant_phis(_start);

src/hotspot/share/c1/c1_IR.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,16 @@ void IR::print(bool cfg_only, bool live_only) {
12611261
}
12621262
}
12631263

1264+
class EndNotNullValidator : public BlockClosure {
1265+
public:
1266+
EndNotNullValidator(IR* hir) {
1267+
hir->start()->iterate_postorder(this);
1268+
}
1269+
1270+
void block_do(BlockBegin* block) {
1271+
assert(block->end() != NULL, "Expect block end to exist.");
1272+
}
1273+
};
12641274

12651275
typedef GrowableArray<BlockList*> BlockListList;
12661276

@@ -1363,6 +1373,7 @@ class VerifyBlockBeginField : public BlockClosure {
13631373
void IR::verify() {
13641374
#ifdef ASSERT
13651375
PredecessorValidator pv(this);
1376+
EndNotNullValidator(this);
13661377
VerifyBlockBeginField verifier;
13671378
this->iterate_postorder(&verifier);
13681379
#endif

src/hotspot/share/c1/c1_Instruction.cpp

Lines changed: 12 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -524,39 +524,21 @@ Constant::CompareResult Constant::compare(Instruction::Condition cond, Value rig
524524

525525
// Implementation of BlockBegin
526526

527-
void BlockBegin::set_end(BlockEnd* end) {
528-
assert(end != NULL, "should not reset block end to NULL");
529-
if (end == _end) {
530-
return;
531-
}
532-
clear_end();
533-
534-
// Set the new end
535-
_end = end;
527+
void BlockBegin::set_end(BlockEnd* new_end) { // Assumes that no predecessor of new_end still has it as its successor
528+
assert(new_end != NULL, "Should not reset block new_end to NULL");
529+
if (new_end == _end) return;
536530

537-
_successors.clear();
538-
// Now reset successors list based on BlockEnd
539-
for (int i = 0; i < end->number_of_sux(); i++) {
540-
BlockBegin* sux = end->sux_at(i);
541-
_successors.append(sux);
542-
sux->_predecessors.append(this);
531+
// Remove this block as predecessor of its current successors
532+
if (_end != NULL)
533+
for (int i = 0; i < number_of_sux(); i++) {
534+
sux_at(i)->remove_predecessor(this);
543535
}
544-
_end->set_begin(this);
545-
}
546-
547536

548-
void BlockBegin::clear_end() {
549-
// Must make the predecessors/successors match up with the
550-
// BlockEnd's notion.
551-
if (_end != NULL) {
552-
// disconnect from the old end
553-
_end->set_begin(NULL);
537+
_end = new_end;
554538

555-
// disconnect this block from it's current successors
556-
for (int i = 0; i < _successors.length(); i++) {
557-
_successors.at(i)->remove_predecessor(this);
558-
}
559-
_end = NULL;
539+
// Add this block as predecessor of its new successors
540+
for (int i = 0; i < number_of_sux(); i++) {
541+
sux_at(i)->add_predecessor(this);
560542
}
561543
}
562544

@@ -575,24 +557,14 @@ void BlockBegin::disconnect_edge(BlockBegin* from, BlockBegin* to) {
575557
if (index >= 0) {
576558
sux->_predecessors.remove_at(index);
577559
}
578-
from->_successors.remove_at(s);
560+
from->end()->remove_sux_at(s);
579561
} else {
580562
s++;
581563
}
582564
}
583565
}
584566

585567

586-
void BlockBegin::disconnect_from_graph() {
587-
// disconnect this block from all other blocks
588-
for (int p = 0; p < number_of_preds(); p++) {
589-
pred_at(p)->remove_successor(this);
590-
}
591-
for (int s = 0; s < number_of_sux(); s++) {
592-
sux_at(s)->remove_predecessor(this);
593-
}
594-
}
595-
596568
void BlockBegin::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) {
597569
// modify predecessors before substituting successors
598570
for (int i = 0; i < number_of_sux(); i++) {
@@ -669,14 +641,6 @@ BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) {
669641
}
670642

671643

672-
void BlockBegin::remove_successor(BlockBegin* pred) {
673-
int idx;
674-
while ((idx = _successors.find(pred)) >= 0) {
675-
_successors.remove_at(idx);
676-
}
677-
}
678-
679-
680644
void BlockBegin::add_predecessor(BlockBegin* pred) {
681645
_predecessors.append(pred);
682646
}
@@ -953,26 +917,10 @@ void BlockList::print(bool cfg_only, bool live_only) {
953917

954918
// Implementation of BlockEnd
955919

956-
void BlockEnd::set_begin(BlockBegin* begin) {
957-
BlockList* sux = NULL;
958-
if (begin != NULL) {
959-
sux = begin->successors();
960-
} else if (this->begin() != NULL) {
961-
// copy our sux list
962-
BlockList* sux = new BlockList(this->begin()->number_of_sux());
963-
for (int i = 0; i < this->begin()->number_of_sux(); i++) {
964-
sux->append(this->begin()->sux_at(i));
965-
}
966-
}
967-
_sux = sux;
968-
}
969-
970-
971920
void BlockEnd::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) {
972921
substitute(*_sux, old_sux, new_sux);
973922
}
974923

975-
976924
// Implementation of Phi
977925

978926
// Normal phi functions take their operands from the last instruction of the

0 commit comments

Comments
 (0)