Mercurial > hg > truffle
diff src/share/vm/opto/output.cpp @ 12355:cefad50507d8
Merge with hs25-b53
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Fri, 11 Oct 2013 10:38:03 +0200 |
parents | 3cce976666d9 650868c062a9 |
children | d8041d695d19 |
line wrap: on
line diff
--- a/src/share/vm/opto/output.cpp Thu Oct 10 18:26:22 2013 +0200 +++ b/src/share/vm/opto/output.cpp Fri Oct 11 10:38:03 2013 +0200 @@ -54,11 +54,10 @@ extern int emit_exception_handler(CodeBuffer &cbuf); extern int emit_deopt_handler(CodeBuffer &cbuf); -//------------------------------Output----------------------------------------- // Convert Nodes to instruction bits and pass off to the VM void Compile::Output() { // RootNode goes - assert( _cfg->_broot->_nodes.size() == 0, "" ); + assert( _cfg->get_root_block()->number_of_nodes() == 0, "" ); // The number of new nodes (mostly MachNop) is proportional to // the number of java calls and inner loops which are aligned. @@ -68,14 +67,14 @@ return; } // Make sure I can find the Start Node - Block *entry = _cfg->_blocks[1]; - Block *broot = _cfg->_broot; - - const StartNode *start = entry->_nodes[0]->as_Start(); + Block *entry = _cfg->get_block(1); + Block *broot = _cfg->get_root_block(); + + const StartNode *start = entry->head()->as_Start(); // Replace StartNode with prolog MachPrologNode *prolog = new (this) MachPrologNode(); - entry->_nodes.map( 0, prolog ); + entry->map_node(prolog, 0); _cfg->map_node_to_block(prolog, entry); _cfg->unmap_node_from_block(start); // start is no longer in any block @@ -109,40 +108,44 @@ } // Insert epilogs before every return - for( uint i=0; i<_cfg->_num_blocks; i++ ) { - Block *b = _cfg->_blocks[i]; - if( !b->is_connector() && b->non_connector_successor(0) == _cfg->_broot ) { // Found a program exit point? - Node *m = b->end(); - if( m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt ) { - MachEpilogNode *epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return); - b->add_inst( epilog ); - _cfg->map_node_to_block(epilog, b); + for (uint i = 0; i < _cfg->number_of_blocks(); i++) { + Block* block = _cfg->get_block(i); + if (!block->is_connector() && block->non_connector_successor(0) == _cfg->get_root_block()) { // Found a program exit point? + Node* m = block->end(); + if (m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt) { + MachEpilogNode* epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return); + block->add_inst(epilog); + _cfg->map_node_to_block(epilog, block); } } } # ifdef ENABLE_ZAP_DEAD_LOCALS - if ( ZapDeadCompiledLocals ) Insert_zap_nodes(); + if (ZapDeadCompiledLocals) { + Insert_zap_nodes(); + } # endif - uint* blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1); - blk_starts[0] = 0; + uint* blk_starts = NEW_RESOURCE_ARRAY(uint, _cfg->number_of_blocks() + 1); + blk_starts[0] = 0; // Initialize code buffer and process short branches. CodeBuffer* cb = init_buffer(blk_starts); - if (cb == NULL || failing()) return; + if (cb == NULL || failing()) { + return; + } ScheduleAndBundle(); #ifndef PRODUCT if (trace_opto_output()) { tty->print("\n---- After ScheduleAndBundle ----\n"); - for (uint i = 0; i < _cfg->_num_blocks; i++) { + for (uint i = 0; i < _cfg->number_of_blocks(); i++) { tty->print("\nBB#%03d:\n", i); - Block *bb = _cfg->_blocks[i]; - for (uint j = 0; j < bb->_nodes.size(); j++) { - Node *n = bb->_nodes[j]; + Block* block = _cfg->get_block(i); + for (uint j = 0; j < block->number_of_nodes(); j++) { + Node* n = block->get_node(j); OptoReg::Name reg = _regalloc->get_reg_first(n); tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : ""); n->dump(); @@ -151,11 +154,15 @@ } #endif - if (failing()) return; + if (failing()) { + return; + } BuildOopMaps(); - if (failing()) return; + if (failing()) { + return; + } fill_buffer(cb, blk_starts); } @@ -217,10 +224,10 @@ return; // no safepoints/oopmaps emitted for calls in stubs,so we don't care // Insert call to zap runtime stub before every node with an oop map - for( uint i=0; i<_cfg->_num_blocks; i++ ) { - Block *b = _cfg->_blocks[i]; - for ( uint j = 0; j < b->_nodes.size(); ++j ) { - Node *n = b->_nodes[j]; + for( uint i=0; i<_cfg->number_of_blocks(); i++ ) { + Block *b = _cfg->get_block(i); + for ( uint j = 0; j < b->number_of_nodes(); ++j ) { + Node *n = b->get_node(j); // Determining if we should insert a zap-a-lot node in output. // We do that for all nodes that has oopmap info, except for calls @@ -249,7 +256,7 @@ } if (insert) { Node *zap = call_zap_node(n->as_MachSafePoint(), i); - b->_nodes.insert( j, zap ); + b->insert_node(zap, j); _cfg->map_node_to_block(zap, b); ++j; } @@ -275,7 +282,6 @@ return _matcher->match_sfpt(ideal_node); } -//------------------------------is_node_getting_a_safepoint-------------------- bool Compile::is_node_getting_a_safepoint( Node* n) { // This code duplicates the logic prior to the call of add_safepoint // below in this file. @@ -285,7 +291,6 @@ # endif // ENABLE_ZAP_DEAD_LOCALS -//------------------------------compute_loop_first_inst_sizes------------------ // Compute the size of first NumberOfLoopInstrToAlign instructions at the top // of a loop. When aligning a loop we need to provide enough instructions // in cpu's fetch buffer to feed decoders. The loop alignment could be @@ -302,42 +307,39 @@ // or alignment padding is larger then MaxLoopPad. By default, MaxLoopPad // is equal to OptoLoopAlignment-1 except on new Intel cpus, where it is // equal to 11 bytes which is the largest address NOP instruction. - if( MaxLoopPad < OptoLoopAlignment-1 ) { - uint last_block = _cfg->_num_blocks-1; - for( uint i=1; i <= last_block; i++ ) { - Block *b = _cfg->_blocks[i]; + if (MaxLoopPad < OptoLoopAlignment - 1) { + uint last_block = _cfg->number_of_blocks() - 1; + for (uint i = 1; i <= last_block; i++) { + Block* block = _cfg->get_block(i); // Check the first loop's block which requires an alignment. - if( b->loop_alignment() > (uint)relocInfo::addr_unit() ) { + if (block->loop_alignment() > (uint)relocInfo::addr_unit()) { uint sum_size = 0; uint inst_cnt = NumberOfLoopInstrToAlign; - inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt, _regalloc); + inst_cnt = block->compute_first_inst_size(sum_size, inst_cnt, _regalloc); // Check subsequent fallthrough blocks if the loop's first // block(s) does not have enough instructions. - Block *nb = b; - while( inst_cnt > 0 && - i < last_block && - !_cfg->_blocks[i+1]->has_loop_alignment() && - !nb->has_successor(b) ) { + Block *nb = block; + while(inst_cnt > 0 && + i < last_block && + !_cfg->get_block(i + 1)->has_loop_alignment() && + !nb->has_successor(block)) { i++; - nb = _cfg->_blocks[i]; + nb = _cfg->get_block(i); inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc); } // while( inst_cnt > 0 && i < last_block ) - b->set_first_inst_size(sum_size); + block->set_first_inst_size(sum_size); } // f( b->head()->is_Loop() ) } // for( i <= last_block ) } // if( MaxLoopPad < OptoLoopAlignment-1 ) } -//----------------------shorten_branches--------------------------------------- // The architecture description provides short branch variants for some long // branch instructions. Replace eligible long branches with short branches. void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size, int& stub_size) { - - // ------------------ // Compute size of each block, method size, and relocation information size - uint nblocks = _cfg->_num_blocks; + uint nblocks = _cfg->number_of_blocks(); uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); @@ -364,7 +366,7 @@ uint last_avoid_back_to_back_adr = max_uint; uint nop_size = (new (this) MachNopNode())->size(_regalloc); for (uint i = 0; i < nblocks; i++) { // For all blocks - Block *b = _cfg->_blocks[i]; + Block* block = _cfg->get_block(i); // During short branch replacement, we store the relative (to blk_starts) // offset of jump in jmp_offset, rather than the absolute offset of jump. @@ -377,10 +379,10 @@ DEBUG_ONLY( jmp_rule[i] = 0; ) // Sum all instruction sizes to compute block size - uint last_inst = b->_nodes.size(); + uint last_inst = block->number_of_nodes(); uint blk_size = 0; for (uint j = 0; j < last_inst; j++) { - Node* nj = b->_nodes[j]; + Node* nj = block->get_node(j); // Handle machine instruction nodes if (nj->is_Mach()) { MachNode *mach = nj->as_Mach(); @@ -441,8 +443,8 @@ // When the next block starts a loop, we may insert pad NOP // instructions. Since we cannot know our future alignment, // assume the worst. - if (i< nblocks-1) { - Block *nb = _cfg->_blocks[i+1]; + if (i < nblocks - 1) { + Block* nb = _cfg->get_block(i + 1); int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit(); if (max_loop_pad > 0) { assert(is_power_of_2(max_loop_pad+relocInfo::addr_unit()), ""); @@ -473,26 +475,26 @@ has_short_branch_candidate = false; int adjust_block_start = 0; for (uint i = 0; i < nblocks; i++) { - Block *b = _cfg->_blocks[i]; + Block* block = _cfg->get_block(i); int idx = jmp_nidx[i]; - MachNode* mach = (idx == -1) ? NULL: b->_nodes[idx]->as_Mach(); + MachNode* mach = (idx == -1) ? NULL: block->get_node(idx)->as_Mach(); if (mach != NULL && mach->may_be_short_branch()) { #ifdef ASSERT assert(jmp_size[i] > 0 && mach->is_MachBranch(), "sanity"); int j; // Find the branch; ignore trailing NOPs. - for (j = b->_nodes.size()-1; j>=0; j--) { - Node* n = b->_nodes[j]; + for (j = block->number_of_nodes()-1; j>=0; j--) { + Node* n = block->get_node(j); if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) break; } - assert(j >= 0 && j == idx && b->_nodes[j] == (Node*)mach, "sanity"); + assert(j >= 0 && j == idx && block->get_node(j) == (Node*)mach, "sanity"); #endif int br_size = jmp_size[i]; int br_offs = blk_starts[i] + jmp_offset[i]; // This requires the TRUE branch target be in succs[0] - uint bnum = b->non_connector_successor(0)->_pre_order; + uint bnum = block->non_connector_successor(0)->_pre_order; int offset = blk_starts[bnum] - br_offs; if (bnum > i) { // adjust following block's offset offset -= adjust_block_start; @@ -520,7 +522,7 @@ diff -= nop_size; } adjust_block_start += diff; - b->_nodes.map(idx, replacement); + block->map_node(replacement, idx); mach->subsume_by(replacement, C); mach = replacement; progress = true; @@ -637,7 +639,7 @@ new ConstantOopWriteValue(cik->java_mirror()->constant_encoding())); Compile::set_sv_for_object_node(objs, sv); - uint first_ind = spobj->first_index(); + uint first_ind = spobj->first_index(sfpt->jvms()); for (uint i = 0; i < spobj->n_fields(); i++) { Node* fld_node = sfpt->in(first_ind+i); (void)FillLocArray(sv->field_values()->length(), sfpt, fld_node, sv->field_values(), objs); @@ -892,7 +894,7 @@ GrowableArray<MonitorValue*> *monarray = new GrowableArray<MonitorValue*>(num_mon); // Loop over monitors and insert into array - for(idx = 0; idx < num_mon; idx++) { + for (idx = 0; idx < num_mon; idx++) { // Grab the node that defines this monitor Node* box_node = sfn->monitor_box(jvms, idx); Node* obj_node = sfn->monitor_obj(jvms, idx); @@ -900,11 +902,11 @@ // Create ScopeValue for object ScopeValue *scval = NULL; - if( obj_node->is_SafePointScalarObject() ) { + if (obj_node->is_SafePointScalarObject()) { SafePointScalarObjectNode* spobj = obj_node->as_SafePointScalarObject(); scval = Compile::sv_for_node_id(objs, spobj->_idx); if (scval == NULL) { - const Type *t = obj_node->bottom_type(); + const Type *t = spobj->bottom_type(); ciKlass* cik = t->is_oopptr()->klass(); assert(cik->is_instance_klass() || cik->is_array_klass(), "Not supported allocation."); @@ -912,14 +914,14 @@ new ConstantOopWriteValue(cik->java_mirror()->constant_encoding())); Compile::set_sv_for_object_node(objs, sv); - uint first_ind = spobj->first_index(); + uint first_ind = spobj->first_index(youngest_jvms); for (uint i = 0; i < spobj->n_fields(); i++) { Node* fld_node = sfn->in(first_ind+i); (void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs); } scval = sv; } - } else if( !obj_node->is_Con() ) { + } else if (!obj_node->is_Con()) { OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node); if( obj_node->bottom_type()->base() == Type::NarrowOop ) { scval = new_loc_value( _regalloc, obj_reg, Location::narrowoop ); @@ -1086,11 +1088,11 @@ if (has_mach_constant_base_node()) { // Fill the constant table. // Note: This must happen before shorten_branches. - for (uint i = 0; i < _cfg->_num_blocks; i++) { - Block* b = _cfg->_blocks[i]; - - for (uint j = 0; j < b->_nodes.size(); j++) { - Node* n = b->_nodes[j]; + for (uint i = 0; i < _cfg->number_of_blocks(); i++) { + Block* b = _cfg->get_block(i); + + for (uint j = 0; j < b->number_of_nodes(); j++) { + Node* n = b->get_node(j); // If the node is a MachConstantNode evaluate the constant // value section. @@ -1173,7 +1175,7 @@ // !!!!! This preserves old handling of oopmaps for now debug_info()->set_oopmaps(_oop_map_set); - uint nblocks = _cfg->_num_blocks; + uint nblocks = _cfg->number_of_blocks(); // Count and start of implicit null check instructions uint inct_cnt = 0; uint *inct_starts = NEW_RESOURCE_ARRAY(uint, nblocks+1); @@ -1221,21 +1223,21 @@ // Now fill in the code buffer Node *delay_slot = NULL; - for (uint i=0; i < nblocks; i++) { - Block *b = _cfg->_blocks[i]; - - Node *head = b->head(); + for (uint i = 0; i < nblocks; i++) { + Block* block = _cfg->get_block(i); + Node* head = block->head(); // If this block needs to start aligned (i.e, can be reached other // than by falling-thru from the previous block), then force the // start of a new bundle. - if (Pipeline::requires_bundling() && starts_bundle(head)) + if (Pipeline::requires_bundling() && starts_bundle(head)) { cb->flush_bundle(true); + } #ifdef ASSERT - if (!b->is_connector()) { + if (!block->is_connector()) { stringStream st; - b->dump_head(_cfg, &st); + block->dump_head(_cfg, &st); MacroAssembler(cb).block_comment(st.as_string()); } jmp_target[i] = 0; @@ -1246,16 +1248,16 @@ int blk_offset = current_offset; // Define the label at the beginning of the basic block - MacroAssembler(cb).bind(blk_labels[b->_pre_order]); - - uint last_inst = b->_nodes.size(); + MacroAssembler(cb).bind(blk_labels[block->_pre_order]); + + uint last_inst = block->number_of_nodes(); // Emit block normally, except for last instruction. // Emit means "dump code bits into code buffer". for (uint j = 0; j<last_inst; j++) { // Get the node - Node* n = b->_nodes[j]; + Node* n = block->get_node(j); // See if delay slots are supported if (valid_bundle_info(n) && @@ -1309,9 +1311,9 @@ assert((padding % nop_size) == 0, "padding is not a multiple of NOP size"); int nops_cnt = padding / nop_size; MachNode *nop = new (this) MachNopNode(nops_cnt); - b->_nodes.insert(j++, nop); + block->insert_node(nop, j++); last_inst++; - _cfg->map_node_to_block(nop, b); + _cfg->map_node_to_block(nop, block); nop->emit(*cb, _regalloc); cb->flush_bundle(true); current_offset = cb->insts_size(); @@ -1325,7 +1327,7 @@ mcall->method_set((intptr_t)mcall->entry_point()); // Save the return address - call_returns[b->_pre_order] = current_offset + mcall->ret_addr_offset(); + call_returns[block->_pre_order] = current_offset + mcall->ret_addr_offset(); if (mcall->is_MachCallLeaf()) { is_mcall = false; @@ -1362,7 +1364,7 @@ // If this is a branch, then fill in the label with the target BB's label else if (mach->is_MachBranch()) { // This requires the TRUE branch target be in succs[0] - uint block_num = b->non_connector_successor(0)->_pre_order; + uint block_num = block->non_connector_successor(0)->_pre_order; // Try to replace long branch if delay slot is not used, // it is mostly for back branches since forward branch's @@ -1395,8 +1397,8 @@ // Insert padding between avoid_back_to_back branches. if (needs_padding && replacement->avoid_back_to_back()) { MachNode *nop = new (this) MachNopNode(); - b->_nodes.insert(j++, nop); - _cfg->map_node_to_block(nop, b); + block->insert_node(nop, j++); + _cfg->map_node_to_block(nop, block); last_inst++; nop->emit(*cb, _regalloc); cb->flush_bundle(true); @@ -1408,7 +1410,7 @@ jmp_size[i] = new_size; jmp_rule[i] = mach->rule(); #endif - b->_nodes.map(j, replacement); + block->map_node(replacement, j); mach->subsume_by(replacement, C); n = replacement; mach = replacement; @@ -1416,8 +1418,8 @@ } mach->as_MachBranch()->label_set( &blk_labels[block_num], block_num ); } else if (mach->ideal_Opcode() == Op_Jump) { - for (uint h = 0; h < b->_num_succs; h++) { - Block* succs_block = b->_succs[h]; + for (uint h = 0; h < block->_num_succs; h++) { + Block* succs_block = block->_succs[h]; for (uint j = 1; j < succs_block->num_preds(); j++) { Node* jpn = succs_block->pred(j); if (jpn->is_JumpProj() && jpn->in(0) == mach) { @@ -1428,7 +1430,6 @@ } } } - #ifdef ASSERT // Check that oop-store precedes the card-mark else if (mach->ideal_Opcode() == Op_StoreCM) { @@ -1439,17 +1440,18 @@ if (oop_store == NULL) continue; count++; uint i4; - for( i4 = 0; i4 < last_inst; ++i4 ) { - if( b->_nodes[i4] == oop_store ) break; + for (i4 = 0; i4 < last_inst; ++i4) { + if (block->get_node(i4) == oop_store) { + break; + } } // Note: This test can provide a false failure if other precedence // edges have been added to the storeCMNode. - assert( i4 == last_inst || i4 < storeCM_idx, "CM card-mark executes before oop-store"); + assert(i4 == last_inst || i4 < storeCM_idx, "CM card-mark executes before oop-store"); } assert(count > 0, "storeCM expects at least one precedence edge"); } #endif - else if (!n->is_Proj()) { // Remember the beginning of the previous instruction, in case // it's followed by a flag-kill and a null-check. Happens on @@ -1545,12 +1547,12 @@ // If the next block is the top of a loop, pad this block out to align // the loop top a little. Helps prevent pipe stalls at loop back branches. if (i < nblocks-1) { - Block *nb = _cfg->_blocks[i+1]; + Block *nb = _cfg->get_block(i + 1); int padding = nb->alignment_padding(current_offset); if( padding > 0 ) { MachNode *nop = new (this) MachNopNode(padding / nop_size); - b->_nodes.insert( b->_nodes.size(), nop ); - _cfg->map_node_to_block(nop, b); + block->insert_node(nop, block->number_of_nodes()); + _cfg->map_node_to_block(nop, block); nop->emit(*cb, _regalloc); current_offset = cb->insts_size(); } @@ -1590,8 +1592,6 @@ } #endif - // ------------------ - #ifndef PRODUCT // Information on the size of the method, without the extraneous code Scheduling::increment_method_size(cb->insts_size()); @@ -1652,52 +1652,55 @@ _inc_table.set_size(cnt); uint inct_cnt = 0; - for( uint i=0; i<_cfg->_num_blocks; i++ ) { - Block *b = _cfg->_blocks[i]; + for (uint i = 0; i < _cfg->number_of_blocks(); i++) { + Block* block = _cfg->get_block(i); Node *n = NULL; int j; // Find the branch; ignore trailing NOPs. - for( j = b->_nodes.size()-1; j>=0; j-- ) { - n = b->_nodes[j]; - if( !n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con ) + for (j = block->number_of_nodes() - 1; j >= 0; j--) { + n = block->get_node(j); + if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) { break; + } } // If we didn't find anything, continue - if( j < 0 ) continue; + if (j < 0) { + continue; + } // Compute ExceptionHandlerTable subtable entry and add it // (skip empty blocks) - if( n->is_Catch() ) { + if (n->is_Catch()) { // Get the offset of the return from the call - uint call_return = call_returns[b->_pre_order]; + uint call_return = call_returns[block->_pre_order]; #ifdef ASSERT assert( call_return > 0, "no call seen for this basic block" ); - while( b->_nodes[--j]->is_MachProj() ) ; - assert( b->_nodes[j]->is_MachCall(), "CatchProj must follow call" ); + while (block->get_node(--j)->is_MachProj()) ; + assert(block->get_node(j)->is_MachCall(), "CatchProj must follow call"); #endif // last instruction is a CatchNode, find it's CatchProjNodes - int nof_succs = b->_num_succs; + int nof_succs = block->_num_succs; // allocate space GrowableArray<intptr_t> handler_bcis(nof_succs); GrowableArray<intptr_t> handler_pcos(nof_succs); // iterate through all successors for (int j = 0; j < nof_succs; j++) { - Block* s = b->_succs[j]; + Block* s = block->_succs[j]; bool found_p = false; - for( uint k = 1; k < s->num_preds(); k++ ) { - Node *pk = s->pred(k); - if( pk->is_CatchProj() && pk->in(0) == n ) { + for (uint k = 1; k < s->num_preds(); k++) { + Node* pk = s->pred(k); + if (pk->is_CatchProj() && pk->in(0) == n) { const CatchProjNode* p = pk->as_CatchProj(); found_p = true; // add the corresponding handler bci & pco information - if( p->_con != CatchProjNode::fall_through_index ) { + if (p->_con != CatchProjNode::fall_through_index) { // p leads to an exception handler (and is not fall through) - assert(s == _cfg->_blocks[s->_pre_order],"bad numbering"); + assert(s == _cfg->get_block(s->_pre_order), "bad numbering"); // no duplicates, please - if( !handler_bcis.contains(p->handler_bci()) ) { + if (!handler_bcis.contains(p->handler_bci())) { uint block_num = s->non_connector()->_pre_order; handler_bcis.append(p->handler_bci()); handler_pcos.append(blk_labels[block_num].loc_pos()); @@ -1716,9 +1719,9 @@ } // Handle implicit null exception table updates - if( n->is_MachNullCheck() ) { - uint block_num = b->non_connector_successor(0)->_pre_order; - _inc_table.append( inct_starts[inct_cnt++], blk_labels[block_num].loc_pos() ); + if (n->is_MachNullCheck()) { + uint block_num = block->non_connector_successor(0)->_pre_order; + _inc_table.append(inct_starts[inct_cnt++], blk_labels[block_num].loc_pos()); continue; } } // End of for all blocks fill in exception table entries @@ -1777,14 +1780,12 @@ memset(_current_latency, 0, node_max * sizeof(unsigned short)); // Clear the bundling information - memcpy(_bundle_use_elements, - Pipeline_Use::elaborated_elements, - sizeof(Pipeline_Use::elaborated_elements)); + memcpy(_bundle_use_elements, Pipeline_Use::elaborated_elements, sizeof(Pipeline_Use::elaborated_elements)); // Get the last node - Block *bb = _cfg->_blocks[_cfg->_blocks.size()-1]; - - _next_node = bb->_nodes[bb->_nodes.size()-1]; + Block* block = _cfg->get_block(_cfg->number_of_blocks() - 1); + + _next_node = block->get_node(block->number_of_nodes() - 1); } #ifndef PRODUCT @@ -1834,7 +1835,6 @@ sizeof(Pipeline_Use::elaborated_elements)); } -//------------------------------ScheduleAndBundle------------------------------ // Perform instruction scheduling and bundling over the sequence of // instructions in backwards order. void Compile::ScheduleAndBundle() { @@ -1861,7 +1861,6 @@ scheduling.DoScheduling(); } -//------------------------------ComputeLocalLatenciesForward------------------- // Compute the latency of all the instructions. This is fairly simple, // because we already have a legal ordering. Walk over the instructions // from first to last, and compute the latency of the instruction based @@ -1879,7 +1878,7 @@ // Used to allow latency 0 to force an instruction to the beginning // of the bb uint latency = 1; - Node *use = bb->_nodes[j]; + Node *use = bb->get_node(j); uint nlen = use->len(); // Walk over all the inputs @@ -2031,7 +2030,6 @@ return _available[0]; } -//------------------------------AddNodeToAvailableList------------------------- void Scheduling::AddNodeToAvailableList(Node *n) { assert( !n->is_Proj(), "projections never directly made available" ); #ifndef PRODUCT @@ -2077,7 +2075,6 @@ #endif } -//------------------------------DecrementUseCounts----------------------------- void Scheduling::DecrementUseCounts(Node *n, const Block *bb) { for ( uint i=0; i < n->len(); i++ ) { Node *def = n->in(i); @@ -2100,7 +2097,6 @@ } } -//------------------------------AddNodeToBundle-------------------------------- void Scheduling::AddNodeToBundle(Node *n, const Block *bb) { #ifndef PRODUCT if (_cfg->C->trace_opto_output()) { @@ -2293,7 +2289,7 @@ (OptoReg::is_valid(_regalloc->get_reg_first(n)) || op != Op_BoxLock)) ) { // Push any trailing projections - if( bb->_nodes[bb->_nodes.size()-1] != n ) { + if( bb->get_node(bb->number_of_nodes()-1) != n ) { for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { Node *foi = n->fast_out(i); if( foi->is_Proj() ) @@ -2315,7 +2311,6 @@ DecrementUseCounts(n,bb); } -//------------------------------ComputeUseCount-------------------------------- // This method sets the use count within a basic block. We will ignore all // uses outside the current basic block. As we are doing a backwards walk, // any node we reach that has a use count of 0 may be scheduled. This also @@ -2337,21 +2332,21 @@ _unconditional_delay_slot = NULL; #ifdef ASSERT - for( uint i=0; i < bb->_nodes.size(); i++ ) - assert( _uses[bb->_nodes[i]->_idx] == 0, "_use array not clean" ); + for( uint i=0; i < bb->number_of_nodes(); i++ ) + assert( _uses[bb->get_node(i)->_idx] == 0, "_use array not clean" ); #endif // Force the _uses count to never go to zero for unscheduable pieces // of the block for( uint k = 0; k < _bb_start; k++ ) - _uses[bb->_nodes[k]->_idx] = 1; - for( uint l = _bb_end; l < bb->_nodes.size(); l++ ) - _uses[bb->_nodes[l]->_idx] = 1; + _uses[bb->get_node(k)->_idx] = 1; + for( uint l = _bb_end; l < bb->number_of_nodes(); l++ ) + _uses[bb->get_node(l)->_idx] = 1; // Iterate backwards over the instructions in the block. Don't count the // branch projections at end or the block header instructions. for( uint j = _bb_end-1; j >= _bb_start; j-- ) { - Node *n = bb->_nodes[j]; + Node *n = bb->get_node(j); if( n->is_Proj() ) continue; // Projections handled another way // Account for all uses @@ -2400,20 +2395,22 @@ Block *bb; // Walk over all the basic blocks in reverse order - for( int i=_cfg->_num_blocks-1; i >= 0; succ_bb = bb, i-- ) { - bb = _cfg->_blocks[i]; + for (int i = _cfg->number_of_blocks() - 1; i >= 0; succ_bb = bb, i--) { + bb = _cfg->get_block(i); #ifndef PRODUCT if (_cfg->C->trace_opto_output()) { tty->print("# Schedule BB#%03d (initial)\n", i); - for (uint j = 0; j < bb->_nodes.size(); j++) - bb->_nodes[j]->dump(); + for (uint j = 0; j < bb->number_of_nodes(); j++) { + bb->get_node(j)->dump(); + } } #endif // On the head node, skip processing - if( bb == _cfg->_broot ) + if (bb == _cfg->get_root_block()) { continue; + } // Skip empty, connector blocks if (bb->is_connector()) @@ -2432,10 +2429,10 @@ } // Leave untouched the starting instruction, any Phis, a CreateEx node - // or Top. bb->_nodes[_bb_start] is the first schedulable instruction. - _bb_end = bb->_nodes.size()-1; + // or Top. bb->get_node(_bb_start) is the first schedulable instruction. + _bb_end = bb->number_of_nodes()-1; for( _bb_start=1; _bb_start <= _bb_end; _bb_start++ ) { - Node *n = bb->_nodes[_bb_start]; + Node *n = bb->get_node(_bb_start); // Things not matched, like Phinodes and ProjNodes don't get scheduled. // Also, MachIdealNodes do not get scheduled if( !n->is_Mach() ) continue; // Skip non-machine nodes @@ -2455,19 +2452,19 @@ // in the block), because they have delay slots we can fill. Calls all // have their delay slots filled in the template expansions, so we don't // bother scheduling them. - Node *last = bb->_nodes[_bb_end]; + Node *last = bb->get_node(_bb_end); // Ignore trailing NOPs. while (_bb_end > 0 && last->is_Mach() && last->as_Mach()->ideal_Opcode() == Op_Con) { - last = bb->_nodes[--_bb_end]; + last = bb->get_node(--_bb_end); } assert(!last->is_Mach() || last->as_Mach()->ideal_Opcode() != Op_Con, ""); if( last->is_Catch() || // Exclude unreachable path case when Halt node is in a separate block. (_bb_end > 1 && last->is_Mach() && last->as_Mach()->ideal_Opcode() == Op_Halt) ) { // There must be a prior call. Skip it. - while( !bb->_nodes[--_bb_end]->is_MachCall() ) { - assert( bb->_nodes[_bb_end]->is_MachProj(), "skipping projections after expected call" ); + while( !bb->get_node(--_bb_end)->is_MachCall() ) { + assert( bb->get_node(_bb_end)->is_MachProj(), "skipping projections after expected call" ); } } else if( last->is_MachNullCheck() ) { // Backup so the last null-checked memory instruction is @@ -2476,7 +2473,7 @@ Node *mem = last->in(1); do { _bb_end--; - } while (mem != bb->_nodes[_bb_end]); + } while (mem != bb->get_node(_bb_end)); } else { // Set _bb_end to point after last schedulable inst. _bb_end++; @@ -2505,7 +2502,7 @@ assert( _scheduled.size() == _bb_end - _bb_start, "wrong number of instructions" ); #ifdef ASSERT for( uint l = _bb_start; l < _bb_end; l++ ) { - Node *n = bb->_nodes[l]; + Node *n = bb->get_node(l); uint m; for( m = 0; m < _bb_end-_bb_start; m++ ) if( _scheduled[m] == n ) @@ -2516,14 +2513,14 @@ // Now copy the instructions (in reverse order) back to the block for ( uint k = _bb_start; k < _bb_end; k++ ) - bb->_nodes.map(k, _scheduled[_bb_end-k-1]); + bb->map_node(_scheduled[_bb_end-k-1], k); #ifndef PRODUCT if (_cfg->C->trace_opto_output()) { tty->print("# Schedule BB#%03d (final)\n", i); uint current = 0; - for (uint j = 0; j < bb->_nodes.size(); j++) { - Node *n = bb->_nodes[j]; + for (uint j = 0; j < bb->number_of_nodes(); j++) { + Node *n = bb->get_node(j); if( valid_bundle_info(n) ) { Bundle *bundle = node_bundling(n); if (bundle->instr_count() > 0 || bundle->flags() > 0) { @@ -2550,7 +2547,6 @@ } // end DoScheduling -//------------------------------verify_good_schedule--------------------------- // Verify that no live-range used in the block is killed in the block by a // wrong DEF. This doesn't verify live-ranges that span blocks. @@ -2563,7 +2559,6 @@ } #ifdef ASSERT -//------------------------------verify_do_def---------------------------------- void Scheduling::verify_do_def( Node *n, OptoReg::Name def, const char *msg ) { // Check for bad kills if( OptoReg::is_valid(def) ) { // Ignore stores & control flow @@ -2579,7 +2574,6 @@ } } -//------------------------------verify_good_schedule--------------------------- void Scheduling::verify_good_schedule( Block *b, const char *msg ) { // Zap to something reasonable for the verify code @@ -2588,8 +2582,8 @@ // Walk over the block backwards. Check to make sure each DEF doesn't // kill a live value (other than the one it's supposed to). Add each // USE to the live set. - for( uint i = b->_nodes.size()-1; i >= _bb_start; i-- ) { - Node *n = b->_nodes[i]; + for( uint i = b->number_of_nodes()-1; i >= _bb_start; i-- ) { + Node *n = b->get_node(i); int n_op = n->Opcode(); if( n_op == Op_MachProj && n->ideal_reg() == MachProjNode::fat_proj ) { // Fat-proj kills a slew of registers @@ -2639,7 +2633,6 @@ from->add_prec(to); } -//------------------------------anti_do_def------------------------------------ void Scheduling::anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is_def ) { if( !OptoReg::is_valid(def_reg) ) // Ignore stores & control flow return; @@ -2709,7 +2702,6 @@ add_prec_edge_from_to(kill,pinch); } -//------------------------------anti_do_use------------------------------------ void Scheduling::anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ) { if( !OptoReg::is_valid(use_reg) ) // Ignore stores & control flow return; @@ -2722,7 +2714,7 @@ pinch->req() == 1 ) { // pinch not yet in block? pinch->del_req(0); // yank pointer to later-def, also set flag // Insert the pinch-point in the block just after the last use - b->_nodes.insert(b->find_node(use)+1,pinch); + b->insert_node(pinch, b->find_node(use) + 1); _bb_end++; // Increase size scheduled region in block } @@ -2730,7 +2722,6 @@ } } -//------------------------------ComputeRegisterAntidependences----------------- // We insert antidependences between the reads and following write of // allocated registers to prevent illegal code motion. Hopefully, the // number of added references should be fairly small, especially as we @@ -2775,10 +2766,10 @@ // it being in the current block. bool fat_proj_seen = false; uint last_safept = _bb_end-1; - Node* end_node = (_bb_end-1 >= _bb_start) ? b->_nodes[last_safept] : NULL; + Node* end_node = (_bb_end-1 >= _bb_start) ? b->get_node(last_safept) : NULL; Node* last_safept_node = end_node; for( uint i = _bb_end-1; i >= _bb_start; i-- ) { - Node *n = b->_nodes[i]; + Node *n = b->get_node(i); int is_def = n->outcnt(); // def if some uses prior to adding precedence edges if( n->is_MachProj() && n->ideal_reg() == MachProjNode::fat_proj ) { // Fat-proj kills a slew of registers @@ -2827,7 +2818,7 @@ // Do not allow defs of new derived values to float above GC // points unless the base is definitely available at the GC point. - Node *m = b->_nodes[i]; + Node *m = b->get_node(i); // Add precedence edge from following safepoint to use of derived pointer if( last_safept_node != end_node && @@ -2844,11 +2835,11 @@ if( n->jvms() ) { // Precedence edge from derived to safept // Check if last_safept_node was moved by pinch-point insertion in anti_do_use() - if( b->_nodes[last_safept] != last_safept_node ) { + if( b->get_node(last_safept) != last_safept_node ) { last_safept = b->find_node(last_safept_node); } for( uint j=last_safept; j > i; j-- ) { - Node *mach = b->_nodes[j]; + Node *mach = b->get_node(j); if( mach->is_Mach() && mach->as_Mach()->ideal_Opcode() == Op_AddP ) mach->add_prec( n ); } @@ -2864,8 +2855,6 @@ } } -//------------------------------garbage_collect_pinch_nodes------------------------------- - // Garbage collect pinch nodes for reuse by other blocks. // // The block scheduler's insertion of anti-dependence @@ -2940,7 +2929,6 @@ pinch->set_req(0, NULL); } -//------------------------------print_statistics------------------------------- #ifndef PRODUCT void Scheduling::dump_available() const {