PATCH: removes expand_constant language hook

Mark Mitchell mark@codesourcery.com
Fri Mar 30 06:12:00 GMT 2007


Ollie Wild wrote:

> Here's an updated patch which handles recursion in the initializer.
> The assembly generated with this patch is nearly identical to that
> generated without it.  However, 0 offsets are now initialized in the
> bss section rather than the data section.  Hopefully, no one has a
> problem with that.

As Andrew says, moving stuff from .data to .bss is a win.  So, though
(as you say) this happens rarely, that's certainly not a problem.

>     * typeck2.c (digest_init): Call cplus_expand_constant after
>     convert_for_initialization.

I'm concerned about this part.  My concern was that PTRMEM_CST is a more
useful representation for the front end than the low-level
representation, especially in the case of pointers to member functions.
 Ideally, we'd like to optimize:

  struct S { void f(); };
  typedef void (S::*P)(void);
  const P ps[2] = { &S::f, NULL };
  void g(S s) {
    P p = ps[0];
    (s.*p)();
  }

into "S.f()".  I'm sure we don't do this now, but we could.

In theory, even with the lowered form, we have enough representation --
but it's ugly and complicated to go back from the lowered form to a
constant.  I'd really like G++ to be able to represent things in their
natural C++ forms as long as possible; the fact that a
pointer-to-member-function is actually a structure (and an ABI-dependent
structure at that!) is a detail.

More concretely, does your patch handle:

  struct S { void f(); };
  typedef void (S::*P)(void);
  const P p = &S::f;
  template <P p> void g();
  g<p>();

I'd like to be sure that the pointer-to-member constant is still
recognized by the template machinery as a constant parameter in this
case.  I'm not sure if digest_init gets called in this case.

So, I'd be happier if we could do this at the point where we know we're
actually generating the constant, which is why the hooks went into
expand_constant in the first place.

Backing up, I'm assuming that the problem you're trying to handle is
that, for LTO, we need to avoid PTRMEM_CSTs, because we won't have
cplus_expand_constant around to expand them for us at LTO time?  We
could just make PTRMEM_CST a part of the middle-end -- but,
unfortunately, expand_ptrmemfunc_cst depends on knowing how to cast to
virtual bases, which is C++-specific.

Therefore, I think the best solution would be to lower PTRMEM_CST only
at the point of outputting LTO information.  (For PTRMEM_CSTs in the
bodies of functions, that already happens at the point of generating
GENERIC.)  In other words, when outputting the initializer for a global
variable into the LTO information, call the lang_hook to expand
constants so that the lowered information makes it to LTO.

What do you think?

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713



More information about the Gcc-patches mailing list