views:

98

answers:

1

I'm looking at this bit of text in the documentation for Visual C++'s _ReadWriteBarrier intrinsic:

In past versions of the Visual C++ compiler, the _ReadWriteBarrier and _WriteBarrier functions were enforced only locally and did not affect functions up the call tree. In Visual C++ 2005 and later, these functions are enforced all the way up the call tree.

I understand what the barrier does within a function, but the "up the call tree" seems to imply that a function foo() calling a function bar() can know whether bar() contains a barrier or not. What actually changed in VC2005 to enable this... the calling convention/ABI, some global analysis done by the compiler, or what ?

+1  A: 

MS docs are never great, and this one is a good example of that. There are 2 parts to the _ReadWriteBarrier:

  1. telling the CPU to do a memory barrier (ie mfence),
  2. telling the compiler not to optimize around the barrier.

I suspect the call tree part is referring to #2. ie:

int x = 0;

void foo()
{
   x = 7;
   _ReadWriteBarrier();
   x = 8;
}

Without the barrier, x=7 can be completely removed by the compiler. With the barrier, it stays. Now, what about a function that calls foo?

void bar()
{
   x = 3;  // optimized away?
   foo();
   x = 4;
}

I think in the past x=3 might have been optimized away (which can be hard for the compiler to tell whether that's allowed or not), but now it will correctly keep the x=3 instructions.

I think.

tony
That is also how I understand the MS docs. But how is it possible for the compiler to implement this behaviour? If the answer would simply be that all non-inline function calls are compiler reorder fences, then why the reference to the earlier versions of VC not implementing this?
shojtsy
I don't really know. It could mark each function with attributes that the linker then interprets. This may be as simple as how they do name mangling or a complicated database inside the lib or at least in the object dictionary during compile... However, typically in the past compilers always assumed the worst about functions that they couldn't see into, thus not optimizing around it. Maybe as they get smarter they need to expose more information.
tony