[LLVMdev] PassManager and dependencies

Chris Lattner sabre at nondot.org
Sun Oct 20 22:41:01 PDT 2002


> Ouch. mea culpa.  It would be a good idea for preservesAll and
> preservesCFG to have the same interface (since I, at least, thought that
> they did ;)

Yup, I'll look into changing that when I have spare time (ha ha).

> >instead of a simple:
> >  virtual const string& name() const { return "B"; }

> Do you think it's a good idea to return a reference to a temporary?

Oops, sorry about that, I forgot to drop the reference:

virtual string name() const { return "B"; }

> Are you claiming that most compilers are so grossly inefficient that
> checking on every call is more expensive than creating the object on
> every call?  If you're going to be passing around objects, they have to
> be created somewhere.  By declaring things static (and preferably const
> as well), the compiler has the opportunity to optimize away the
> constructor call.

The compiler always has the opportunity to optimize away the constructor
call.  Remember that if the compiler is thread-capable, that you don't
just have a simple test to see if it's initialized, you have to at least
have a second chance lock or atomic operation, which is slow and bigger.
Regardless of locking, accessing global variables (Which statics
effectively are) is a good way to stop the optimizer dead in its tracks,
especially with GCC.

To emphasize my main point though, I wasn't trying to say that the above
would be faster, my point is that it _doesn't need to be_ fast.
Premature optimization, evil, and all that.

> >  2. Don't optimize things that don't have to be optimized.  In general
> >     these methods aren't called enough, or only during debugging, so it
> >     is better to be clear than it is to save a few cycles.  As a general
> >     rule, optimize for clarity, not performance.  Often performance comes
> >     for free with clarity.

> What could be more clear than "static X x; return x;"?

return X();

Remember you also need the initializer expression.

> >  3. If you REALLY want to be efficient, think about other short-cuts.  In
> >     this case, a constant string is always returned.  You could change
> >     the virtual method to always return a const char*, therefore avoiding
> >     a copy constructor call that may be unneccesary:

> A good reference-counted string implementation should efficiently handle
> returning a const& as in this case.  Of course, this is example code
> that I hacked out in about ten minutes just to illustrate the problem,
> so I would say that the goal is to optimize for speed of coding: I wrote
> it as it came to  me.

I understand that this wasn't meant to be the most optimal or thought out
code, I was just trying to get across the fact that it's not a good
default habit to get into for returning constant strings.  As it stands,
returning a const char* (if you can) would be MUCH faster than without.

Again in the presence of possible threads, reference counted strings are
MUCH slower than always copying in some cases.  A reasonable example of
this discussion is here, but there are many others:

http://www.gotw.ca/publications/optimizations.htm
http://www.gotw.ca/gotw/045.htm

The real point I was trying to make is that clear code is often efficient,
and only when you find that efficiency is actually a problem for a piece
of code should you resort to optimizations like this.  Compiler optimizers
can be made smarter for a fixed cost (giving benefits to a wide variety of
codes), but code maintenance has a cost that grows with the complexity of
code (and individual optimizations like this only gives a benefit to one
particular part of the code).  Increasing complexity for no real payoff
has no benefit.

-Chris

http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/




More information about the llvm-dev mailing list