From: Brian J. <bjj...@us...> - 2001-06-06 19:24:08
|
On Tue, 5 Jun 2001, Christian Bauer wrote: > > On Tue, Jun 05, 2001 at 06:18:55AM +0200, Gwenole Beauchesne wrote: > > > I think we have to come up with a subterfuge to fool the > > > compiler's data flow analyzer. > > > > "volatile"? > > Yes but according to Brian that doesn't seem to do the trick though > it should unless there is a bug in SGI C++ compiler ? Declaring page[] as "volatile" keeps the compiler from removing the second write, but that's all that "volatile" is required to do. It doesn't enforce any sort of ordering between page[] and handler_called. You need some sort of explicit dependency or something the compiler can't move (like a system call) for that. From what I'm told, gcc loads a lot more meaning onto "volatile" than the spec really requires. BTW, I didn't have any trouble with the sigcontext subterfuge tests, but perhaps I just got lucky. IRIX doesn't require a subterfuge. > > > On Tue, Jun 05, 2001 at 06:18:55AM +0200, Gwenole Beauchesne wrote: > > > I think we have to come up with a subterfuge to fool the > > > compiler's data flow analyzer. Something like a fake use after > > > each write. But that still wouldn't do the trick, would it? "volatile" will ensure that two writes are generated, but we still need a way to make sure the handler_called is read after the writes. There's a __synchronize() compiler intrinsic which explicitly enforces this restriction. That's probably the safest way to go, at least for SGI's compilers: *************** *** 281,286 **** --- 281,290 ---- page[123] = 45; page[123] = 45; + #ifdef sgi + // Keep SGI's MIPSPro compilers from moving the read of handler_called + __synchronize(); + #endif if (handler_called != 1) return 1; Looking at the generated code, it seems to do exactly the right thing. > > > Brian, is your compiler still optimizing enough to inline a > > > function defined after its call is issued ? Let's have for > > > example: > > > ... > > > int main() { > > > int some_int; > > > foo(&some_int); > > > } > > > > > > void foo(int *) { > > > printf("foo\n"); > > > } Yes. It completely removes foo(), and main() degenerates into a simple call to printf(). 9 MIPS instructions, counting the stack frame setup and teardown, and the implied return(0). (When you select a high enough optimization level, SGI's compilers actually compile into an intermidiate code, and let the linker invoke a full interprocedural analysis before code generation even begins. So the interprocedural optimizer always has complete information. It takes a _long_ time to link an application as huge as BII, but the resulting code is worth it.) Brian -------------------------------------------------------------------- "I use not only the brains I have, but all I can borrow." -- Woodrow Wilson |