From d5f01a7b1f429aaca93ab5c6ff0f0f09f16fc784 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 17 Jan 2017 10:41:50 -0800 Subject: [PATCH] Continuing work on phi nodes --- src/compilation.rs | 43 ++++++++++++++++++++++++++++++++----------- src/llvm_wrap.rs | 24 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/compilation.rs b/src/compilation.rs index b8ac7b5..64b586d 100644 --- a/src/compilation.rs +++ b/src/compilation.rs @@ -55,6 +55,7 @@ struct CompilationData { builder: LLVMBuilderRef, variables: VariableMap, main_function: LLVMValueRef, + current_function: Option, } pub fn compile_ast(ast: AST, filename: &str, return_string: bool) -> Option { @@ -75,6 +76,7 @@ pub fn compile_ast(ast: AST, filename: &str, return_string: bool) -> Option { - /* 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; diff --git a/src/llvm_wrap.rs b/src/llvm_wrap.rs index b145695..401b7d0 100644 --- a/src/llvm_wrap.rs +++ b/src/llvm_wrap.rs @@ -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 { 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, + incoming_blocks: Vec) { + + 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()) }