Can I implement optimization rules with typed-HIR?

I'm trying to implement an optimization rule that removes unnecessary memory allocation, and I wonder if I can implement this using typed-HIR.

Context

For some immutable variables declared with let keyword, you can reduce memory allocation by changing the keyword to const or static.

I thought I can use typed-HIR to implement an optimization pass which will change let declared variable to const, and use the inferred type.

I looked into MIR but it seems like it doesn't have any information for data types and how it was declared.

Example

You can see that there are 3 function, each declares an array within the scope of the function and it will return the integer at the location of the argument.

You can see that let_array comes with a lot of mov instruction that writes a lot of stuff on to the RAM (very slow!) while other function has only 1 mov instruction which is for reading a value from the memory.

#[no_mangle]
pub fn let_array(idx: u8)  -> isize
{
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29];
return array[idx as usize];
}

#[no_mangle]
pub fn const_array(idx: u8) -> isize
{
const ARRAY: [isize; 42] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29];
return ARRAY[idx as usize];
}

#[no_mangle]
pub fn static_array(idx: u8) -> isize
{
static ARRAY: [isize; 42] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29];
return ARRAY[idx as usize];
}

Can you do this in LLVM instead? It'd be nice to have it work without needing to think about THIR problems like blocks or whatever.

If I'm correct, LLVM can't tell how long the data written on the RAM has to exist. So I don't think you can really do that.

It's an alloca in LLVM. I see no reason it couldn't turn that into a longer-lived allocation if it wanted to.

1 Like

I think you are right.

After reading through the LLVM's manual, I realized that LLVM uses ‘llvm.lifetime.start’ Intrinsic' to tell memory object's lifetime.

I think I will see if I can implement it as a LLVM transformer.

https://llvm.org/docs/LangRef.html#alloca-instruction https://llvm.org/docs/LangRef.html#llvm-lifetime-start-intrinsic

Thanks a lot @scottmcm :smiley: