Suppose I have compiled a record equivalent to:
struct ST {
short s;
char c3, c4;
}
STvar;
and llvm IR:
%STvar = alloca { i16, i8, i8 }
According to "The Often Misunderstood GEP Instruction", I can
construct an artificial llvm type to supply to GEP. (The "ugly GEP"?)
So I can think of three ways to access STvar.c3. These are in order
of increasing easiness for me to produce, but decreasing, by my guess,
useful information content for llvm. Also, I understand 3) would be
the only way, if c3 didn't start and end on byte boundaries.
; 1) Use a struct field number:
%1 = getelementptr { i16, i8, i8 }* %STvar i32 0, i32 1 ; {i8*}: &struct_member_no_1
%2 = load i8* %1
; 2) Use a byte number:
%3 = getelementptr [ 4 x i8 ]* %STvar i32 0, i32 2 ; {i8*}: &byte_number_2
%4 = load i8* %3
; 3) Use a word number, then shift & mask within:
%5 = getelementptr [ 1 x i32 ]* %STvar i32 0, i32 0 ; {i32*}: &word_number_0
%6 = load i32* %5 ; {i32}: word_number_0
%7 = lshr i32 %6 8 ; {i32}: right_justified
%8 = and i32 %7 0xff ; {i32}: irrelevant_bits_zeroed
Question 1:
Does this choice affect the optimization possibilities?
Now suppose I had provided debug metadata describing the original struct,
and the llvm infrastructure decided to keep STvar.c3 in a hardware machine
register for a while.
Question 2:
Would the final debug information reflect that STvar.c3 is in a register,
for the different ways of coding the llvm IR?