On Nov 16, 2006, at 6:25 PM, Reid Spencer wrote: > On Thu, 2006-11-16 at 17:44 -0800, Bill Wendling wrote: >> Basically, this is to get rid of static c'tor/d'tors scattered all >> over the source tree. (You get them whenever you #include >> <iostream>.) >> A smart compiler should be able to remove all of the empty functions >> because they don't have any side-effects. > Hi Reid,
> I understand the motivation for the change and I commend it, but I'm > concerned about getting it right. You're assuming a few things: a) the > compiler is smart enough to get rid of calls that have no side > effects, > b) the compiler knows how to determine if a function has no side > effects > without help (operator<< isn't marked "pure"), and c) that there > aren't > any side effects. c) can probably be proven by your iostream > implementation but a) and b) are a little tougher. > Of course, LLVM is self-hosted, so it should be smart enough to handle it. :-) > Can we build an optimized, with symbols (-g -O2) version of one of > these > modules and see if those symbols are getting removed ? If so, I'm > fine > with it. If not, we need a new strategy. > I hope I did this correctly. Anyway, here are the files: t.h: #include <ostream> class llvm_ostream { std::ostream* Stream; public: llvm_ostream() : Stream(0) {} llvm_ostream(std::ostream& OStream) : Stream(&OStream) {} template <typename Ty> llvm_ostream& operator << (const Ty& Thing) { #ifndef NDEBUG if (Stream) *Stream << Thing; #endif return *this; } }; /// getErrorOutputStream - Returns the error output stream (std::cerr). This /// places the std::c* I/O streams into one .cpp file and relieves the whole /// program from having to have hundreds of static c'tor/d'tors for them. /// llvm_ostream getErrorOutputStream(const char *DebugType); #ifdef NDEBUG #define DOUT llvm_ostream() #else #define DOUT getErrorOutputStream(DEBUG_TYPE) #endif t.cpp: #define DEBUG_TYPE "experiment" #include "t.h" int main() { DOUT << "Hello world\n"; } foo.cpp: #include "t.h" #include <iostream> llvm_ostream getErrorOutputStream(const char *DebugType) { if (DebugType) return llvm_ostream(std::cerr); else return llvm_ostream(); } Compiled with -DNDEBUG -g -O2 gives: $ nm -A foo.o foo.o: 00000170 s EH_frame1 foo.o: 00000160 s __GLOBAL__I__Z20getErrorOutputStreamPKc foo.o: 00000000 a __GLOBAL__I__Z20getErrorOutputStreamPKc.eh foo.o: 00000000 T __Z20getErrorOutputStreamPKc foo.o: 00000000 A __Z20getErrorOutputStreamPKc.eh foo.o: 000000d0 s __Z41__static_initialization_and_destruction_0ii foo.o: 0000018c s __Z41__static_initialization_and_destruction_0ii.eh foo.o: U __ZNSt8ios_base4InitC1Ev foo.o: U __ZNSt8ios_base4InitD1Ev foo.o: U __ZSt4cerr foo.o: 000001d0 b __ZSt8__ioinit foo.o: U ___cxa_atexit foo.o: U ___dso_handle foo.o: U ___gxx_personality_v0 foo.o: 00000040 t ___tcf_0 foo.o: 00000000 a ___tcf_0.eh foo.o: U dyld_stub_binding_helper $ nm -A t.o t.o: 00000000 T _main t.o: 00000000 A _main.eh Compiling with -g -O2 gives: $ nm -A foo.o foo.o: 00000170 s EH_frame1 foo.o: 00000160 s __GLOBAL__I__Z20getErrorOutputStreamPKc foo.o: 00000000 a __GLOBAL__I__Z20getErrorOutputStreamPKc.eh foo.o: 00000000 T __Z20getErrorOutputStreamPKc foo.o: 00000000 A __Z20getErrorOutputStreamPKc.eh foo.o: 000000d0 s __Z41__static_initialization_and_destruction_0ii foo.o: 0000018c s __Z41__static_initialization_and_destruction_0ii.eh foo.o: U __ZNSt8ios_base4InitC1Ev foo.o: U __ZNSt8ios_base4InitD1Ev foo.o: U __ZSt4cerr foo.o: 000001d0 b __ZSt8__ioinit foo.o: U ___cxa_atexit foo.o: U ___dso_handle foo.o: U ___gxx_personality_v0 foo.o: 00000040 t ___tcf_0 foo.o: 00000000 a ___tcf_0.eh foo.o: U dyld_stub_binding_helper $ nm -A t.o t.o: 000000bc s EH_frame1 t.o: U __Z20getErrorOutputStreamPKc t.o: U __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc t.o: U ___gxx_personality_v0 t.o: 00000000 T _main t.o: 000000d8 S _main.eh t.o: U dyld_stub_binding_helper So it seems like gcc is doing the right thing, I suppose. I'm going to give it a try with the LLVM source in the CodeGen directory. -bw _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits