AnyDSL / thorin

The Higher-Order Intermediate Representation
https://anydsl.github.io
GNU Lesser General Public License v3.0
150 stars 15 forks source link

Issue with compilation when using arrays of functions, while executing `external functions` in the loop assigning the functions (in the array). #168

Open FelixKawala opened 1 month ago

FelixKawala commented 1 month ago

Might have two separate issues here. I commented some peculiarities I found while playing around with the code.

Issue description:

Seems like adding an external function messes up the code generation, when arrays of functions are assigned. This also happens for arrays of structs that contain functions.

Issues:

  1. It seems like only the last function that was written to (in an array of functions) can be accessed, when using an external function in the loop.

  2. We also can't use range(...) to write to the function array. We need to use unroll(...).

The following code will not compile in the current configuration:

#[import] fn extern_fun(&u8) -> ();

#[export]
fn @main() -> i32 {
    let dummy_u8_ref:&u8;

    let mut test_arr:[fn()->i32 * 3];   // <- set this to 2 (since we are using 1 in test_arr(1)()) and it will compile. It seems like the last function
    let iterations = 3;                 // <- or set this to 2                                      written to can be accessed, every other function can't. 

    for i in unroll(0, iterations){     //    Changing this to "range" will result in no compilation even when excluding "extern_fun".
        extern_fun(dummy_u8_ref);       //    Without this it will compile just fine. (When using unroll).
        test_arr(i) = @||{i};           //    Without this it will not compile (no matter where the array is accessed).
    }

    test_arr(1)()                       //    Set this to 2 and it will compile. (0 also won't work). Without this line it will compile just fine. (With range or unroll).
}
Hugobros3 commented 1 month ago

What error messages are you seeing ? I'd like additional informations on your setup to make sure I can reproduce properly.

Hugobros3 commented 1 month ago

Looks like an issue with closure conversion

Hugobros3 commented 1 month ago

Indeed. It's the same thing as: https://github.com/AnyDSL/thorin/issues/116

Hugobros3 commented 1 month ago

I note that mem2reg could also be made a bit stronger, and this would hide the bug in this case by effectively removing the array. But the real bug is that our closure conversion pass is busted and needs a rewrite. I attempted one last year but ended up shelving it because it was based on an experimental branch that ended up being unworkable.

FelixKawala commented 1 month ago

What error messages are you seeing ? I'd like additional informations on your setup to make sure I can reproduce properly.

Seems like you already reproduced it. Here are some infos anyways. I run a 64 Bit Ubuntu 22.04.4 LTS on an all-AMD machine. The Error/Assertion I'm seeing is:

artic: /home/felix/repo/anydsl-metaproject/llvm-project/llvm/lib/IR/Instructions.cpp:631: void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, const llvm::Twine&): Assertion `(Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"' failed.
make[2]: *** [CMakeFiles/svgf.dir/build.make:105: min_abstraction_example.ll] Aborted (core dumped)
make[2]: *** Deleting file 'min_abstraction_example.ll'
make[1]: *** [CMakeFiles/Makefile2:217: CMakeFiles/svgf.dir/all] Error 2
make: *** [Makefile:91: all] Error 2