> The purpose of PIC is really to allow position-independent data access,
> not for jump fixes. 

No, not only for data access. PIC also deals with function calls; just
compile

void foo();
void bar()
{foo();}

> This call-then-pop to get EIP makes me grimace. Intel is forcing us to
> make TWO MEMORY ACCESSES just to get the value of the program counter.
> Does anyone know if Intel had a justification for this?

Sure. Compatibility to the 8086, which was in turn like the 8008/Z80
processors...

> It seems like all shared libraries and shared objects on Intel take
> a serious penalty every time they access non-auto storage.

The performance loss comes from not being able to use ebx, not because
of the overhead of loading the register. I guess a modern process does
not even touch main memory for that...

> Is GCC smart enough to figure this out in most cases, and cache the
> value of these expensive variables during long stretches of computation,
> then save the result into the real location at the end of a function
> call or basic block? 

GCC will only load the PIC register only once. It will not
specifically optimize access to global variables, instead, that will
be done as part of the normal data flow analysis.

> The important point of this example is that the inline function is
> complex enough to exhaust the general-purpose registers. This means that
> expensive_var cannot be stored indefinitely in any one register. In this
> case, I think it would be Good for GCC to create an invisible automatic
> variable to store the value of expensive_var during the execution of
> crunch_numbers().
> 
> Does GCC indeed do something like this?

I think it won't. Instead, it will try to clear as many registers as
possible inside the loop, and leave the variable's value in a register
- unless the address of the variable was taken, in which case every
store will go into the variable.

Regards,
Martin

Reply via email to