This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: spill_failure


Rajkishore Barik <rajbarik@in.ibm.com> writes:

> > Hmm, let me rephrase your question:
> > "I did some GCC hacking that I'm not showing, and it doesn't work,
> > please help me fix it."
> 
> This is not what I meant. I meant if similar problem has been reported by 
> anyone else before.

Everybody who works with the backend has seen this particular error
all too often.  It doesn't have any one cause.  As Steven said, it
means that reload was unable to find enough registers to do work which
it needed to do.

 In any case. This is the piece of code that I add
> after every integer "set" instruction returned from "single_set()" module.
> 
>     // "insn" being the current integer set instruction
>     // "value" being the "destination" of the set instruction
>     // GCOV_COUNTER_V_RANGE is a new Value Range Counter added by me
>     enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
>     start_sequence ();
>     rtx stored_val_ref = rtl_coverage_counter_ref(GCOV_COUNTER_V_RANGE, 
> 0); 
>     rtx stored_val = validize_mem (stored_val_ref);
>     rtx uval = gen_reg_rtx (mode);
>     convert_move (uval, copy_rtx (value), 0);
>     rtx tmp=expand_simple_binop(mode, IOR,copy_rtx(uval),
>                 copy_rtx(stored_val),stored_val,0, OPTAB_WIDEN);
>     sequence = get_insns ();
>     end_sequence ();
>     emit_insn_after(sequence,insn);
> 
> Note that I these pieces of code just before register allocation and code
> scheduling are done.

I note that these are reasonably complex operations to be adding this
late in the compiler.  And that you don't have the case of tmp !=
stored_val.  The insn on which reload crashes strongly suggests that
this is a DImode value, which is particularly awkward on the x86
because of the paucity of registers.  The code above appears to
convert the DImode value to SImode anyhow.

> > > ./mul_mdmd_md.c: In function Ãmul_mdmd_md_l1_arb_allÃ:
> > > ./mul_mdmd_md.c:343: error: unable to find a register to spill in 
> class
> > > ÃAD_REGSÃ
> > > ./mul_mdmd_md.c:343: error: this is the insn:
> > > (insn 529 8 530 0 (parallel [
> > >             (set (reg:DI 232)
> > >                 (sign_extend:DI (reg/v:SI 149 [ M ])))
> > >             (clobber (reg:CC 17 flags))
> > >             (clobber (scratch:SI))
> > >         ]) 82 {*extendsidi2_1} (nil)
> > >     (expr_list:REG_UNUSED (scratch:SI)
> > >         (expr_list:REG_UNUSED (reg:CC 17 flags)
> > >             (nil))))
> > > ./mul_mdmd_md.c:343: internal compiler error: in spill_failure, at
> > > reload1.c:1885
> > What this basically says is that after register allocation some insns
> > do not have all their operand constraints satisfied, so reload needs
> > to fix up something, but it cannot use the registers it needs.
> 
> The same piece of code works fine for me for the whole lot of benchmarks
> without having any problem. Its a few which cause this AD_REG spill 
> problem.
> I am wondering why is this happening.

Basically because reload has been baffled.  It picked an alternative
but was unable to find the particular registers required to fill that
alternative.

I don't know whether you mentioned which sources you are using.  The
error message indicates that reload is looking for AD_REGS.  I'm not
sure why this would happen in mainline, where extendsidi2_1 only uses
AD_REGS if the value is already there.  But I think it may be possible
for reload to pick a particular alternative, then be forced to spill
the register, and then still try to stick to the originally chosen
alternative.  If so, that would cause this kind of failure.

You might consider not adding your code for DImode values.

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]