Continuing work on phi nodes
This commit is contained in:
parent
1702163478
commit
d5f01a7b1f
@ -55,6 +55,7 @@ struct CompilationData {
|
||||
builder: LLVMBuilderRef,
|
||||
variables: VariableMap,
|
||||
main_function: LLVMValueRef,
|
||||
current_function: Option<LLVMValueRef>,
|
||||
}
|
||||
|
||||
pub fn compile_ast(ast: AST, filename: &str, return_string: bool) -> Option<String> {
|
||||
@ -75,6 +76,7 @@ pub fn compile_ast(ast: AST, filename: &str, return_string: bool) -> Option<Stri
|
||||
module: module,
|
||||
variables: names,
|
||||
main_function: main_function,
|
||||
current_function: None,
|
||||
};
|
||||
|
||||
let bb = LLVMWrap::AppendBasicBlockInContext(data.context, data.main_function, "entry");
|
||||
@ -135,6 +137,8 @@ impl CodeGen for Function {
|
||||
let function = self.prototype.codegen(data);
|
||||
let ref body = self.body;
|
||||
|
||||
data.current_function = Some(function);
|
||||
|
||||
let return_type = LLVMWrap::Int64TypeInContext(data.context);
|
||||
let mut ret = LLVMWrap::ConstInt(return_type, 0, false);
|
||||
|
||||
@ -156,6 +160,9 @@ impl CodeGen for Function {
|
||||
// get basic block of main
|
||||
let main_bb = LLVMWrap::GetBasicBlocks(data.main_function).get(0).expect("Couldn't get first block of main").clone();
|
||||
LLVMWrap::PositionBuilderAtEnd(data.builder, main_bb);
|
||||
|
||||
data.current_function = None;
|
||||
|
||||
ret
|
||||
}
|
||||
}
|
||||
@ -169,7 +176,7 @@ impl CodeGen for Prototype {
|
||||
for _ in 0..num_args {
|
||||
arguments.push(LLVMWrap::Int64TypeInContext(data.context));
|
||||
}
|
||||
|
||||
|
||||
let function_type =
|
||||
LLVMWrap::FunctionType(return_type,
|
||||
arguments,
|
||||
@ -221,39 +228,53 @@ impl CodeGen for Expression {
|
||||
int_value
|
||||
}
|
||||
Conditional(ref test, ref then_expr, ref else_expr) => {
|
||||
/*
|
||||
let condition_value = test.codegen(data);
|
||||
let is_nonzero =
|
||||
LLVMWrap::BuildICmp(data.builder,
|
||||
LLVMIntPredicate::LLVMIntNE,
|
||||
condition_value,
|
||||
zero,
|
||||
"is_nonzero");
|
||||
"ifcond");
|
||||
|
||||
let func: LLVMValueRef = data.main_function;
|
||||
let then_block =
|
||||
LLVMWrap::AppendBasicBlockInContext(data.context, func, "entry");
|
||||
let else_block =
|
||||
LLVMWrap::AppendBasicBlockInContext(data.context, func, "entry");
|
||||
let func = LLVMWrap::GetBasicBlockParent(LLVMWrap::GetInsertBlock(data.builder));
|
||||
|
||||
let mut then_block =
|
||||
LLVMWrap::AppendBasicBlockInContext(data.context, func, "then_block");
|
||||
let mut else_block =
|
||||
LLVMWrap::AppendBasicBlockInContext(data.context, func, "else_block");
|
||||
let merge_block =
|
||||
LLVMWrap::AppendBasicBlockInContext(data.context, func, "entry");
|
||||
LLVMWrap::AppendBasicBlockInContext(data.context, func, "ifcont");
|
||||
|
||||
// add conditional branch to ifcond block
|
||||
LLVMWrap::BuildCondBr(data.builder, is_nonzero, then_block, else_block);
|
||||
|
||||
// start inserting into then block
|
||||
LLVMWrap::PositionBuilderAtEnd(data.builder, then_block);
|
||||
|
||||
// then-block codegen
|
||||
let then_return = then_expr.codegen(data);
|
||||
LLVMWrap::BuildBr(data.builder, merge_block);
|
||||
|
||||
// update then block b/c recursive codegen() call may have changed the notion of
|
||||
// the current block
|
||||
then_block = LLVMWrap::GetInsertBlock(data.builder);
|
||||
|
||||
// then do the same stuff again for the else branch
|
||||
//
|
||||
LLVMWrap::PositionBuilderAtEnd(data.builder, else_block);
|
||||
let else_return = match *else_expr {
|
||||
Some(ref e) => e.codegen(data),
|
||||
None => zero,
|
||||
};
|
||||
LLVMWrap::BuildBr(data.builder, merge_block);
|
||||
else_block = LLVMWrap::GetInsertBlock(data.builder);
|
||||
|
||||
LLVMWrap::PositionBuilderAtEnd(data.builder, merge_block);
|
||||
|
||||
let phi = LLVMWrap::BuildPhi(data.builder, int_type, "phinnode");
|
||||
|
||||
|
||||
zero
|
||||
*/
|
||||
unreachable!()
|
||||
}
|
||||
Block(ref exprs) => {
|
||||
let mut ret = zero;
|
||||
|
@ -239,6 +239,10 @@ pub fn BuildICmp(builder: LLVMBuilderRef,
|
||||
unsafe { core::LLVMBuildICmp(builder, op, lhs, rhs, name.as_ptr()) }
|
||||
}
|
||||
|
||||
pub fn GetBasicBlockParent(block: LLVMBasicBlockRef) -> LLVMValueRef {
|
||||
unsafe { core::LLVMGetBasicBlockParent(block) }
|
||||
}
|
||||
|
||||
pub fn GetBasicBlocks(function: LLVMValueRef) -> Vec<LLVMBasicBlockRef> {
|
||||
let size = CountBasicBlocks(function);
|
||||
unsafe {
|
||||
@ -260,6 +264,26 @@ pub fn PrintModuleToString(module: LLVMModuleRef) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn BuildPhi(builder: LLVMBuilderRef, ty: LLVMTypeRef, name: &str) -> LLVMValueRef {
|
||||
unsafe {
|
||||
let name = CString::new(name).unwrap();
|
||||
unsafe { core::LLVMBuildPhi(builder, ty, name.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn AddIncoming(phi_node: LLVMValueRef, incoming_values: Vec<LLVMValueRef>,
|
||||
incoming_blocks: Vec<LLVMBasicBlockRef>) {
|
||||
|
||||
let count = incoming_blocks.len();
|
||||
if incoming_values.len() != count {
|
||||
panic!("Bad invocation of AddIncoming");
|
||||
}
|
||||
unsafe {
|
||||
//core::LLVMAddIncoming(phi_node);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub fn PrintModuleToFile(module: LLVMModuleRef, filename: &str) -> LLVMBool {
|
||||
let out_file = CString::new(filename).unwrap();
|
||||
unsafe { core::LLVMPrintModuleToFile(module, out_file.as_ptr(), ptr::null_mut()) }
|
||||
|
Loading…
Reference in New Issue
Block a user