> -----Original Message----- > From: Jeff Law [mailto:l...@redhat.com] > Sent: Tuesday, November 06, 2012 4:51 AM > To: Bin Cheng > Cc: gcc-patches@gcc.gnu.org > Subject: Re: [PATCH Version 2][RFA]Improving register pressure directed hoist > > On 11/02/2012 02:34 AM, Bin Cheng wrote: > >> > > Also I don't understand why the bogus patch can catch more hoist > > opportunities and improve code size, so please help if you have any > > idea about this. > Well, perturbing the code, particularly in a way which is supposed to change > the amount of register pressure is certainly going to affect the allocators > and reload. > > It shouldn't be that hard to look at results which differ between the two > patches and analyze why they're different. I will try to investigate this issue.
> > > > > 2012-11-02 Bin Cheng<bin.ch...@arm.com> > > > > * gcse.c: (struct bb_data): Add new fields, old_pressure, live_in > > and backup. > > (calculate_bb_reg_pressure): Initialize live_in and backup. > > (update_bb_reg_pressure): New. > > (should_hoist_expr_to_dom): Add new parameter from. > > Monitor the change of reg pressure and use it to drive hoisting. > > (hoist_code): Update LIVE and reg pressure information. > > > > gcc/testsuite/ChangeLog > > 2012-11-02 Bin Cheng<bin.ch...@arm.com> > > > > * gcc.dg/hoist-register-pressure-3.c: New test. > > > > > > +/* Update register pressure for BB when hoisting an expression from > > + instruction FROM, if live ranges of inputs are shrunk. Also > > + maintain live_in information if live range of register referred > > + in FROM is shrunk. > > + > > + Return 0 if register pressure doesn't change, otherwise return > > + the number by which register pressure is decreased. > > + > > + NOTE: Register pressure won't be increased in this function. */ > > + > > +static int > > +update_bb_reg_pressure (basic_block bb, rtx from, > > + enum reg_class pressure_class, int nregs) { > > + rtx dreg, insn; > > + basic_block succ_bb; > > + df_ref *op, op_ref; > > + edge succ; > > + edge_iterator ei; > > + int decreased_pressure = 0; > > + > > + for (op = DF_INSN_USES (from); *op; op++) > > + { > > + dreg = DF_REF_REAL_REG (*op); > > + /* The live range of register is shrunk only if it isn't: > > + 1. referred on any path from the end of this block to EXIT, or > > + 2. referred by insns other than FROM in this block. */ > > + FOR_EACH_EDGE (succ, ei, bb->succs) > > + { > > + succ_bb = succ->dest; > > + if (succ_bb == EXIT_BLOCK_PTR) > > + continue; > > + > > + if (bitmap_bit_p (BB_DATA (succ_bb)->live_in, REGNO (dreg))) > > + break; > > + } > > + if (succ != NULL) > > + continue; > > + > > + op_ref = DF_REG_USE_CHAIN (REGNO (dreg)); > > + for (; op_ref; op_ref = DF_REF_NEXT_REG (op_ref)) > > + { > > + if (!DF_REF_INSN_INFO (op_ref)) > > + continue; > > + > > + insn = DF_REF_INSN (op_ref); > > + if (BLOCK_FOR_INSN (insn) == bb > > + && NONDEBUG_INSN_P (insn) && insn != from) > > + break; > > + } > > + > > + /* Decrease register pressure and update live_in information for > > + this block. */ > > + if (!op_ref) > > + { > > + decreased_pressure += nregs; > > + BB_DATA (bb)->max_reg_pressure[pressure_class] -= nregs; > > + bitmap_clear_bit (BB_DATA (bb)->live_in, REGNO (dreg)); > > + } > > + } > > + return decreased_pressure; > So we're looking to see if any of the registers used in FROM are used after > from. If none are used, then we decrease the register pressure by nregs which > appears to be a property of the the registers *set* in FROM. > Is seems like there's some inconsistency here. Or have I misunderstood > something? > > I'm not sure how much it matters in practice, except perhaps for conversions > and the like where the source and destination operands are different modes. Agreed, I missed the inconsistence of register_class/number between input and output. I will fix this issue and measure the effect once I get back to office. Thanks for your comments.