This is the mail archive of the gcc-bugs@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]

Re: flow still deleting important labels



  In message <19990328165757.A19211@cygnus.com>you write:
  > Ok, sanity check me here.  I found enough places we were doing
  > the wrong thing wrt REG_LABEL I can't believe I'm not skewed.

  [ Reordering your message...  It's easiest to answer this first :-) ]
  > So how did this work before, anyway?
If jump.c ever found a non-jumping insn with a LABEL_REF, it would attach
a REG_LABEL note to the insn.

Then in flow:

                       /* References to labels in non-jumping insns have
                           REG_LABEL notes attached to them.

                           This can happen for computed gotos; we don't care
                           about them here since the values are also on the
                           label_value_list and will be marked live if we find
                           a live computed goto.

                           This can also happen when we take the address of
                           a label to pass as an argument to __throw.  Note
                           throw only uses the value to determine what handler
                           should be called -- ie the label is not used as
                           a jump target, it just marks regions in the code.

                           In theory we should be able to ignore the REG_LABEL
                           notes, but we have to make sure that the label and
                           associated insns aren't marked dead, so we make
                           the block in question live and create an edge from
                           this insn to the label.  This is not strictly
                           correct, but it is close enough for now.  */
                        for (note = REG_NOTES (insn);
                             note;
                             note = XEXP (note, 1))
                          {
                            if (REG_NOTE_KIND (note) == REG_LABEL)
                              {
                                x = XEXP (note, 0);
                                block_live[BLOCK_NUM (x)] = 1;
                                mark_label_ref (gen_rtx_LABEL_REF (VOIDmode, x),
                                                insn, 0);
                              }
                          }

So that marked the label as reachable.  It's an inaccuracy in the cfg that we
decided to "live with" about a year or so ago I suspect.  [ It was an
improvement over marking those labels are reachable from every computed jump
if I remember correctly. ]

In the new flow code you only look at the last insn in the basic block to find
out the outgong edges exist for each block.  So you never see any REG_LABELs
that may be attached to instructions within the basic block.  Thus you never
mark their destination as reachable and you eventually kill it as unreachable.

I believe this is wrong.  If you have a reference to a label in a block that
is reachable, then you must consider the block starting with that label also
reachable -- or at least arrange to keep the label for the sake of EH which
may be marking a region of code with it.

I suspect you also need to create a fake edge to that block so that we don't
have blocks in the cfg that can't be reached from the root node -- you'll
confuse gcse, haifa and other global optimizers.

It may be better to make the edge to the target block from the entry block
instead of the block which had the reference.  That may (or may not) help
the global optimizers.

I didn't read the code that closely, so I could be wrong.  Anyway, I suspect
this is what's causing our labels to go away in the normal -mgas case.


  > Basic problem -- expand_builtin_setjmp puts a label in memory.
  > The code it generates to do that doesn't contain a REG_LABEL.
  > Secondary problems exist in that the REG_LABEL keeps vanishing.
This is the -mno-gas case I presume.  In that case labels are not
legitimate constants and thus we call force_const_mem on them to shove
them into memory.  That's how they got into the constant pool in the -mno-gas
case.

I believe in the normal -mgas case we do have the appropriate REG_LABEL
notes and we just need to fix flow to not delete a label which is
referenced by a non-jumping insn inside a basic block.

I'm not *that* concerned about the -mno-gas case -- HP's assembler is far
too lame to be useful on PAs.


jeff


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