JuliaHubOSS / llvm-cbe

resurrected LLVM "C Backend", with improvements
Other
826 stars 141 forks source link

Global variable declared out of order #146

Closed SusanTan closed 7 months ago

SusanTan commented 2 years ago

Hi,

I came across this code: @tree.sdown = internal global i8 getelementptr inbounds ([4 x i8], [4 x i8] @.str, i32 0, i32 0), align 8, !dbg !0 @.str = private unnamed_addr constant [4 x i8] c" |\00", align 1

Since in llvm Global Variables can be out of order, the created cbe.c couldn't compile because the equivalent of @.str in cbe.c isn't declared when the equivalent of @tree.sdown tries to use it.

Original code can be found here: https://github.com/acmeism/RosettaCodeData/blob/master/Task/Visualize-a-tree/C/visualize-a-tree.c

Compiled using: clang -Xclang -disable-O0-optnone -S -emit-llvm -g visualize-a-tree.c

hikari-no-yume commented 2 years ago

I compiled it locally, I guess you're talking about this?

/* Global Variable Definitions and Initialization */
static uint8_t* tree_OC_sdown = ((&_OC_str.array[((int32_t)0)]));
static struct l_array_4_uint8_t _OC_str = { "  |" };

Looks like a straightforward case of the definitions happening in the wrong order. In other words: yeah, this is definitely a bug!

I've fixed some issues like this for types, but I guess constants have the same issue. I think it would be nice to have a generic solution to all variations of this problem. I think that would require using some sort of intermediate step within the “C backend”: generate all pieces with dependency information, sort them into the right order, then spit them out.

SusanTan commented 2 years ago

I compiled it locally, I guess you're talking about this?

/* Global Variable Definitions and Initialization */
static uint8_t* tree_OC_sdown = ((&_OC_str.array[((int32_t)0)]));
static struct l_array_4_uint8_t _OC_str = { "  |" };

Looks like a straightforward case of the definitions happening in the wrong order. In other words: yeah, this is definitely a bug!

I've fixed some issues like this for types, but I guess constants have the same issue. I think it would be nice to have a generic solution to all variations of this problem. I think that would require using some sort of intermediate step within the “C backend”: generate all pieces with dependency information, sort them into the right order, then spit them out.

Yep, the C code you showed was what I saw. I also agree to see a generic solution. Please let me know when the commit is made! Thank you :)