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?

> > 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.

(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.)

> What ever is 
>       static void init(void) __attribute__((unused));
> supposed to mean absent any implementation?

That it's a prototype, obviously.

> 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. 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.

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

> > 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");

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.

> > 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?

> > 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. 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.

> 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!

> 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?

> 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.

> 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? 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.

> 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...


Reply via email to