Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

May a pointer ever point to a cpu register?

I'm wondering if a pointer may point to a cpu register since in the case it may not, using reference instead of pointer where possible would give compiler opportunity to do some optimizations because the referenced object may reside in some register but an object pointed to by a pointer may not.

like image 594
Pooria Avatar asked Oct 14 '10 20:10

Pooria


People also ask

Can a pointer point to a register?

If the variable is optimized to a register, the compiler would know that the reference is also that same register. A pointer will always need to point to a memory location. Even on the odd architecture that gives memory locations to its registers, it seems unlikely that the compiler would support such an operation.

Is the data pointer a register?

The Data Pointer (DPTR) is the 8051's only user-accessible 16-bit (2-byte) register. The Accumulator, R0–R7 registers and B register are 1-byte value registers. DPTR is meant for pointing to data. It is used by the 8051 to access external memory using the address indicated by DPTR.

Can a pointer point to multiple things?

Yes. A pointer p to type T can point to a single T , or to an array of T . In the latter case you can index into the array using pointer arithmetics, such as p[n] .

Do pointers point to memory?

A pointer is a variable that stores a memory address. Pointers are used to store the addresses of other variables or memory items. Pointers are very useful for another type of parameter passing, usually referred to as Pass By Address. Pointers are essential for dynamic memory allocation.


4 Answers

In general, CPU registers do not have memory addresses, though a CPU architecure could make them addressable (I;m not familar with any - if someone knows of one, I'd appreciate a comment). However, there's no standard way in C to get the address of a register. In fact if you mark a variable with the register storage class you aren't permitted to take that variables address using the & operator.

The key issue is aliasing - if the compiler can determine that an object isn't aliased then it can generally perform optimizations (whether the object is accessed via a pointer or a reference). I don't think you'll get any optimization benefit using a reference over a pointer (in general anyway).

However if you copy the object into a local variable, then the compiler can make an easier determination that there's no aliasing of the local assuming you don't pass the temporaries address around. This is a case where you can help the compiler optimize; however if the copy operation is expensive, it might not pay off in the end.

For something that would fit in a CPU register, copying to a temp is often a good way to go - compilers are great at optimizing those to registers.

like image 76
Michael Burr Avatar answered Nov 07 '22 05:11

Michael Burr


When a reference is passed to a function, the compiler will probably implement it as a hidden pointer - so changing the type won't matter.

When a reference is created and used locally, the compiler may be smart enough to know what it refers to and treat it as an alias to the referenced variable. If the variable is optimized to a register, the compiler would know that the reference is also that same register.

A pointer will always need to point to a memory location. Even on the odd architecture that gives memory locations to its registers, it seems unlikely that the compiler would support such an operation.

Edit: As an example, here is the generated code from Microsoft C++ with optimizations on. The code for the pointer and a passed reference are identical. The parameter passed by value for some reason did not end up in a register, even when I rearranged the parameter list. Even so, once the value was copied to a register both the local variable and the local reference used the same register without reloading it.

void __fastcall test(int i, int * ptr, int & ref)
{
_i$ = 8                         ; size = 4
_ref$ = 12                      ; size = 4
?test@@YIXHPAHAAH@Z PROC                ; test, COMDAT
; _ptr$ = ecx

; 8    :    global_int1 += *ptr;

    mov edx, DWORD PTR [ecx]

; 9    : 
; 10   :    global_int2 += ref;

    mov ecx, DWORD PTR _ref$[esp-4]
    mov eax, DWORD PTR _i$[esp-4]
    add DWORD PTR ?global_int1@@3HA, edx    ; global_int1
    mov edx, DWORD PTR [ecx]
    add DWORD PTR ?global_int2@@3HA, edx    ; global_int2

; 11   : 
; 12   :    int & ref2 = i;
; 13   :    global_int3 += ref2;

    add DWORD PTR ?global_int3@@3HA, eax    ; global_int3

; 14   : 
; 15   :    global_int4 += i;

    add DWORD PTR ?global_int4@@3HA, eax    ; global_int4
like image 45
Mark Ransom Avatar answered Nov 07 '22 05:11

Mark Ransom


I think what you meant to say is whether an integral value referred to by a reference reside in a register.

Usually, most compilers treat references the same way as pointers. That is to say references are just pointers with special "dereference" semantics built in. So, sadly there usually is no optimization unlike with integral values that can fit into registers. The only difference between a reference and a pointer is that a reference must (but not enforced by the compiler) refer to a valid object, whereas a pointer can be NULL.

like image 24
Michael Goldshteyn Avatar answered Nov 07 '22 03:11

Michael Goldshteyn


In many(if not most or all) implementations a reference is deep inside implemented via a pointer. So I think that doing it via a pointer or reference is pretty much irrelevant for an optimizer.

like image 36
Armen Tsirunyan Avatar answered Nov 07 '22 03:11

Armen Tsirunyan