Final intermodule patch

Mark Mitchell mark@codesourcery.com
Mon Jul 14 00:01:00 GMT 2003


>  
> > In the case of "export", the current approach would result in multiply
> > defined symbols at link time because global entities present in both the
> > template and main translation unit would be emitted twice -- once when
> > you compiled the template, and once when you compiled the file that
> > instantiated the template.
> I don't understand why we can't simply get rid of the second copy of the
> symbols when we see we already assembled the template once
> In fact I would expect that for C++ we can save many of template
> instantiations in the compilation.

Consider these files:

  template.C
  ==========
   
  int i = 3;

  export template <typename T> int f (T) { return i; }

  main1.C:
  ========

  extern int i;

  int main () { return i; }

  main2.C:
  ========
  
  export template <typename T> int f(T);

  int main () { return f(7); }
 
Now, the following must work:

  g++ -c template.C
  g++ -c main1.C
  g++ -o main1 template.o main1.o

For that to work, "i" must be defined in "template.o".

The following must also work:

  g++ -c main2.C
  g++ -o main2 template.o main2.o

For that to work, "i" must not be defined in main2.o, even though the
entire contents of template.C are going to be implicitly visible in
main2.C.  Note that there are no entities with internal linkage in this
example.

The obvious way for this to work is that when compiling main2.C, the
compiler reads main2.C and template.C.  It puts the entities from each
file in separate translation units, using TRANSLATION_UNIT_DECL.  It
does the instantiation of "f<int>", and puts that instantiation in
main2.C's translation unit.  It then emits the main2.C translation unit,
but not the definition of things that are in template.C.

That all works great if you have multiple .s files; one simple approach
is that the .s file for template.C is "/dev/null". 

If you were to use the current approach, everything would work fine at
the tree level, but your .s file would contain emissions belonging to
template.C as well as main2.C, and that won't work -- you'd end up
defining "i" in main2.o.

> > Workability is more objective than beauty, and I don't see why my
> > suggestion is unworkable.  It requires work, but much of the work would
> 
> Hmm, I must be still missing something.  How do you suggest to solve the
> problem of inlining infecting one module by accesses to static data in
> other modules?  It would be very bad if static accesses prevented
> intramodule inlining.

By using aliases with external linkage, as I suggested in my original
post.  On a system without aliases, it might make sense to rename the
entity and give it external linkage, rather than creating an alias.  

That's a QOI issue for those platforms.

> And lastly I would like to get into function clonning busyness sometime
> in foreseable future.  In that case I will have two copies of the same
> function accessing the same static variables quite unavoidably.

Yes. 

This same problem happens in C++ with template instantiation.

Consider this code:

  static int i;
  export template <typename T> int f(T) { return i; }

If "f" is instantiated in another translation unit, that other
translation unit needs to reference "i", even though it has internal
linkage.

The solution is to give "i" an alias so that you can talk about it
elsewhere.

-- 
Mark Mitchell <mark@codesourcery.com>
CodeSourcery, LLC



More information about the Gcc-patches mailing list