[LLVMdev] Testing LLVM on OS X
Patrick Flanagan
valtrain at mac.com
Wed May 12 13:56:01 PDT 2004
Sorry for the delayed response, we're having finals and stuff here so
I've been pretty distracted studying for those. I will grab the latest
from CVS tonight and rerun that and see what the difference is.
Patrick
On May 9, 2004, at 4:53 PM, Chris Lattner wrote:
> On Tue, 4 May 2004, Chris Lattner wrote:
>
>> On Tue, 4 May 2004, Chris Lattner wrote:
>>> I suspect that a large reason that LLVM does worst than a native C
>>> compiler with the CBE+GCC is that LLVM generates very low-level C
>>> code,
>>> and I'm not convinced that GCC is doing a very good job (ie, without
>>> syntactic loops).
>>
>> Yup, this is EXACTLY what is going on.
>>
>> I took this very simple C function:
>>
>> int Array[1000];
>> void test(int X) {
>> int i;
>> for (i = 0; i < 1000; ++i)
>> Array[i] += X;
>> }
>>
>> Compile with -O3 on OS/X gave me this:
>>
>> _test:
>> mflr r5
>> bcl 20,31,"L00000000001$pb"
>> "L00000000001$pb":
>> mflr r2
>> mtlr r5
>> addis r4,r2,ha16(L_Array$non_lazy_ptr-"L00000000001$pb")
>> li r2,0
>> lwz r9,lo16(L_Array$non_lazy_ptr-"L00000000001$pb")(r4)
>> li r4,1000
>> mtctr r4
>> L9:
>> lwzx r7,r2,r9 ; load
>> add r6,r7,r3 ; add
>> stwx r6,r2,r9 ; store
>> addi r2,r2,4 ; Increment pointer
>> bdnz L9 ; Decrement count register, branch
>> while not zero
>> blr
>>
>> This is nice code, good GCC. :)
>
> Okay, I changed the C backend to emit syntactic loops around the real
> loops, and it seems to make a big difference. LLVM now generates this
> code (note that the actual loop is not actually responsible for control
> flow, it's unreachable):
>
> void test(int l7_X) {
> unsigned l8_indvar;
> unsigned l8_indvar__PHI_TEMPORARY;
> int *l14_tmp_2E_4;
> int l7_tmp_2E_7;
> unsigned l8_indvar_2E_next;
>
> l8_indvar__PHI_TEMPORARY = 0u; /* for PHI node */
> goto l13_no_exit;
>
> do { /* Syntactic loop 'no_exit' to make GCC happy */
> l13_no_exit:
> l8_indvar = l8_indvar__PHI_TEMPORARY;
> l14_tmp_2E_4 = &Array[l8_indvar];
> l7_tmp_2E_7 = *l14_tmp_2E_4;
> *l14_tmp_2E_4 = (l7_tmp_2E_7 + l7_X);
> l8_indvar_2E_next = l8_indvar + 1u;
> l8_indvar__PHI_TEMPORARY = l8_indvar_2E_next; /* for PHI node */
> if ((l8_indvar_2E_next == 1000u)) {
> goto l13_return;
> } else {
> goto l13_no_exit;
> }
>
> } while (1); /* end of syntactic loop 'no_exit' */
> l13_return:
> return;
> }
>
> Instead of:
>
>> void test(int l7_X) {
>> unsigned l8_indvar;
>> unsigned l8_indvar__PHI_TEMPORARY;
>> int *l14_tmp_2E_5;
>> int l7_tmp_2E_9;
>> unsigned l8_indvar_2E_next;
>>
>> l8_indvar__PHI_TEMPORARY = 0u; /* for PHI node */
>>
>> l13_no_exit:
>> l8_indvar = l8_indvar__PHI_TEMPORARY;
>> l14_tmp_2E_5 = &Array[l8_indvar];
>> l7_tmp_2E_9 = *l14_tmp_2E_5;
>> *l14_tmp_2E_5 = (l7_tmp_2E_9 + l7_X);
>> l8_indvar_2E_next = l8_indvar + 1u;
>> if (!(l8_indvar_2E_next == 1000u)) {
>> l8_indvar__PHI_TEMPORARY = l8_indvar_2E_next; /* for PHI node */
>> goto l13_no_exit;
>> }
>> return;
>> }
>
> The new CBE generated code causes GCC to compile the function into:
>
> _test:
> mflr r5
> bcl 20,31,"L00000000001$pb"
> "L00000000001$pb":
> mflr r4
> mtlr r5
> addis r2,r4,ha16(_Array-"L00000000001$pb")
> li r4,1000
> mtctr r4
> la r9,lo16(_Array-"L00000000001$pb")(r2)
> li r2,0
> L10:
> L2:
> lwzx r7,r2,r9
> add r6,r7,r3
> stwx r6,r2,r9
> addi r2,r2,4
> bdnz L10
> L7:
> blr
>
> ... which is exactly what we want. Patrick, I would appreciate it if
> you
> could rerun your tests on PPC and let me know if this helps. :)
>
> -Chris
>
> --
> http://llvm.cs.uiuc.edu/
> http://www.nondot.org/~sabre/Projects/
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
>
More information about the llvm-dev
mailing list