comp.lang.ada
 help / color / mirror / Atom feed
From: ralph@inputplus.demon.co.uk (Ralph Corderoy)
Subject: Pragma Inline and its Effects of Compilation Dependencies.
Date: 2000/03/20
Date: 2000-03-20T00:00:00+00:00	[thread overview]
Message-ID: <8b64ul$jov$1@inputplus.demon.co.uk> (raw)

Hi,

I was recently asked to look into an Ada compilation problem that
centred around the use of pragma inline.  The result was a realisation
that the pragmas weren't accurately reflected in the compiler suite's
dependency graph used to determine compilation order.  Consequently,
when building a set of source from scratch a separate containing an
inlined routine wasn't being built before its callers.

I'd like to check that I understand what's wrong and how it should work,
and then ask for advice on where to go from here.

Assume we've two packages, foo and bar, with bar making use of foo.

    ==> foo.s.ada <==
    package foo is
        procedure x;

        procedure y;
        pragma inline(y);
    end;

    ==> foo.b.ada <==
    package body foo is
        procedure x is separate;
        procedure y is separate;
    end;

    ==> foo.x.ada <==
    separate(foo)
    procedure x is begin null; end;

    ==> foo.y.ada <==
    separate(foo)
    procedure y is begin null; end;

    ==> bar.s.ada <==
    with foo;

    package bar is
        procedure x;
        procedure y;
    end;

    ==> bar.b.ada <==
    package body bar is
        procedure x is separate;
        procedure y is separate;
    end;

    ==> bar.x.ada <==
    separate(bar)
    procedure x is begin foo.y; end;

    ==> bar.y.ada <==
    separate(bar)
    procedure y is begin null; end;

Are these the dependencies that exist.

    1 foo.b.ada -> foo.s.ada because a body depends on its spec
    2 foo.x.ada -> foo.b.ada because a sub-unit depends on its parent
    3 foo.y.ada -> foo.b.ada because a sub-unit depends on its parent

    4 bar.b.ada -> bar.s.ada because a body depends on its spec
    5 bar.x.ada -> bar.b.ada because a sub-unit depends on its parent
    6 bar.y.ada -> bar.b.ada because a sub-unit depends on its parent

    7 bar.s.ada -> foo.s.ada because bar's spec withs foo
    8 bar.x.ada -> foo.y.ada because bar.x calls inlined foo.y

A linear ordering of this partial order is

    foo.s.ada foo.b.ada foo.x.ada foo.y.ada
    bar.s.ada bar.b.ada bar.x.ada bar.y.ada

The compiler suite I was using had instead

    8 bar.x.ada -> foo.b.ada

allowing it to use the linear ordering

    foo.s.ada foo.b.ada
    bar.s.ada bar.b.ada bar.x.ada bar.y.ada
    foo.x.ada foo.y.ada

This fails to inline foo.y because it isn't available when bar.x is
built.

I believe calling an inlined routine creates a dependency from the
caller to the routine itself, and if it is a separate that isn't the
same as the body of the package, as used by the compiler above.

First question.  How well do other compilers handle this;  not too well
judging by the the existence of adamakegen
(http://www.ics.uci.edu/~softtest/adamakegen.html) and its complaints
about Verdix/SunAda.

I've read a little about gnat's gnatmake and how the compiler doesn't
follow the normal library implementation and instead uses the source
files coupled with ALI files.  Does that mean in practice it copes
correctly with inline dependencies, including when they're in separates?
The manual seemed to suggest it didn't consider source outside the
current library.  That wouldn't help in my case.  Consider if foo was
being built into a separate Ada library from bar;  I alter foo.y.ada and
build locally there.  I then want to move to bar's library and find it
is out of date.

It seems what I need is something that will take many source files,
parse them, and spit out the dependencies for use in something like a
traditional makefile.  It isn't a trivial task as things like package
renames and use clauses help to obscure what is being called.  Plus it
mustn't make the mistake of thinking an inline creates a dependency to
the package body when a separate exists.  Does something like this
exist?

The alternative seems to be to re-build bar from scratch whenever foo is
changed because it can't be left to the compiler to calculate what to
rebuild and relying on the programmer to know who calls foo.y is a
no-no.  But building bar and everything else could take eons.

This can't be an original problem.  What do people with large Ada
projects do?


Ralph.





             reply	other threads:[~2000-03-20  0:00 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-03-20  0:00 Ralph Corderoy [this message]
2000-03-21  0:00 ` Pragma Inline and its Effects of Compilation Dependencies Robert Dewar
2000-03-21  0:00   ` Paul Graham
2000-03-21  0:00     ` Gautier
2000-03-22  0:00       ` Robert Dewar
2000-03-22  0:00         ` Wes Groleau
2000-03-22  0:00           ` Robert A Duff
2000-03-22  0:00         ` Larry Kilgallen
2000-03-22  0:00           ` Robert Dewar
2000-03-22  0:00             ` Larry Kilgallen
2000-03-22  0:00           ` Ted Dennison
2000-03-22  0:00     ` Ken Garlington
2000-03-23  0:00   ` Ralph Corderoy
2000-03-23  0:00     ` Robert Dewar
2000-03-24  0:00       ` Robert A Duff
2000-03-21  0:00 ` Samuel T. Harris
2000-03-23  0:00   ` Ralph Corderoy
2000-03-24  0:00     ` Samuel T. Harris
2000-03-24  0:00       ` Robert Dewar
2000-03-22  0:00 ` Robert Dewar
2000-03-23  0:00   ` Ralph Corderoy
2000-03-23  0:00     ` Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox