This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Live range splitting in new allocator
- To: Michael Meissner <meissner at cygnus dot com>
- Subject: Re: Live range splitting in new allocator
- From: Daniel Berlin <dberlin at redhat dot com>
- Date: Mon, 29 Jan 2001 16:05:51 -0500 (EST)
- cc: <gcc at gcc dot gnu dot org>
>
> Hmmm, I was about to dust off the old live range splitting code I had written
> some time ago (considerably more than 30 lines), which unfortunately is
> currently if'ed out in the current internal Red Hat compiler, due to dataflow
> problems.
The dataflow analysis module is giving us all the info we need.
>
> In addition to the dataflow problems, another problem that I haven't had time
> to work on is how to inform the debugger of a variables location as it moves
> betweent he stack and multiple registers. The current compiler is broken in
> this regard, but LRS makes it more visible, since things can be in multiple
> registers for a longer time.
>
I'll just turn it off when optimization is not in use.
> At the time I did the code (2-3 years ago), stabs was the preferred debug
> format, and we added an extension to stabs that gdb knows about to trace this
> movement. Obviously with dwarf-2 this could be done via the locator fields
> (which does break for VLIW machines). One thing that I had thought about doing
> for other debug formats, but couldn't get right when I was working on the code,
> was to split the lexical blocks each time you have a variable cross LRS
> boundaries. For instance, if you have the program:
>
<snip>
Live range splitting in the allocator is done rather simply, since it's a
global allocator, and we have all the data flow analysis we need.
We don't even need to add stores, because we know the specific ues of a
given definition.
IE
given
int i;
for (i=0; i< 100; i++)
{
int a;
a=i;
}
for (i=0; i < 100; i++)
{
int b;
b=i;
}
, the dataflow analysis module' use-def chains for the first definition of
i, will contain the use at a, and thechjchain for the second definition of
i, will contain the use at b.
So we can simply rename the pseudo the second i is using, and all the uses
of that second i, withjout screwing up the first i definition.
>
> so that if you were in the middle of one of the loops, the debugger would think
> that i was just a lexically scopped replacement for the outer i.
>
> > This works perfectly.
> > I then update *all* the info (because i've been trying to figure out why
> > this problem occurrs, updating more and more info as i go along).
> > This means, I reset the log_links and reg_notes, then do this:
> >
> > find_basic_blocks(get_insns(), max_reg_num(), rtl_dump_file);
> > max_regno = max_reg_num();
> > fprintf(stderr, "New max_regno:%d, max_reg_num():%d", max_regno, max_reg_num());
> > reg_scan(get_insns(), max_reg_num(), 1);
> > allocate_reg_info(max_regno, FALSE, TRUE);
> > update_equiv_regs();
> > cleanup_cfg (get_insns());
> > count_or_remove_death_notes(0,1);
> > update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
> > PROP_FINAL);
> > regclass(get_insns(), max_reg_num(), rtl_dump_file);
> > schedule_insns(rtl_dump_file);
> >
> >
> > We now properly allocate registers, including for the new pseudos.
> >
> > After reload, but before reload_cse_regs, for one of the new pseudos, we
> > have this:
> >
> > (insn 41 34 281 (set (reg:SI 4 [151])
> > (const_int 0 [0x0])) 282 {*movsi_internal1} (nil)
> > (nil))
> >
> > After reload_cse_regs starts processing, something up and changes this to:
> > (insn 41 34 281 (set (reg:SI 805875168 [4])
> > (const_int 0 [0x0])) 282 {*movsi_internal1} (nil)
> > (nil))
> >
> > It's already like that by the time it calls reload_cse_simplify on the
> > insn.
> > (gdb) c
> > Continuing.
> >
> > Breakpoint 6, reload_cse_regs_1 (first=0x300926a0) at
> > ../../gcc/reload1.c:8134
> > 8134 reload_cse_simplify (insn);
> > (gdb) p debug_rtx(insn)
> >
> > (jump_insn 23 22 24 (set (pc)
> > (label_ref 175)) 467 {jump} (insn_list:REG_DEP_ANTI 21 (insn_list
> > 22 (nil)))
> > (nil))
> > $29 = void
> > (gdb) c
> > Continuing.
> >
> > Breakpoint 6, reload_cse_regs_1 (first=0x300926a0) at
> > ../../gcc/reload1.c:8134
> > 8134 reload_cse_simplify (insn);
> > (gdb) p debug_rtx(insn)
> >
> > (insn 41 34 281 (set (reg:SI 805875168 [4])
> > (const_int 0 [0x0])) 282 {*movsi_internal1} (nil)
> > (nil))
> > $30 = void
> >
> >
> > WTF is going on?
> >
> > Something is turning the register numbers on the new pseudos to garbage.
> > It's not a memory overwrite, or at least, electricfence doesn't catch it.
> > If i remove the call to reload_cse_regs, something else turns it to the
> > same exact garbage a little later, etc.
> >
> > It's really annoying me.
> > Am i generating the new pseudos wrong? I'm using gen_reg_rtx.
>
> What is happening I believe is that there are these tables based on the
> register number. You have to extend these tables whenever you allocate
> registers in the middle end.
>
I am, that is what the allocate_reg_info does.
There is some stupid table somewhere that is being allocated at the
beginning of a function, and doesn't ever sxpect to be extended.
--Dan