
Code optimisation concerning pointers
Quote:
>Hello,
>I have a question about the way pointers can be used in C.
>I am working on an application, where structures are initialised with
>use of pointers. But now it appears that the compiler we are using, is
>not making very smart code.
>We are coding for a 286 microprocessor and the compiler is the IAR
>compiler (I wonder if anybody knows this one and has good or bad
>experiences with it).
>The problem is the following.
>Say we have a stucture like:
>struct test {
> int item1,
> int item2,
> int item3,
> int item4
>} test_struct;
>main()
>{
>test_struct *ptr;
> ptr = &test;
> ptr->item1 = 1;
> ptr->item2 = 2;
> ptr->item3 = 3;
> ptr->item4 = 4;
>}
It's noteworthy that in this case what you could do is declare a static
structure with which you could initialize *ptr in a single assignment:
test_struct *ptr;
static test_struct intial_value = { 1, 2, 3, 4 };
*ptr = initial_value;
This could generate better code.
Quote:
>The compiler creates the following kind of instructions:
> MOV DI, address TEST
> MOV int ptr [DI], 1
> MOV DI, address TEST
> MOV int ptr [DI + 2], 2
> MOV DI, address TEST
> MOV int ptr [DI + 4], 3
This is strage code. Given that the pointer has already been assigned to
a local pointer object, it's odd that the effective address of the test
object is being reloaded. This effective address cannot possibly be
changed by the data moves, and neither can the contents of register DI.
Quote:
>My question is: Is there a way to avoid the loading of the DI register
>for every statement that is compiled, and if so, how to do it. This
>because we are running out of code size.
You are asking a question that the C language cannot answer. All I can say is
that you should firstly read all of the available documentation about your
compiler. Be sure that you understand its various options that affect code
generation. The documentation may have the answer. Secondly, perhaps you
should obtain support from the vendors of that compiler.
The output above does not look like the compiler was operated using
optimization, because it failed to eliminated very obvious cases of useless
code.
My hypothesis about your compiler is that as it is translating code, it has a
way of representing where the current value of some declared object resides.
When it processes the assignment or initialization ptr = &test, it makes a note
in some internal table: ``the value of the pointer ptr is now associated with
the effective address of object test''. Then each time a dereference of that
pointer occurs, it generates some intermediate code of the form:
t1 <- &test
*t1 <- 1
t2 <- &test
*(t2 + 2) <- 2
where t1 and t2 represent abstract temporaries that are later assigned to
registers.
A optimization pass on intermediate code would eliminate redundant loads
of the effective address, realizing that t2 is the same as t1:
t1 <- &test
*t1 <- 1
*(t1 + 1) <- 1
This is just a hypothesis, of course.
Ensure that you are operating the compiler with optimization turn on,
and if it has multiple ``levels'' of optimization, experiment with these.
If following the documentation doesn't improve the results, and you cannot
accept the results, you will have to find an alternate compiler.
--
"In My Egotistical Opinion, most people's C programs should be
indented six feet downward and covered with dirt."
-- Blair P. Houghton