uint Block::code_alignment() { // Check for Root block if( _pre_order == 0 ) return CodeEntryAlignment; // Check for Start block if( _pre_order == 1 ) return InteriorEntryAlignment; // Check for loop alignment LoopNode *l = head()->is_Loop(); if( l && l->is_inner_loop() ) { // Pre- and post-loops have low trip count so do not bother with // NOPs for align loop head. The constants are hidden from tuning // but only because my "divide by 4" heuristic surely gets nearly // all possible gain (a "do not align at all" heuristic has a // chance of getting a really tiny gain). CountedLoopNode *cl = head()->is_CountedLoop(); if( cl && (cl->is_pre_loop() || cl->is_post_loop()) ) return (OptoLoopAlignment > 4) ? (OptoLoopAlignment>>2) : 1; // Loops with low backedge frequency should not be aligned. MachNode *mach = l->in(LoopNode::LoopBackControl)->in(0)->is_Mach(); if( mach ) { const MachIfNode *miff = mach->is_MachIf(); if( miff && miff->_prob < 0.01 ) return 1; // Loop does not loop, more often than not! } return OptoLoopAlignment; // Otherwise align loop head }
bool CountedLoopReserveKit::create_reserve() { if (!_active) { return false; } if(!_lpt->_head->is_CountedLoop()) { if (TraceLoopOpts) { tty->print_cr("CountedLoopReserveKit::create_reserve: %d not counted loop", _lpt->_head->_idx); } return false; } CountedLoopNode *cl = _lpt->_head->as_CountedLoop(); if (!cl->is_valid_counted_loop()) { if (TraceLoopOpts) { tty->print_cr("CountedLoopReserveKit::create_reserve: %d not valid counted loop", cl->_idx); } return false; // skip malformed counted loop } if (!cl->is_main_loop()) { bool loop_not_canonical = true; if (cl->is_post_loop() && (cl->slp_max_unroll() > 0)) { loop_not_canonical = false; } // only reject some loop forms if (loop_not_canonical) { if (TraceLoopOpts) { tty->print_cr("CountedLoopReserveKit::create_reserve: %d not canonical loop", cl->_idx); } return false; // skip normal, pre, and post (conditionally) loops } } _lp = _lpt->_head->as_Loop(); _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this); if (!_lp_reserved->is_CountedLoop()) { return false; } Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl); if (!ifslow_pred->is_IfFalse()) { return false; } Node* iff = ifslow_pred->in(0); if (!iff->is_If() || iff != _iff) { return false; } if (iff->in(1)->Opcode() != Op_ConI) { return false; } return _has_reserved = true; }
bool CountedLoopReserveKit::create_reserve() { if (!_active) { return false; } if(!_lpt->_head->is_CountedLoop()) { if (TraceLoopOpts) { tty->print_cr("CountedLoopReserveKit::create_reserve: %d not counted loop", _lpt->_head->_idx); } return false; } CountedLoopNode *cl = _lpt->_head->as_CountedLoop(); if (!cl->is_valid_counted_loop()) { if (TraceLoopOpts) { tty->print_cr("CountedLoopReserveKit::create_reserve: %d not valid counted loop", cl->_idx); } return false; // skip malformed counted loop } if (!cl->is_main_loop()) { if (TraceLoopOpts) { tty->print_cr("CountedLoopReserveKit::create_reserve: %d not main loop", cl->_idx); } return false; // skip normal, pre, and post loops } _lp = _lpt->_head->as_Loop(); _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this); if (!_lp_reserved->is_CountedLoop()) { return false; } Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl); if (!ifslow_pred->is_IfFalse()) { return false; } Node* iff = ifslow_pred->in(0); if (!iff->is_If() || iff != _iff) { return false; } if (iff->in(1)->Opcode() != Op_ConI) { return false; } return _has_reserved = true; }
//============================================================================= //------------------------------Ideal------------------------------------------ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ Node *in1 = in(1); Node *in2 = in(2); if( in1 == this ) return NULL; if( in2 == this ) return NULL; uint op1 = in1->Opcode(); uint op2 = in2->Opcode(); const Type *t2 = phase->type( in2 ); // Convert "x-c0" into "x+ -c0". if( t2->base() == Type::Int ){ // Might be bottom or top... const TypeInt *i = t2->is_int(); if( i->is_con() ) return new (3) AddINode(in(1), phase->intcon(-i->get_con())); } // Convert "(x+c0) - y" into (x-y) + c0" if( op1 == Op_AddI && in1->in(1) != in1 ) { // Do not collapse (x+y)-y if "+" is a loop increment, because the // "-" is loop invariant and collapsing extends the live-range of "x" // to overlap with the "+", forcing another register to be used in // the loop. const PhiNode *phi; CountedLoopNode *l; // This test will be clearer with '&&' (apply DeMorgan's rule) // but I like the early cutouts that happen here. if( !(phi=in1->in(1)->is_Phi()) || phi->is_copy() || !(l=phi->region()->is_CountedLoop()) || in1 != l->incr() ) { const Type *tadd = phase->type( in1->in(2) ); if( tadd->singleton() ) { Node *sub2 = phase->transform( new (3) SubINode( in1->in(1), in2 )); return new (3) AddINode( sub2, in1->in(2) ); } } } // Convert "x - (x+y)" into "-y" if( op2 == Op_AddI && phase->eqv( in1, in2->in(1) ) ) return new (3) SubINode( phase->intcon(0),in2->in(2)); // Convert "(x-y) - x" into "-y" if( op1 == Op_SubI && phase->eqv( in1->in(1), in2 ) ) return new (3) SubINode( phase->intcon(0),in1->in(2)); // Convert "x - (y+x)" into "-y" if( op2 == Op_AddI && phase->eqv( in1, in2->in(2) ) ) return new (3) SubINode( phase->intcon(0),in2->in(1)); // Convert "0 - (x-y)" into "y-x" if( phase->type( in1 ) == TypeInt::ZERO && op2 == Op_SubI ) return new (3) SubINode( in2->in(2), in2->in(1) ); // Convert "0 - (x+con)" into "-con-x" jint con; if( phase->type( in1 ) == TypeInt::ZERO && op2 == Op_AddI && in2->in(2)->get_int(&con) ) return new (3) SubINode( phase->intcon(-con), in2->in(1) ); // Convert "(X+A) - (X+B)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) ) return new (3) SubINode( in1->in(2), in2->in(2) ); // Convert "(A+X) - (B+X)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) ) return new (3) SubINode( in1->in(1), in2->in(1) ); // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally // nicer to optimize than subtract. if( op2 == Op_SubI && in2->in(1) != this && in2->in(1) != in2) { Node *add1 = phase->transform( new (3) AddINode( in1, in2->in(2) ) ); return new (3) SubINode( add1, in2->in(1) ); } return NULL; }
//============================================================================= //------------------------------Ideal------------------------------------------ Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node *in1 = in(1); Node *in2 = in(2); if( in1 == this ) return NULL; if( in2 == this ) return NULL; uint op1 = in1->Opcode(); uint op2 = in2->Opcode(); const TypeLong *i = phase->type( in2 )->isa_long(); // Convert "x-c0" into "x+ -c0". if( i && // Might be bottom or top... i->is_con() ) return new (3) AddLNode(in(1), phase->makecon(TypeLong::make(-i->get_con()))); // Convert "(x+c0) - y" into (x-y) + c0" if( op1 == Op_AddL && in1->in(1) != in1 ) { // Do not collapse (x+y)-y if "+" is a loop increment, because the // "-" is loop invariant and collapsing extends the live-range of "x" // to overlap with the "+", forcing another register to be used in // the loop. const PhiNode *phi; CountedLoopNode *l; if( !(phi=in1->in(1)->is_Phi()) || !phi->in(0) || !(l=phi->in(0)->is_CountedLoop()) || in1 != l->incr() ) { const Type *tadd = phase->type( in1->in(2) ); if( tadd->singleton() ) { Node *sub2 = phase->transform( new (3) SubLNode( in1->in(1), in2 )); return new (3) AddLNode( sub2, in1->in(2) ); } } } // Convert "x - (x+y)" into "-y" if( op2 == Op_AddL && phase->eqv( in1, in2->in(1) ) ) return new (3) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); // Convert "x - (y+x)" into "-y" if( op2 == Op_AddL && phase->eqv( in1, in2->in(2) ) ) return new (3) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); // Convert "0 - (x-y)" into "y-x" if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL ) return new (3) SubLNode( in2->in(2), in2->in(1) ); // Convert "(X+A) - (X+B)" into "A - B" if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) ) return new (3) SubLNode( in1->in(2), in2->in(2) ); // Convert "(A+X) - (B+X)" into "A - B" if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) ) return new (3) SubLNode( in1->in(1), in2->in(1) ); // Convert "A-(B-C)" into (A+C)-B" if( op2 == Op_SubL && in2->in(1) != this ) { Node *add1 = phase->transform( new (3) AddLNode( in1, in2->in(2) ) ); return new (3) SubLNode( add1, in2->in(1) ); } return NULL; }