> On Wed, 6 Dec 2000, Patrik Stridvall wrote:
> 
> > > I find your line of reasoning ridiculous at best. A compiler 
> > > is certainly
> > > in the best position of all reasonable things to determine 
> > > whether a piece
> > > of code it has just compiled is actually used in the 
> module that it is
> > > commanded to compile.
> > 
> > Proving it can analyze and understand what any present 
> > inline assembler does (or doesn't), yes.
> 
> It does its job - does its best with whatever the coder tells 
> it. It's not
> its job to analyze something the coder doesn't tell it to 
> work on, which
> makes sense, and is expected behaviour, since the compiler 
> isn't supposed
> to be an intelligent decompiler that can determine your 
> constraints for
> you - it is certainly not within the scope of a C compiler.
> 
> Why don't you say that "putting variables into registers is a 
> bug because
> it can cause problems with signal handlers that want to 
> access them", and
> say that the compiler should never do that when it detects that signal
> handlers are being used, no matter how high the optimization 
> level is? And
> that using a documented attribute like "volatile" to work 
> around this bug
> is so Microsoft-ish that you won't do it?

Sure sure, but the main point of argument is about 
whether __attribute__((unused)) is a constraint or not.
 
> > > The compiler is also *expected* to 
> > > remove dead code,
> > > *especially* if attribute((unused)) is used, as this 
> attribute is very
> > > often used in inline functions in .h files.
> > 
> > OK perhaps "attribute((unused))" does something differently that I
> > orginally thought. However the optimizer can check for inline
> > attribute as well can't it?
> 
> Sure - and if absent, optimization levels -O3 (and above) 
> decides on its
> own whether to inline the function or not. This is desired 
> behaviour, old
> & portable C code isn't written with "inline" all over it, it's the
> compiler's job to optimize where it can.

Yes, but old portable code doesn't use __attribute__((unused)) does it?

In any case, ask yourself whether you prefer you old & portable
application to work correctly or whether you want it to possibly
have subtle bugs. Better safe that sorry IMHO.

> (Even when there is an "inline", the compiler is permitted to 
> ignore it
> when it wants to (and at -O0 it'll always be ignored). 
> Putting "inline" in
> the code is just a hint.)

Yes, it is a hint, but that doesn't mean that it doesn't conway
other forms of information, like this function will not be
refered to using function pointers and that its absence in
presence of other attributes like unused doesn't mean anything.
 
> > What ever is 
> >     static void init(void) __attribute__((unused));
> > supposed to mean absent any implementation?
> 
> That it's a prototype, obviously.

Indeed, a prototype for something the compiler might not
be able to detect and therefore avoid to warn about
and/or remove during optimization.

> > Sure 
> >     static inline void init(void) __attribute__((unused));
> > with an implementation probably means what you say but not
> > without inline or implementation.
> 
> If this isn't one example of your behated heuristics, I don't 
> know what
> is.

I think we have different definitions of the word heuristics,
see below.

> It's even one that has the potential to demand 
> multipassing, which the
> C standard is written to avoid the need for by allowing prototypes,
> attributes, incomplete types, etc... and now you want to 
> invalidate all
> this effort to make C a fast single-pass compiler language.

How do you perform dead function removal without multiple passes?
You can't possible know whether it is used or not before you
have seen all the code?

In any case does the C standard really mention dead function removal?

> But the "init" implementation does exist, the compiler just decides to
> inline it.

Yes, ignoring the __attribute__((unused)) constraint,
which should mean IMHO in absence of explict inline
do not ever inline it (see below).
 
> > > And no optimizations ever depend on what any assembler code 
> > > does (it only
> > > depends on any specified (gcc-specific) constraints), talking 
> > > against the
> > > opposite idea just seems silly.
> > 
> > So 
> >     static void init(void) __attribute__((unused))
> > absent an implementation isn't a constraint?
> 
> Absolutely correct, for once. (If anything, it's a hint to 
> the compiler to
> unleash every bit of optimization power it has, including 
> removing unused
> code, although this is not what happens.)
> 
> A constraint is like this: asm("rep stosl" :: "a"(val), "D"(addr),
> "c"(count) : "memory");

I know that is a constraint, I just claim there might exist other
types of constraints.
 
> Here the compiler is, in addition to be told to what 
> registers the input
> operands must be in (which is a constraint), also told that 
> the operation
> affects memory, which causes the compiler to make sure it doesn't keep
> other variables in registers across this operation. That's the only
> analysis it needs, given directly by the coder rather than 
> worked out by
> some "heuristics" in the compiler, as it should be.

I know how GNU asm constraint work, but thanks anyway.
 
> > > This kind of quickly glancing over a very short section of 
> > > docs, rapidly
> > > misunderstanding it, then writing complete paragraphs 
> about the faulty
> > > conclusion, is something I only expect of users, not of 
> developers...
> > 
> > OK. What I meant was don't use -O6 if you prefer 
> correctness over speed.
> > 
> > Regardless the fact remains _if_ -O6 uses _heuristics_ (see 
> below) it
> > might generate wrong code even if it is bug free. Note _if_.
> 
> It does use heuristics to determine whether to inline the 
> function or not,
> and it will never generate wrong code. Again, what's so hard 
> to understand
> about that?

I think we have different definitions of heuristics.
 
> > > No C code can become incorrect in gcc using heuristics to 
> determine
> > > whether to inline a C function or not. Either it's inlined, 
> > > or it isn't,
> > > and both produce utterly correct compiled code in all 
> cases, if the
> > > compiler is bug free.
> > 
> > Deciding whether a functions should be inline or not doesn't involve
> > heuristics it involves fuzzy logic or whatever you wish to call it.
> 
> Fuzzy logic is also a heuristic, but pure fuzzy logic doesn't 
> cut it.

OK, wrong choice or words (that why I added whatever you wish to call it).

> For
> example, the most important heuristic the compiler employs is that the
> function simply cannot be inlined if it's referenced by 
> address, rather
> than just called, or if it's calling itself recursively.

But that is not an heuristic. If it it referenced or recusive
it is always correct to not inline it. There is no incorrect
cases and therefore it is not an heuristic it is an algoritm
and i'm not possitive that it is even a non-optimal algoritm.
 
> > Heuristics implies that one correct answer to a question exist
> > but the algoritm you use might not always find it and if it does
> > not it might lead to bad things.
> 
> There is a correct answer - whether inlining causes the app 
> to go faster,
> or whether it'll just cause bloat. So what if it doesn't find the best
> answer? All you will end up with is code that hasn't been 
> optimized to the
> fullest. You'll never get *incorrect* code just because it's 
> not optimized
> perfectly!

Sure but you will if you incorrectly eliminate dead code
that is the case now.
 
> > There doesn't exist a correct answer on whether a function
> > should be inlined or not it depends on the context.
> 
> Well that's why it needs heuristics to check the context with. The
> heuristic currently doesn't extend to unconstrained asm code, 
> but that is
> expected behaviour. If you expect otherwise, I know a few *real* C
> programmers around here who will gladly flame you to ashes 
> for ignorance
> of the C language, portability issues, the workings of a compiler, and
> general understanding of the computing environment. Should I 
> refer you to
> them?

The key word is unconstrained, which is the point where I don't agree.
 
> > Whether you want speed or size and on the executing CPU and all sort
> > of other things.
> 
> It knows that with -O3 (and especially -O6), you want speed.
> If you want size, stick with -O2.
> 
> > Sure, any bug can be documented and become a feature.
> > Microsoft is an expert on this. :-)
> 
> And you're becoming an expert on attacking well-designed features and
> calling them bugs just because you don't like them, or like any
> prejudicial person, fear them because you don't understand them.

I certainly don't like the way it works now,
but that doesn't nessary make me prejudical,
does it?
 
> > Seriously, it depends on what you mean by incorrect. It is
> > incorrect in the meaning that might lead to wrong results.
> > And yes this is an example of an _heuristics_ by my definition
> > of the word it is just that you doucument that the meaning of
> > the code as undefined in the a cases not handled by the
> > heuristics.
> 
> Undefined when not handled by the heuristics? If you can't 
> stop writing
> long essays abouts things you've misunderstood, are you sure 
> you're fit to
> be a hacker?

Aren't you becoming a little personal now?

> An asm statements that depends on the outside 
> environment but
> still lacks constraints is certainly undefined from the start, it's
> conceptually just pure luck that it works at all (until the compiler
> changes this environment at high optimization levels), and 
> even convincing
> the optimizer's heuristics to do the "right thing" by chance 
> isn't going
> to make it less undefined - only applying constraints will.

Yes, constraints like __attribute__((unused)).
 
Then we have a little missundering with the word heurstics.
There are four kinds of algoritms.

1. Optimal algoritms
2. Non-optimal algoritms
3  Algoritms buggy by design
4. Algoritms buggy by misstake

As far as I'm concern 3 is heuristics,
but you seem to wish to include 2 as well.

But never mind it is not important for whether GNU C is buggy
or not.

> > In any case gcc does ignore constraints as stated above
> > and thus has a bug.
> 
> Which constraints? Our code doesn't contain any constraints 
> at all, that's
> the problem. If you tell the gcc people that they have a bug 
> because Wine
> code is using gcc extensions (asm) incorrectly, I'm sure 
> they'll have a
> good laugh on your expense...

But it isn't, it is using the _ANSI_ C feature asm which
doesn't have any constraints. There is a difference between
not specifing any constraints and specifing that there is
no constraints you know.

In most cases this doesn't matter and perhaps GNU C
doesn't separate among them but there still is a
subtle difference.

In addition I claim that __attribute__((unused)) is a constraint.

>From the gcc manual.
< `unused'
<     This attribute, attached to a function, means that the function is
<     meant to be possibly unused.  GNU CC will not produce a warning
<     for this function.

It says that no warning will be issued and it is _possibly_ unused.
Note _possibly_. I interpret this as a definition _might_ exists
somewhere but if the compiler can't detect it, it shouldn't produce
a warning.

Your interpretation that it should agresively optimize it away
if it can't detect it. This is IMHO inconsistant with _possibly_
unused.

In the mail I sent later in the night that you haven't answer (yet),
I try very briefly to explain that what you want to happend can
be done with other means that doesn't involve having
the optimizer hope and pray that nobody uses it.

If the constraint __attribute__((unused)) doesn't exist I
agree that is correct to remove because then you haven't
said anything about the function neither in any
asm constraint nor in any other constraint.

In short, I expect GNU C to do the following:
If a function have __attribute__((unused)) and not an
explict inline, do not remove it or inline it unless
it can tell for _certain_ that isn't used. That is
_all_ asm statement have some sort of constraints
and none of them ask for this function. Of course
if the constraints by mistake doesn't ask for this
function it is OK to remove it since then it is
the fault of the programmer not the compiler.

The compiler just need to mark function with 
__attribute__((unused)) and no explict inline as
do not inline this functions under any cirumcstances
which a flag AFAIU already  must exist in compiler
for marking functions when it finds that used in
a function pointer. It just marks it right away.

As for dead function removal well that multi pass
anyway to having a flag that says all asm have
constraints it not that expensive to maintain is it?
If that flags is not set do not perform dead function
removal. Very simple.

Is this really so stupid, that you have to resort to
name calling during the argument?

Reply via email to