Improve LLVM IR SSA names
This commit is contained in:
		
							parent
							
								
									71a01dad69
								
							
						
					
					
						commit
						33d5ee03f0
					
				| @ -18,9 +18,9 @@ fn main() { | |||||||
|         FunctionFlags::default(), |         FunctionFlags::default(), | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     let arg = m_entry.build(Constant(I32(5))).unwrap(); |     let arg = m_entry.build("const", Constant(I32(5))).unwrap(); | ||||||
|     let fibonacci_call = m_entry |     let fibonacci_call = m_entry | ||||||
|         .build(FunctionCall(fibonacci.value(), vec![arg])) |         .build("const", FunctionCall(fibonacci.value(), vec![arg])) | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
|     m_entry |     m_entry | ||||||
|         .terminate(TerminatorKind::Ret(fibonacci_call)) |         .terminate(TerminatorKind::Ret(fibonacci_call)) | ||||||
| @ -28,10 +28,10 @@ fn main() { | |||||||
| 
 | 
 | ||||||
|     let mut f_entry = fibonacci.block("entry"); |     let mut f_entry = fibonacci.block("entry"); | ||||||
| 
 | 
 | ||||||
|     let num_3 = f_entry.build(Constant(I32(3))).unwrap(); |     let num_3 = f_entry.build("const", Constant(I32(3))).unwrap(); | ||||||
|     let param_n = f_entry.build(Param(0)).unwrap(); |     let param_n = f_entry.build("param", Param(0)).unwrap(); | ||||||
|     let cond = f_entry |     let cond = f_entry | ||||||
|         .build(ICmp(CmpPredicate::LT, param_n, num_3)) |         .build("cmp", ICmp(CmpPredicate::LT, param_n, num_3)) | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
| 
 | 
 | ||||||
|     let mut then_b = fibonacci.block("then"); |     let mut then_b = fibonacci.block("then"); | ||||||
| @ -41,21 +41,21 @@ fn main() { | |||||||
|         .terminate(TerminatorKind::CondBr(cond, then_b.value(), else_b.value())) |         .terminate(TerminatorKind::CondBr(cond, then_b.value(), else_b.value())) | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
| 
 | 
 | ||||||
|     let ret_const = then_b.build(Constant(I32(1))).unwrap(); |     let ret_const = then_b.build("const", Constant(I32(1))).unwrap(); | ||||||
|     then_b.terminate(TerminatorKind::Ret(ret_const)).unwrap(); |     then_b.terminate(TerminatorKind::Ret(ret_const)).unwrap(); | ||||||
| 
 | 
 | ||||||
|     let const_1 = else_b.build(Constant(I32(1))).unwrap(); |     let const_1 = else_b.build("const", Constant(I32(1))).unwrap(); | ||||||
|     let const_2 = else_b.build(Constant(I32(2))).unwrap(); |     let const_2 = else_b.build("const", Constant(I32(2))).unwrap(); | ||||||
|     let param_1 = else_b.build(Sub(param_n, const_1)).unwrap(); |     let param_1 = else_b.build("sub", Sub(param_n, const_1)).unwrap(); | ||||||
|     let param_2 = else_b.build(Sub(param_n, const_2)).unwrap(); |     let param_2 = else_b.build("sub", Sub(param_n, const_2)).unwrap(); | ||||||
|     let call_1 = else_b |     let call_1 = else_b | ||||||
|         .build(FunctionCall(fibonacci.value(), vec![param_1])) |         .build("fibonacci", FunctionCall(fibonacci.value(), vec![param_1])) | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
|     let call_2 = else_b |     let call_2 = else_b | ||||||
|         .build(FunctionCall(fibonacci.value(), vec![param_2])) |         .build("fibonacci", FunctionCall(fibonacci.value(), vec![param_2])) | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
| 
 | 
 | ||||||
|     let add = else_b.build(Add(call_1, call_2)).unwrap(); |     let add = else_b.build("add", Add(call_1, call_2)).unwrap(); | ||||||
| 
 | 
 | ||||||
|     else_b.terminate(TerminatorKind::Ret(add)).unwrap(); |     else_b.terminate(TerminatorKind::Ret(add)).unwrap(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -61,6 +61,7 @@ pub struct BlockHolder { | |||||||
| pub struct InstructionHolder { | pub struct InstructionHolder { | ||||||
|     pub(crate) value: InstructionValue, |     pub(crate) value: InstructionValue, | ||||||
|     pub(crate) data: InstructionData, |     pub(crate) data: InstructionData, | ||||||
|  |     pub(crate) name: String, | ||||||
|     pub(crate) record: Option<InstructionDebugRecordData>, |     pub(crate) record: Option<InstructionDebugRecordData>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -149,6 +150,7 @@ impl Builder { | |||||||
|         &self, |         &self, | ||||||
|         block_val: &BlockValue, |         block_val: &BlockValue, | ||||||
|         data: InstructionData, |         data: InstructionData, | ||||||
|  |         name: String, | ||||||
|     ) -> Result<InstructionValue, ()> { |     ) -> Result<InstructionValue, ()> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let mut modules = self.modules.borrow_mut(); |             let mut modules = self.modules.borrow_mut(); | ||||||
| @ -159,6 +161,7 @@ impl Builder { | |||||||
|             block.instructions.push(InstructionHolder { |             block.instructions.push(InstructionHolder { | ||||||
|                 value, |                 value, | ||||||
|                 data, |                 data, | ||||||
|  |                 name, | ||||||
|                 record: None, |                 record: None, | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -743,6 +743,7 @@ impl InstructionHolder { | |||||||
|         _block: LLVMBasicBlockRef, |         _block: LLVMBasicBlockRef, | ||||||
|     ) -> LLVMValue { |     ) -> LLVMValue { | ||||||
|         let _ty = self.value.get_type(module.builder).unwrap(); |         let _ty = self.value.get_type(module.builder).unwrap(); | ||||||
|  |         let name = into_cstring(self.name.clone()); | ||||||
|         let val = unsafe { |         let val = unsafe { | ||||||
|             use super::Instr::*; |             use super::Instr::*; | ||||||
|             match &self.data.kind { |             match &self.data.kind { | ||||||
| @ -751,22 +752,22 @@ impl InstructionHolder { | |||||||
|                 Add(lhs, rhs) => { |                 Add(lhs, rhs) => { | ||||||
|                     let lhs_val = module.values.get(&lhs).unwrap().value_ref; |                     let lhs_val = module.values.get(&lhs).unwrap().value_ref; | ||||||
|                     let rhs_val = module.values.get(&rhs).unwrap().value_ref; |                     let rhs_val = module.values.get(&rhs).unwrap().value_ref; | ||||||
|                     LLVMBuildAdd(module.builder_ref, lhs_val, rhs_val, c"add".as_ptr()) |                     LLVMBuildAdd(module.builder_ref, lhs_val, rhs_val, name.as_ptr()) | ||||||
|                 } |                 } | ||||||
|                 Sub(lhs, rhs) => { |                 Sub(lhs, rhs) => { | ||||||
|                     let lhs_val = module.values.get(&lhs).unwrap().value_ref; |                     let lhs_val = module.values.get(&lhs).unwrap().value_ref; | ||||||
|                     let rhs_val = module.values.get(&rhs).unwrap().value_ref; |                     let rhs_val = module.values.get(&rhs).unwrap().value_ref; | ||||||
|                     LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, c"sub".as_ptr()) |                     LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, name.as_ptr()) | ||||||
|                 } |                 } | ||||||
|                 Mult(lhs, rhs) => { |                 Mult(lhs, rhs) => { | ||||||
|                     let lhs_val = module.values.get(&lhs).unwrap().value_ref; |                     let lhs_val = module.values.get(&lhs).unwrap().value_ref; | ||||||
|                     let rhs_val = module.values.get(&rhs).unwrap().value_ref; |                     let rhs_val = module.values.get(&rhs).unwrap().value_ref; | ||||||
|                     LLVMBuildMul(module.builder_ref, lhs_val, rhs_val, c"mul".as_ptr()) |                     LLVMBuildMul(module.builder_ref, lhs_val, rhs_val, name.as_ptr()) | ||||||
|                 } |                 } | ||||||
|                 And(lhs, rhs) => { |                 And(lhs, rhs) => { | ||||||
|                     let lhs_val = module.values.get(&lhs).unwrap().value_ref; |                     let lhs_val = module.values.get(&lhs).unwrap().value_ref; | ||||||
|                     let rhs_val = module.values.get(&rhs).unwrap().value_ref; |                     let rhs_val = module.values.get(&rhs).unwrap().value_ref; | ||||||
|                     LLVMBuildAnd(module.builder_ref, lhs_val, rhs_val, c"and".as_ptr()) |                     LLVMBuildAnd(module.builder_ref, lhs_val, rhs_val, name.as_ptr()) | ||||||
|                 } |                 } | ||||||
|                 ICmp(pred, lhs, rhs) => { |                 ICmp(pred, lhs, rhs) => { | ||||||
|                     let lhs = module.values.get(&lhs).unwrap(); |                     let lhs = module.values.get(&lhs).unwrap(); | ||||||
| @ -777,7 +778,7 @@ impl InstructionHolder { | |||||||
|                         pred.as_llvm_int(lhs._ty.signed()), |                         pred.as_llvm_int(lhs._ty.signed()), | ||||||
|                         lhs.value_ref, |                         lhs.value_ref, | ||||||
|                         rhs_val, |                         rhs_val, | ||||||
|                         c"icmp".as_ptr(), |                         name.as_ptr(), | ||||||
|                     ) |                     ) | ||||||
|                 } |                 } | ||||||
|                 FunctionCall(function_value, instruction_values) => { |                 FunctionCall(function_value, instruction_values) => { | ||||||
| @ -797,7 +798,7 @@ impl InstructionHolder { | |||||||
|                         fun.value_ref, |                         fun.value_ref, | ||||||
|                         param_list.as_mut_ptr(), |                         param_list.as_mut_ptr(), | ||||||
|                         param_list.len() as u32, |                         param_list.len() as u32, | ||||||
|                         c"call".as_ptr(), |                         name.as_ptr(), | ||||||
|                     ); |                     ); | ||||||
|                     if is_void { |                     if is_void { | ||||||
|                         LLVMContextSetDiscardValueNames(module.context_ref, 0); |                         LLVMContextSetDiscardValueNames(module.context_ref, 0); | ||||||
| @ -814,7 +815,7 @@ impl InstructionHolder { | |||||||
|                     let phi = LLVMBuildPhi( |                     let phi = LLVMBuildPhi( | ||||||
|                         module.builder_ref, |                         module.builder_ref, | ||||||
|                         _ty.as_llvm(module.context_ref, &module.types), |                         _ty.as_llvm(module.context_ref, &module.types), | ||||||
|                         c"phi".as_ptr(), |                         name.as_ptr(), | ||||||
|                     ); |                     ); | ||||||
|                     LLVMAddIncoming( |                     LLVMAddIncoming( | ||||||
|                         phi, |                         phi, | ||||||
| @ -827,13 +828,13 @@ impl InstructionHolder { | |||||||
|                 Alloca(ty) => LLVMBuildAlloca( |                 Alloca(ty) => LLVMBuildAlloca( | ||||||
|                     module.builder_ref, |                     module.builder_ref, | ||||||
|                     ty.as_llvm(module.context_ref, &module.types), |                     ty.as_llvm(module.context_ref, &module.types), | ||||||
|                     c"alloca".as_ptr(), |                     name.as_ptr(), | ||||||
|                 ), |                 ), | ||||||
|                 Load(ptr, ty) => LLVMBuildLoad2( |                 Load(ptr, ty) => LLVMBuildLoad2( | ||||||
|                     module.builder_ref, |                     module.builder_ref, | ||||||
|                     ty.as_llvm(module.context_ref, &module.types), |                     ty.as_llvm(module.context_ref, &module.types), | ||||||
|                     module.values.get(&ptr).unwrap().value_ref, |                     module.values.get(&ptr).unwrap().value_ref, | ||||||
|                     c"load".as_ptr(), |                     name.as_ptr(), | ||||||
|                 ), |                 ), | ||||||
|                 Store(ptr, val) => { |                 Store(ptr, val) => { | ||||||
|                     let store = LLVMBuildStore( |                     let store = LLVMBuildStore( | ||||||
| @ -849,7 +850,7 @@ impl InstructionHolder { | |||||||
|                         module.builder_ref, |                         module.builder_ref, | ||||||
|                         ty.as_llvm(module.context_ref, &module.types), |                         ty.as_llvm(module.context_ref, &module.types), | ||||||
|                         array_len, |                         array_len, | ||||||
|                         c"array_alloca".as_ptr(), |                         name.as_ptr(), | ||||||
|                     ) |                     ) | ||||||
|                 } |                 } | ||||||
|                 GetElemPtr(arr, indices) => { |                 GetElemPtr(arr, indices) => { | ||||||
| @ -867,32 +868,26 @@ impl InstructionHolder { | |||||||
|                         module.values.get(arr).unwrap().value_ref, |                         module.values.get(arr).unwrap().value_ref, | ||||||
|                         llvm_indices.as_mut_ptr(), |                         llvm_indices.as_mut_ptr(), | ||||||
|                         llvm_indices.len() as u32, |                         llvm_indices.len() as u32, | ||||||
|                         into_cstring(format!("array_gep")).as_ptr(), |                         name.as_ptr(), | ||||||
|                     ) |                     ) | ||||||
|                 } |                 } | ||||||
|                 GetStructElemPtr(struct_val, idx) => { |                 GetStructElemPtr(struct_val, idx) => { | ||||||
|                     let t = struct_val.get_type(module.builder).unwrap(); |                     let t = struct_val.get_type(module.builder).unwrap(); | ||||||
|                     let Type::Ptr(struct_t) = t else { panic!() }; |                     let Type::Ptr(struct_t) = t else { panic!() }; | ||||||
| 
 | 
 | ||||||
|                     let type_fmt = if let Type::CustomType(type_val) = *struct_t { |  | ||||||
|                         format!("M{}T{}", type_val.0.0, type_val.1) |  | ||||||
|                     } else { |  | ||||||
|                         format!("{:?}", struct_t) |  | ||||||
|                     }; |  | ||||||
| 
 |  | ||||||
|                     LLVMBuildStructGEP2( |                     LLVMBuildStructGEP2( | ||||||
|                         module.builder_ref, |                         module.builder_ref, | ||||||
|                         struct_t.as_llvm(module.context_ref, &module.types), |                         struct_t.as_llvm(module.context_ref, &module.types), | ||||||
|                         module.values.get(struct_val).unwrap().value_ref, |                         module.values.get(struct_val).unwrap().value_ref, | ||||||
|                         *idx, |                         *idx, | ||||||
|                         into_cstring(format!("struct.{}.{}.gep", type_fmt, idx)).as_ptr(), |                         name.as_ptr(), | ||||||
|                     ) |                     ) | ||||||
|                 } |                 } | ||||||
|                 ExtractValue(agg_val, idx) => LLVMBuildExtractValue( |                 ExtractValue(agg_val, idx) => LLVMBuildExtractValue( | ||||||
|                     module.builder_ref, |                     module.builder_ref, | ||||||
|                     module.values.get(agg_val).unwrap().value_ref, |                     module.values.get(agg_val).unwrap().value_ref, | ||||||
|                     *idx, |                     *idx, | ||||||
|                     c"extract".as_ptr(), |                     name.as_ptr(), | ||||||
|                 ), |                 ), | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|  | |||||||
| @ -71,6 +71,7 @@ impl Debug for BlockHolder { | |||||||
| impl Debug for InstructionHolder { | impl Debug for InstructionHolder { | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         self.value.fmt(f)?; |         self.value.fmt(f)?; | ||||||
|  |         write!(f, " ({})", self.name)?; | ||||||
|         f.write_str(" = ")?; |         f.write_str(" = ")?; | ||||||
|         self.data.fmt(f) |         self.data.fmt(f) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -204,7 +204,11 @@ pub struct Block<'builder> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'builder> Block<'builder> { | impl<'builder> Block<'builder> { | ||||||
|     pub fn build(&mut self, instruction: Instr) -> Result<InstructionValue, ()> { |     pub fn build<T: Into<String>>( | ||||||
|  |         &mut self, | ||||||
|  |         name: T, | ||||||
|  |         instruction: Instr, | ||||||
|  |     ) -> Result<InstructionValue, ()> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             self.builder.add_instruction( |             self.builder.add_instruction( | ||||||
|                 &self.value, |                 &self.value, | ||||||
| @ -213,6 +217,7 @@ impl<'builder> Block<'builder> { | |||||||
|                     location: None, |                     location: None, | ||||||
|                     meta: None, |                     meta: None, | ||||||
|                 }, |                 }, | ||||||
|  |                 name.into(), | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -343,11 +343,19 @@ impl mir::Module { | |||||||
|             let mut stack_values = HashMap::new(); |             let mut stack_values = HashMap::new(); | ||||||
|             for (i, (p_name, p_ty)) in mir_function.parameters.iter().enumerate() { |             for (i, (p_name, p_ty)) in mir_function.parameters.iter().enumerate() { | ||||||
|                 // Codegen actual parameters
 |                 // Codegen actual parameters
 | ||||||
|                 let param = entry.build(Instr::Param(i)).unwrap(); |                 let arg_name = format!("arg.{}", p_name); | ||||||
|                 let alloca = entry |                 let param = entry | ||||||
|                     .build(Instr::Alloca(p_ty.get_type(&type_values, &types))) |                     .build(format!("{}.get", arg_name), Instr::Param(i)) | ||||||
|  |                     .unwrap(); | ||||||
|  |                 let alloca = entry | ||||||
|  |                     .build( | ||||||
|  |                         &arg_name, | ||||||
|  |                         Instr::Alloca(p_ty.get_type(&type_values, &types)), | ||||||
|  |                     ) | ||||||
|  |                     .unwrap(); | ||||||
|  |                 entry | ||||||
|  |                     .build(format!("{}.store", arg_name), Instr::Store(alloca, param)) | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
|                 entry.build(Instr::Store(alloca, param)).unwrap(); |  | ||||||
|                 stack_values.insert( |                 stack_values.insert( | ||||||
|                     p_name.clone(), |                     p_name.clone(), | ||||||
|                     StackValue( |                     StackValue( | ||||||
| @ -470,15 +478,22 @@ impl mir::Statement { | |||||||
|             mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { |             mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { | ||||||
|                 let value = expression.codegen(scope, &state).unwrap(); |                 let value = expression.codegen(scope, &state).unwrap(); | ||||||
| 
 | 
 | ||||||
|  |                 dbg!(&name); | ||||||
|                 let alloca = scope |                 let alloca = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::Alloca(ty.get_type(scope.type_values, scope.types))) |                     .build( | ||||||
|  |                         name, | ||||||
|  |                         Instr::Alloca(ty.get_type(scope.type_values, scope.types)), | ||||||
|  |                     ) | ||||||
|                     .unwrap() |                     .unwrap() | ||||||
|                     .maybe_location(&mut scope.block, location); |                     .maybe_location(&mut scope.block, location); | ||||||
| 
 | 
 | ||||||
|                 let store = scope |                 let store = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::Store(alloca, value.instr())) |                     .build( | ||||||
|  |                         format!("{}.store", name), | ||||||
|  |                         Instr::Store(alloca, value.instr()), | ||||||
|  |                     ) | ||||||
|                     .unwrap() |                     .unwrap() | ||||||
|                     .maybe_location(&mut scope.block, location); |                     .maybe_location(&mut scope.block, location); | ||||||
| 
 | 
 | ||||||
| @ -522,6 +537,12 @@ impl mir::Statement { | |||||||
| 
 | 
 | ||||||
|                 let rhs_value = rhs.codegen(scope, state)?; |                 let rhs_value = rhs.codegen(scope, state)?; | ||||||
| 
 | 
 | ||||||
|  |                 let backing_var = if let Some(var) = lhs.backing_var() { | ||||||
|  |                     &format!("store.{}", var.1) | ||||||
|  |                 } else { | ||||||
|  |                     "store" | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|                 match lhs_value.0 { |                 match lhs_value.0 { | ||||||
|                     StackValueKind::Immutable(_) => { |                     StackValueKind::Immutable(_) => { | ||||||
|                         panic!("Tried to assign to immutable!") |                         panic!("Tried to assign to immutable!") | ||||||
| @ -529,7 +550,7 @@ impl mir::Statement { | |||||||
|                     StackValueKind::Mutable(instr) => { |                     StackValueKind::Mutable(instr) => { | ||||||
|                         scope |                         scope | ||||||
|                             .block |                             .block | ||||||
|                             .build(Instr::Store(instr, rhs_value.instr())) |                             .build(backing_var, Instr::Store(instr, rhs_value.instr())) | ||||||
|                             .unwrap() |                             .unwrap() | ||||||
|                             .maybe_location(&mut scope.block, location); |                             .maybe_location(&mut scope.block, location); | ||||||
|                     } |                     } | ||||||
| @ -572,10 +593,13 @@ impl mir::Expression { | |||||||
|                                 v.0.derive( |                                 v.0.derive( | ||||||
|                                     scope |                                     scope | ||||||
|                                         .block |                                         .block | ||||||
|                                         .build(Instr::Load( |                                         .build( | ||||||
|                                             v.0.instr(), |                                             format!("{}", varref.1), | ||||||
|                                             inner.get_type(scope.type_values, scope.types), |                                             Instr::Load( | ||||||
|                                         )) |                                                 v.0.instr(), | ||||||
|  |                                                 inner.get_type(scope.type_values, scope.types), | ||||||
|  |                                             ), | ||||||
|  |                                         ) | ||||||
|                                         .unwrap(), |                                         .unwrap(), | ||||||
|                                 ), |                                 ), | ||||||
|                                 *inner.clone(), |                                 *inner.clone(), | ||||||
| @ -604,20 +628,20 @@ impl mir::Expression { | |||||||
|                 Some(StackValue( |                 Some(StackValue( | ||||||
|                     StackValueKind::Immutable(match binop { |                     StackValueKind::Immutable(match binop { | ||||||
|                         mir::BinaryOperator::Add => { |                         mir::BinaryOperator::Add => { | ||||||
|                             scope.block.build(Instr::Add(lhs, rhs)).unwrap() |                             scope.block.build("add", Instr::Add(lhs, rhs)).unwrap() | ||||||
|                         } |                         } | ||||||
|                         mir::BinaryOperator::Minus => { |                         mir::BinaryOperator::Minus => { | ||||||
|                             scope.block.build(Instr::Sub(lhs, rhs)).unwrap() |                             scope.block.build("sub", Instr::Sub(lhs, rhs)).unwrap() | ||||||
|                         } |                         } | ||||||
|                         mir::BinaryOperator::Mult => { |                         mir::BinaryOperator::Mult => { | ||||||
|                             scope.block.build(Instr::Mult(lhs, rhs)).unwrap() |                             scope.block.build("mul", Instr::Mult(lhs, rhs)).unwrap() | ||||||
|                         } |                         } | ||||||
|                         mir::BinaryOperator::And => { |                         mir::BinaryOperator::And => { | ||||||
|                             scope.block.build(Instr::And(lhs, rhs)).unwrap() |                             scope.block.build("and", Instr::And(lhs, rhs)).unwrap() | ||||||
|                         } |                         } | ||||||
|                         mir::BinaryOperator::Cmp(l) => scope |                         mir::BinaryOperator::Cmp(l) => scope | ||||||
|                             .block |                             .block | ||||||
|                             .build(Instr::ICmp(l.int_predicate(), lhs, rhs)) |                             .build("cmp", Instr::ICmp(l.int_predicate(), lhs, rhs)) | ||||||
|                             .unwrap(), |                             .unwrap(), | ||||||
|                     }), |                     }), | ||||||
|                     TypeKind::U32, |                     TypeKind::U32, | ||||||
| @ -643,7 +667,10 @@ impl mir::Expression { | |||||||
|                     StackValueKind::Immutable( |                     StackValueKind::Immutable( | ||||||
|                         scope |                         scope | ||||||
|                             .block |                             .block | ||||||
|                             .build(Instr::FunctionCall(callee.ir.value(), params)) |                             .build( | ||||||
|  |                                 call.name.clone(), | ||||||
|  |                                 Instr::FunctionCall(callee.ir.value(), params), | ||||||
|  |                             ) | ||||||
|                             .unwrap(), |                             .unwrap(), | ||||||
|                     ), |                     ), | ||||||
|                     ret_type, |                     ret_type, | ||||||
| @ -673,12 +700,15 @@ impl mir::Expression { | |||||||
| 
 | 
 | ||||||
|                 let first = scope |                 let first = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::Constant(ConstValue::U32(0))) |                     .build("array.zero", Instr::Constant(ConstValue::U32(0))) | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
| 
 | 
 | ||||||
|                 let ptr = scope |                 let ptr = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::GetElemPtr(kind.instr(), vec![first, idx])) |                     .build( | ||||||
|  |                         format!("array.gep"), | ||||||
|  |                         Instr::GetElemPtr(kind.instr(), vec![first, idx]), | ||||||
|  |                     ) | ||||||
|                     .unwrap() |                     .unwrap() | ||||||
|                     .maybe_location(&mut scope.block, location); |                     .maybe_location(&mut scope.block, location); | ||||||
| 
 | 
 | ||||||
| @ -694,10 +724,13 @@ impl mir::Expression { | |||||||
|                         kind.derive( |                         kind.derive( | ||||||
|                             scope |                             scope | ||||||
|                                 .block |                                 .block | ||||||
|                                 .build(Instr::Load( |                                 .build( | ||||||
|                                     ptr, |                                     "array.load", | ||||||
|                                     val_t.get_type(scope.type_values, scope.types), |                                     Instr::Load( | ||||||
|                                 )) |                                         ptr, | ||||||
|  |                                         val_t.get_type(scope.type_values, scope.types), | ||||||
|  |                                     ), | ||||||
|  |                                 ) | ||||||
|                                 .unwrap() |                                 .unwrap() | ||||||
|                                 .maybe_location(&mut scope.block, location), |                                 .maybe_location(&mut scope.block, location), | ||||||
|                         ), |                         ), | ||||||
| @ -727,37 +760,45 @@ impl mir::Expression { | |||||||
|                     Box::new(elem_ty_kind.get_type(scope.type_values, scope.types)), |                     Box::new(elem_ty_kind.get_type(scope.type_values, scope.types)), | ||||||
|                     instr_list.len() as u64, |                     instr_list.len() as u64, | ||||||
|                 ); |                 ); | ||||||
|  |                 let array_name = format!("{}.{}", elem_ty_kind, instr_list.len()); | ||||||
|  |                 let load_n = format!("{}.load", array_name); | ||||||
| 
 | 
 | ||||||
|                 let array = scope |                 let array = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::Alloca(array_ty.clone())) |                     .build(&array_name, Instr::Alloca(array_ty.clone())) | ||||||
|                     .unwrap() |                     .unwrap() | ||||||
|                     .maybe_location(&mut scope.block, location); |                     .maybe_location(&mut scope.block, location); | ||||||
| 
 | 
 | ||||||
|                 for (index, instr) in instr_list.iter().enumerate() { |                 for (index, instr) in instr_list.iter().enumerate() { | ||||||
|  |                     let gep_n = format!("{}.{}.gep", array_name, index); | ||||||
|  |                     let store_n = format!("{}.{}.store", array_name, index); | ||||||
|  | 
 | ||||||
|                     let index_expr = scope |                     let index_expr = scope | ||||||
|                         .block |                         .block | ||||||
|                         .build(Instr::Constant(ConstValue::U32(index as u32))) |                         .build( | ||||||
|  |                             index.to_string(), | ||||||
|  |                             Instr::Constant(ConstValue::U32(index as u32)), | ||||||
|  |                         ) | ||||||
|                         .unwrap(); |                         .unwrap(); | ||||||
|                     let first = scope |                     let first = scope | ||||||
|                         .block |                         .block | ||||||
|                         .build(Instr::Constant(ConstValue::U32(0))) |                         .build("zero", Instr::Constant(ConstValue::U32(0))) | ||||||
|                         .unwrap(); |                         .unwrap(); | ||||||
|                     let ptr = scope |                     let ptr = scope | ||||||
|                         .block |                         .block | ||||||
|                         .build(Instr::GetElemPtr(array, vec![first, index_expr])) |                         .build(gep_n, Instr::GetElemPtr(array, vec![first, index_expr])) | ||||||
|                         .unwrap() |                         .unwrap() | ||||||
|                         .maybe_location(&mut scope.block, location); |                         .maybe_location(&mut scope.block, location); | ||||||
|                     scope |                     scope | ||||||
|                         .block |                         .block | ||||||
|                         .build(Instr::Store(ptr, *instr)) |                         .build(store_n, Instr::Store(ptr, *instr)) | ||||||
|                         .unwrap() |                         .unwrap() | ||||||
|                         .maybe_location(&mut scope.block, location); |                         .maybe_location(&mut scope.block, location); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 let array_val = scope |                 let array_val = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::Load(array, array_ty)) |                     .build(load_n, Instr::Load(array, array_ty)) | ||||||
|                     .unwrap() |                     .unwrap() | ||||||
|                     .maybe_location(&mut scope.block, location); |                     .maybe_location(&mut scope.block, location); | ||||||
| 
 | 
 | ||||||
| @ -779,9 +820,15 @@ impl mir::Expression { | |||||||
|                     scope.get_typedef(&name).unwrap().kind.clone(); |                     scope.get_typedef(&name).unwrap().kind.clone(); | ||||||
|                 let idx = struct_ty.find_index(field).unwrap(); |                 let idx = struct_ty.find_index(field).unwrap(); | ||||||
| 
 | 
 | ||||||
|  |                 let gep_n = format!("{}.{}.gep", name, field); | ||||||
|  |                 let load_n = format!("{}.{}.load", name, field); | ||||||
|  | 
 | ||||||
|                 let value = scope |                 let value = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::GetStructElemPtr(struct_val.instr(), idx as u32)) |                     .build( | ||||||
|  |                         gep_n, | ||||||
|  |                         Instr::GetStructElemPtr(struct_val.instr(), idx as u32), | ||||||
|  |                     ) | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
| 
 | 
 | ||||||
|                 // value.maybe_location(&mut scope.block, location);
 |                 // value.maybe_location(&mut scope.block, location);
 | ||||||
| @ -791,10 +838,13 @@ impl mir::Expression { | |||||||
|                         struct_val.0.derive( |                         struct_val.0.derive( | ||||||
|                             scope |                             scope | ||||||
|                                 .block |                                 .block | ||||||
|                                 .build(Instr::Load( |                                 .build( | ||||||
|                                     value, |                                     load_n, | ||||||
|                                     type_kind.get_type(scope.type_values, scope.types), |                                     Instr::Load( | ||||||
|                                 )) |                                         value, | ||||||
|  |                                         type_kind.get_type(scope.type_values, scope.types), | ||||||
|  |                                     ), | ||||||
|  |                                 ) | ||||||
|                                 .unwrap(), |                                 .unwrap(), | ||||||
|                         ), |                         ), | ||||||
|                         struct_ty.get_field_ty(&field).unwrap().clone(), |                         struct_ty.get_field_ty(&field).unwrap().clone(), | ||||||
| @ -808,22 +858,28 @@ impl mir::Expression { | |||||||
|             } |             } | ||||||
|             mir::ExprKind::Struct(name, items) => { |             mir::ExprKind::Struct(name, items) => { | ||||||
|                 let struct_ty = Type::CustomType(*scope.type_values.get(name)?); |                 let struct_ty = Type::CustomType(*scope.type_values.get(name)?); | ||||||
|  | 
 | ||||||
|  |                 let load_n = format!("{}.load", name); | ||||||
|  | 
 | ||||||
|                 let struct_ptr = scope |                 let struct_ptr = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::Alloca(struct_ty.clone())) |                     .build(name, Instr::Alloca(struct_ty.clone())) | ||||||
|                     .unwrap() |                     .unwrap() | ||||||
|                     .maybe_location(&mut scope.block, location); |                     .maybe_location(&mut scope.block, location); | ||||||
| 
 | 
 | ||||||
|                 for (i, (_, exp)) in items.iter().enumerate() { |                 for (i, (field_n, exp)) in items.iter().enumerate() { | ||||||
|  |                     let gep_n = format!("{}.{}.gep", name, field_n); | ||||||
|  |                     let store_n = format!("{}.{}.store", name, field_n); | ||||||
|  | 
 | ||||||
|                     let elem_ptr = scope |                     let elem_ptr = scope | ||||||
|                         .block |                         .block | ||||||
|                         .build(Instr::GetStructElemPtr(struct_ptr, i as u32)) |                         .build(gep_n, Instr::GetStructElemPtr(struct_ptr, i as u32)) | ||||||
|                         .unwrap() |                         .unwrap() | ||||||
|                         .maybe_location(&mut scope.block, location); |                         .maybe_location(&mut scope.block, location); | ||||||
|                     if let Some(val) = exp.codegen(scope, state) { |                     if let Some(val) = exp.codegen(scope, state) { | ||||||
|                         scope |                         scope | ||||||
|                             .block |                             .block | ||||||
|                             .build(Instr::Store(elem_ptr, val.instr())) |                             .build(store_n, Instr::Store(elem_ptr, val.instr())) | ||||||
|                             .unwrap() |                             .unwrap() | ||||||
|                             .maybe_location(&mut scope.block, location); |                             .maybe_location(&mut scope.block, location); | ||||||
|                     } |                     } | ||||||
| @ -831,7 +887,7 @@ impl mir::Expression { | |||||||
| 
 | 
 | ||||||
|                 let struct_val = scope |                 let struct_val = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build(Instr::Load(struct_ptr, struct_ty)) |                     .build(load_n, Instr::Load(struct_ptr, struct_ty)) | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
| 
 | 
 | ||||||
|                 Some(StackValue( |                 Some(StackValue( | ||||||
| @ -919,7 +975,10 @@ impl mir::IfExpression { | |||||||
|             incoming.extend(else_res.clone()); |             incoming.extend(else_res.clone()); | ||||||
|             let instr = scope |             let instr = scope | ||||||
|                 .block |                 .block | ||||||
|                 .build(Instr::Phi(incoming.iter().map(|i| i.instr()).collect())) |                 .build( | ||||||
|  |                     "phi", | ||||||
|  |                     Instr::Phi(incoming.iter().map(|i| i.instr()).collect()), | ||||||
|  |                 ) | ||||||
|                 .unwrap(); |                 .unwrap(); | ||||||
| 
 | 
 | ||||||
|             use StackValueKind::*; |             use StackValueKind::*; | ||||||
| @ -957,7 +1016,9 @@ impl mir::CmpOperator { | |||||||
| 
 | 
 | ||||||
| impl mir::Literal { | impl mir::Literal { | ||||||
|     fn as_const(&self, block: &mut Block) -> InstructionValue { |     fn as_const(&self, block: &mut Block) -> InstructionValue { | ||||||
|         block.build(self.as_const_kind()).unwrap() |         block | ||||||
|  |             .build(format!("{}", self), self.as_const_kind()) | ||||||
|  |             .unwrap() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn as_const_kind(&self) -> Instr { |     fn as_const_kind(&self) -> Instr { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user