Skip to content

Improve large structure instances handling #314

@DrXiao

Description

@DrXiao

Description

Currently, shecc cannot correctly handle large structure instances, causing operations such as large structure assignment and passing a large structure instance as a function argument to behave incorrect.

Current Bug

typedef struct {
    int a, b, c, d, e;
} large_struct_t;

void test(large_struct_t s)
{
    printf("test(s) = %d %d %d %d %d\n", s.a, s.b, s.c, s.d, s.e);
}

int main(void)
{
    large_struct_t s;
    s.a = 10;
    s.b = 20;
    s.c = 30;
    s.d = 40;
    s.e = 50;
    printf("s = %d %d %d %d %d\n", s.a, s.b, s.c, s.d, s.e);

    /* Bug 1: assignment is incorrect. */
    large_struct_t s2 = s;
    printf("s2 = %d %d %d %d %d\n", s2.a, s2.b, s2.c, s2.d, s2.e);

    /* Bug 2: pass a large instance as an argument is also incorrect. */
    test(s);
    return 0;
}
$ qemu-arm out/shecc-stage2.elf -o test test.c
$ qemu-arm test
s = 10 20 30 40 50
s2 = 10 0 0 0 0
test(s) = 10 1082129836 1082129828 1082129596 4

Root Cause

One of potential root causes is that the current register allocator lacks proper considerations about "physical storage". Consider the following structure definition in shecc's source code:

typedef struct {
    var_t *var;
    int polluted;
} regfile_t;

shecc uses instances of regfile_t to perform register allocation. Although a register may conceptually hold a variable (var_t), each register on Arm32 and RISC-V can store only a 4 byte object and thus cannot hold large objects.

However, during register allocation, shecc directly assigns each variable to a register even if the variable is a large structure whose size exceeds 4 bytes. Since no additional handling is performed, the code generator ultimately treats every register as if it always stores small objects when generating instructions, which leads to the aforementioned bugs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions