Continuing work on phi nodes
This commit is contained in:
parent
1702163478
commit
d5f01a7b1f
@ -55,6 +55,7 @@ struct CompilationData {
|
|||||||
builder: LLVMBuilderRef,
|
builder: LLVMBuilderRef,
|
||||||
variables: VariableMap,
|
variables: VariableMap,
|
||||||
main_function: LLVMValueRef,
|
main_function: LLVMValueRef,
|
||||||
|
current_function: Option<LLVMValueRef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_ast(ast: AST, filename: &str, return_string: bool) -> Option<String> {
|
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,
|
module: module,
|
||||||
variables: names,
|
variables: names,
|
||||||
main_function: main_function,
|
main_function: main_function,
|
||||||
|
current_function: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bb = LLVMWrap::AppendBasicBlockInContext(data.context, data.main_function, "entry");
|
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 function = self.prototype.codegen(data);
|
||||||
let ref body = self.body;
|
let ref body = self.body;
|
||||||
|
|
||||||
|
data.current_function = Some(function);
|
||||||
|
|
||||||
let return_type = LLVMWrap::Int64TypeInContext(data.context);
|
let return_type = LLVMWrap::Int64TypeInContext(data.context);
|
||||||
let mut ret = LLVMWrap::ConstInt(return_type, 0, false);
|
let mut ret = LLVMWrap::ConstInt(return_type, 0, false);
|
||||||
|
|
||||||
@ -156,6 +160,9 @@ impl CodeGen for Function {
|
|||||||
// get basic block of main
|
// get basic block of main
|
||||||
let main_bb = LLVMWrap::GetBasicBlocks(data.main_function).get(0).expect("Couldn't get first block of main").clone();
|
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);
|
LLVMWrap::PositionBuilderAtEnd(data.builder, main_bb);
|
||||||
|
|
||||||
|
data.current_function = None;
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,7 +176,7 @@ impl CodeGen for Prototype {
|
|||||||
for _ in 0..num_args {
|
for _ in 0..num_args {
|
||||||
arguments.push(LLVMWrap::Int64TypeInContext(data.context));
|
arguments.push(LLVMWrap::Int64TypeInContext(data.context));
|
||||||
}
|
}
|
||||||
|
|
||||||
let function_type =
|
let function_type =
|
||||||
LLVMWrap::FunctionType(return_type,
|
LLVMWrap::FunctionType(return_type,
|
||||||
arguments,
|
arguments,
|
||||||
@ -221,39 +228,53 @@ impl CodeGen for Expression {
|
|||||||
int_value
|
int_value
|
||||||
}
|
}
|
||||||
Conditional(ref test, ref then_expr, ref else_expr) => {
|
Conditional(ref test, ref then_expr, ref else_expr) => {
|
||||||
/*
|
|
||||||
let condition_value = test.codegen(data);
|
let condition_value = test.codegen(data);
|
||||||
let is_nonzero =
|
let is_nonzero =
|
||||||
LLVMWrap::BuildICmp(data.builder,
|
LLVMWrap::BuildICmp(data.builder,
|
||||||
LLVMIntPredicate::LLVMIntNE,
|
LLVMIntPredicate::LLVMIntNE,
|
||||||
condition_value,
|
condition_value,
|
||||||
zero,
|
zero,
|
||||||
"is_nonzero");
|
"ifcond");
|
||||||
|
|
||||||
let func: LLVMValueRef = data.main_function;
|
let func = LLVMWrap::GetBasicBlockParent(LLVMWrap::GetInsertBlock(data.builder));
|
||||||
let then_block =
|
|
||||||
LLVMWrap::AppendBasicBlockInContext(data.context, func, "entry");
|
let mut then_block =
|
||||||
let else_block =
|
LLVMWrap::AppendBasicBlockInContext(data.context, func, "then_block");
|
||||||
LLVMWrap::AppendBasicBlockInContext(data.context, func, "entry");
|
let mut else_block =
|
||||||
|
LLVMWrap::AppendBasicBlockInContext(data.context, func, "else_block");
|
||||||
let merge_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);
|
LLVMWrap::BuildCondBr(data.builder, is_nonzero, then_block, else_block);
|
||||||
|
|
||||||
|
// start inserting into then block
|
||||||
LLVMWrap::PositionBuilderAtEnd(data.builder, then_block);
|
LLVMWrap::PositionBuilderAtEnd(data.builder, then_block);
|
||||||
|
|
||||||
|
// then-block codegen
|
||||||
let then_return = then_expr.codegen(data);
|
let then_return = then_expr.codegen(data);
|
||||||
LLVMWrap::BuildBr(data.builder, merge_block);
|
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);
|
LLVMWrap::PositionBuilderAtEnd(data.builder, else_block);
|
||||||
let else_return = match *else_expr {
|
let else_return = match *else_expr {
|
||||||
Some(ref e) => e.codegen(data),
|
Some(ref e) => e.codegen(data),
|
||||||
None => zero,
|
None => zero,
|
||||||
};
|
};
|
||||||
LLVMWrap::BuildBr(data.builder, merge_block);
|
LLVMWrap::BuildBr(data.builder, merge_block);
|
||||||
|
else_block = LLVMWrap::GetInsertBlock(data.builder);
|
||||||
|
|
||||||
LLVMWrap::PositionBuilderAtEnd(data.builder, merge_block);
|
LLVMWrap::PositionBuilderAtEnd(data.builder, merge_block);
|
||||||
|
|
||||||
|
let phi = LLVMWrap::BuildPhi(data.builder, int_type, "phinnode");
|
||||||
|
|
||||||
|
|
||||||
zero
|
zero
|
||||||
*/
|
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
Block(ref exprs) => {
|
Block(ref exprs) => {
|
||||||
let mut ret = zero;
|
let mut ret = zero;
|
||||||
|
@ -239,6 +239,10 @@ pub fn BuildICmp(builder: LLVMBuilderRef,
|
|||||||
unsafe { core::LLVMBuildICmp(builder, op, lhs, rhs, name.as_ptr()) }
|
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> {
|
pub fn GetBasicBlocks(function: LLVMValueRef) -> Vec<LLVMBasicBlockRef> {
|
||||||
let size = CountBasicBlocks(function);
|
let size = CountBasicBlocks(function);
|
||||||
unsafe {
|
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 {
|
pub fn PrintModuleToFile(module: LLVMModuleRef, filename: &str) -> LLVMBool {
|
||||||
let out_file = CString::new(filename).unwrap();
|
let out_file = CString::new(filename).unwrap();
|
||||||
unsafe { core::LLVMPrintModuleToFile(module, out_file.as_ptr(), ptr::null_mut()) }
|
unsafe { core::LLVMPrintModuleToFile(module, out_file.as_ptr(), ptr::null_mut()) }
|
||||||
|
Loading…
Reference in New Issue
Block a user