-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Introduce phi nodes using the following algorithm:
- Traverse the predecessor blocks when processing a new block (and we should be traversing using
DfsPostOrder, so anyBasicBlockthat is a parent of a child block should already be traversed) - If the predecessor block has any
AstNodeleft on the stack, introducephinodes, with their arguments as the predecessorRegionIdas merge variabes. - If there is only one predecessor for the phi node we created, we can possibly simply resolve the phi node immediately, although this might not be robust for constructs like loops.
We may also have to consider weird edge cases like the following:
temp.arr = {1, temp.foo == 2 ? temp.bar : temp.baz, 3};Sample algorithm:
for pred in self.function.get_predecessors(block_id).map_err(|e| {
FunctionDecompilerError::FunctionError {
source: e,
backtrace: Backtrace::capture(),
context: ctx.get_error_context(),
}
})? {
let exec = ctx
.block_ast_node_stack
.get(&pred)
.expect("Critical error: stack should always be set for each basic block");
// iterate the stack and introduce phi nodes
for frame in exec.iter() {
match frame {
ExecutionFrame::StandaloneNode(node) => {
let current_region_id = self
.block_to_region
.get(&block_id)
.expect("[Bug] The region should exist.");
// For now, print debug
println!(
"Introducing Phi node for block {} to block {}. The value resolves to: {}",
pred,
block_id,
emit(node.clone())
);
}
_ => {
return Err(FunctionDecompilerError::Other {
message: "Expected StandaloneNode".to_string(),
context: ctx.get_error_context(),
backtrace: Backtrace::capture(),
});
}
}
}
}Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request