Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example for build_switch using basic block references #155

Closed
ghaith opened this issue Feb 22, 2020 · 4 comments
Closed

Example for build_switch using basic block references #155

ghaith opened this issue Feb 22, 2020 · 4 comments
Labels
Milestone

Comments

@ghaith
Copy link
Contributor

ghaith commented Feb 22, 2020

While trying to implement a switch statement, we ran into the issue of not being able to pass basic blocks into the build_switch method as it requires a slice of (IntegerValue, &BasicBlocks) but we are building these blocks in a loop which will go out of scope, meaning we are not able to pass them as references.
It would seem natural to me that you would expect a BasicBlock in the method, and not a reference to it since it just a copied llvm-sys object anyway.
Could you give an example on how to implement such a build_switch?

Our code looks like this :

let mut cases = Vec::new();       
//generate a int_value and a BasicBlock for every case-body
for i in 1..conditional_blocks.len() {
    let conditional_block = &conditional_blocks[i];
    let basic_block = self.context.append_basic_block(self.current_function?, "case");
    let condition = self.generate_statement(&*conditional_block.condition)?;
    cases.push((condition.into_int_value(), basic_block));
}
let else_block = self.context.append_basic_block(self.current_function?, "else");

self.builder.build_switch(
    selector_statement.into_int_value(),
    &else_block, 
    cases.as_slice()); // I cannot get this as [(IntegerValue, &BasicBlock)]
 
  • Inkwell Branch Used: [e.g. llvm8-0]
@TheDan64
Copy link
Owner

Try cases.push((condition.into_int_value(), &basic_block));

@TheDan64
Copy link
Owner

Oh, I think I see what you're saying

@ghaith
Copy link
Contributor Author

ghaith commented Feb 23, 2020

I worked around the issue by mapping the vector like that :

 let cases_values : Vec<_> = cases.iter().map(|(value,block)| (value.clone(), block )).collect();

But it somehow feels strange to have to remap my vector and do an extra loop.
I understand that we cannot simply pass the blocks into a build_xxx method since you might want to use them later, but they are small/cheap objects, maybe they should be copied instead of referenced? Or am I missing a bigger picture here?

@TheDan64
Copy link
Owner

TheDan64 commented Feb 23, 2020

I think the short term solution here is to make it take ownership of the block.

Long term, we probably want to make Blocks Copy like the value types, and add the 'ctx lifetime to blocks also like how values have them.

@TheDan64 TheDan64 added this to the 0.1.0 milestone Feb 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants