Try add some display for LLIR
This commit is contained in:
		
							parent
							
								
									f55040ad00
								
							
						
					
					
						commit
						1ba1ae3213
					
				| @ -67,7 +67,7 @@ pub struct InstructionHolder { | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub(crate) struct Builder { | ||||
|     modules: Rc<RefCell<Vec<ModuleHolder>>>, | ||||
|     pub(crate) modules: Rc<RefCell<Vec<ModuleHolder>>>, | ||||
|     pub(crate) producer: String, | ||||
| } | ||||
| 
 | ||||
| @ -368,7 +368,6 @@ impl Builder { | ||||
|                 } | ||||
|                 Instr::FunctionCall(fun, params) => { | ||||
|                     let param_types = self.function_data(&fun).params; | ||||
|                     dbg!(¶m_types, ¶ms); | ||||
|                     if param_types.len() != params.len() { | ||||
|                         return Err(()); // TODO error: invalid amount of params
 | ||||
|                     } | ||||
|  | ||||
| @ -339,7 +339,7 @@ impl ModuleHolder { | ||||
|                     debug.locations.insert(location.value, location_ref); | ||||
|                 } | ||||
| 
 | ||||
|                 for meta in debug.debug.get_metadata().borrow().iter() { | ||||
|                 for meta in debug.debug.get_metadatas().borrow().iter() { | ||||
|                     let meta_ref = meta.compile(&debug); | ||||
|                     debug.metadata.insert(meta.value.clone(), meta_ref); | ||||
|                 } | ||||
| @ -606,7 +606,7 @@ impl FunctionHolder { | ||||
| 
 | ||||
|             let metadata = if let Some(debug) = debug { | ||||
|                 if let Some(value) = &self.data.debug { | ||||
|                     let subprogram = debug.debug.get_subprogram_data(&value); | ||||
|                     let subprogram = debug.debug.get_subprogram_data_unchecked(&value); | ||||
| 
 | ||||
|                     let mangled_length_ptr = &mut 0; | ||||
|                     let mangled_name = LLVMGetValueName2(function_ref, mangled_length_ptr); | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| use std::{cell::RefCell, rc::Rc}; | ||||
| use std::{cell::RefCell, collections::hash_map::Values, rc::Rc}; | ||||
| 
 | ||||
| use crate::builder::InstructionValue; | ||||
| 
 | ||||
| @ -161,7 +161,33 @@ impl DebugInformation { | ||||
|         value | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_metadata(&self) -> Rc<RefCell<Vec<DebugMetadataHolder>>> { | ||||
|     pub fn get_metadata(&self, value: DebugMetadataValue) -> DebugMetadata { | ||||
|         unsafe { self.metadata.borrow().get_unchecked(value.0).data.clone() } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_subprogram_data(&self, value: DebugProgramValue) -> Option<DebugSubprogramData> { | ||||
|         if value.0 == 0 { | ||||
|             None | ||||
|         } else { | ||||
|             Some(self.get_subprogram_data_unchecked(&value)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_type_data(&self, value: DebugTypeValue) -> DebugTypeData { | ||||
|         unsafe { self.types.borrow().get_unchecked(value.0).data.clone() } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_location(&self, value: DebugLocationValue) -> DebugLocation { | ||||
|         unsafe { | ||||
|             self.locations | ||||
|                 .borrow() | ||||
|                 .get_unchecked(value.1) | ||||
|                 .location | ||||
|                 .clone() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_metadatas(&self) -> Rc<RefCell<Vec<DebugMetadataHolder>>> { | ||||
|         self.metadata.clone() | ||||
|     } | ||||
| 
 | ||||
| @ -181,7 +207,7 @@ impl DebugInformation { | ||||
|         self.locations.clone() | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_subprogram_data(&self, value: &DebugProgramValue) -> DebugSubprogramData { | ||||
|     pub fn get_subprogram_data_unchecked(&self, value: &DebugProgramValue) -> DebugSubprogramData { | ||||
|         unsafe { | ||||
|             self.programs | ||||
|                 .borrow() | ||||
|  | ||||
| @ -1,20 +1,187 @@ | ||||
| //! Debug implementations for relevant types
 | ||||
| 
 | ||||
| use std::{ | ||||
|     fmt::{Debug, Write}, | ||||
|     fmt::{Debug, Display, Write}, | ||||
|     marker::PhantomData, | ||||
| }; | ||||
| 
 | ||||
| use crate::{ | ||||
|     CmpPredicate, Instr, InstructionData, TerminatorKind, | ||||
|     CmpPredicate, Context, Instr, InstructionData, TerminatorKind, | ||||
|     builder::*, | ||||
|     debug_information::{ | ||||
|         DebugArrayType, DebugBasicType, DebugFieldType, DebugLocation, DebugLocationValue, | ||||
|         DebugMetadataValue, DebugPointerType, DebugProgramValue, DebugScopeValue, DebugStructType, | ||||
|         DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable, | ||||
|         DebugLocation, DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, | ||||
|         DebugPointerType, DebugProgramValue, DebugRecordKind, DebugScopeValue, DebugStructType, | ||||
|         DebugSubprogramType, DebugTypeData, DebugTypeHolder, DebugTypeValue, | ||||
|     }, | ||||
|     pad_adapter::PadAdapter, | ||||
| }; | ||||
| 
 | ||||
| impl Display for Context { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         Display::fmt(&self.builder, f) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Display for Builder { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         writeln!(f, "Producer: {}", self.producer)?; | ||||
|         for module in self.modules.borrow().iter() { | ||||
|             if module.data.is_main { | ||||
|                 write!(f, "main ")?; | ||||
|             } | ||||
|             writeln!(f, "{} ({:?}) {{", module.data.name, module.value)?; | ||||
|             for function in &module.functions { | ||||
|                 let mut state = Default::default(); | ||||
|                 let mut inner = PadAdapter::wrap(f, &mut state); | ||||
|                 function.builder_fmt(&mut inner, self, &module.debug_information)?; | ||||
|             } | ||||
|             writeln!(f, "}}")?; | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl FunctionHolder { | ||||
|     fn builder_fmt( | ||||
|         &self, | ||||
|         f: &mut impl std::fmt::Write, | ||||
|         builder: &Builder, | ||||
|         debug: &Option<DebugInformation>, | ||||
|     ) -> std::fmt::Result { | ||||
|         if self.data.flags.is_imported { | ||||
|             write!(f, "imported ")?; | ||||
|         } | ||||
|         if self.data.flags.is_extern { | ||||
|             write!(f, "extern ")?; | ||||
|         } | ||||
|         if self.data.flags.is_pub { | ||||
|             write!(f, "pub ")?; | ||||
|         } | ||||
|         if self.data.flags.is_main { | ||||
|             write!(f, "main ")?; | ||||
|         } | ||||
|         let params = self | ||||
|             .data | ||||
|             .params | ||||
|             .iter() | ||||
|             .map(|p| format!("{:?}", p)) | ||||
|             .collect::<Vec<_>>() | ||||
|             .join(", "); | ||||
|         write!( | ||||
|             f, | ||||
|             "fn {}({}) -> {:?} ", | ||||
|             self.data.name, params, self.data.ret | ||||
|         )?; | ||||
| 
 | ||||
|         writeln!(f, "{{")?; | ||||
|         let mut state = Default::default(); | ||||
|         let mut inner = PadAdapter::wrap(f, &mut state); | ||||
|         writeln!(inner, "(Value = {:?}) ", self.value)?; | ||||
|         if let Some(debug) = self.data.debug { | ||||
|             writeln!(inner, "(Debug = {:?})", debug)?; | ||||
|         } | ||||
| 
 | ||||
|         for block in &self.blocks { | ||||
|             let mut state = Default::default(); | ||||
|             let mut inner = PadAdapter::wrap(&mut inner, &mut state); | ||||
|             block.builder_fmt(&mut inner, builder, debug)?; | ||||
|         } | ||||
| 
 | ||||
|         writeln!(f, "}}")?; | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl BlockHolder { | ||||
|     fn builder_fmt( | ||||
|         &self, | ||||
|         f: &mut impl std::fmt::Write, | ||||
|         builder: &Builder, | ||||
|         debug: &Option<DebugInformation>, | ||||
|     ) -> std::fmt::Result { | ||||
|         if self.data.deleted { | ||||
|             write!(f, "deleted ")?; | ||||
|         } | ||||
|         writeln!(f, "{} ({:?}):", self.data.name, self.value)?; | ||||
| 
 | ||||
|         for instr in &self.instructions { | ||||
|             let mut state = Default::default(); | ||||
|             let mut inner = PadAdapter::wrap(f, &mut state); | ||||
|             instr.builder_fmt(&mut inner, builder, debug)?; | ||||
|         } | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl InstructionHolder { | ||||
|     fn builder_fmt( | ||||
|         &self, | ||||
|         f: &mut impl std::fmt::Write, | ||||
|         builder: &Builder, | ||||
|         debug: &Option<DebugInformation>, | ||||
|     ) -> std::fmt::Result { | ||||
|         if let Some(record) = &self.record { | ||||
|             let kind = match record.kind { | ||||
|                 DebugRecordKind::Declare(instruction_value) => { | ||||
|                     format!("= {:?} (Assign)", instruction_value) | ||||
|                 } | ||||
|                 DebugRecordKind::Value(instruction_value) => { | ||||
|                     format!("= {:?} (Value)", instruction_value) | ||||
|                 } | ||||
|             }; | ||||
| 
 | ||||
|             if let Some(debug) = debug { | ||||
|                 writeln!(f, "  (Debug {} {})", record.variable.hr(debug), kind)?; | ||||
|             } | ||||
|         } | ||||
|         writeln!( | ||||
|             f, | ||||
|             "{:?} ({}) = {:?} ", | ||||
|             self.value, self.name, self.data.kind | ||||
|         )?; | ||||
|         if let Some(debug) = debug { | ||||
|             if let Some(location) = self.data.location { | ||||
|                 writeln!(f, "  ^  (At {}) ", debug.get_location(location))?; | ||||
|             } | ||||
|             if let Some(meta) = self.data.meta { | ||||
|                 writeln!(f, "  ^  (Meta {}) ", meta.hr(debug))?; | ||||
|             } | ||||
|         } | ||||
|         writeln!(f)?; | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl DebugMetadataValue { | ||||
|     fn hr(&self, debug: &DebugInformation) -> String { | ||||
|         match debug.get_metadata(*self) { | ||||
|             DebugMetadata::ParamVar(DebugParamVariable { | ||||
|                 name, | ||||
|                 arg_idx, | ||||
|                 location, | ||||
|                 ty, | ||||
|                 .. | ||||
|             }) => format!( | ||||
|                 "param {} (idx {}) (type {:?}) at {}", | ||||
|                 name, arg_idx, ty, location | ||||
|             ), | ||||
|             DebugMetadata::LocalVar(DebugLocalVariable { | ||||
|                 name, location, ty, .. | ||||
|             }) => format!("var {} (type {:?}) at {}", name, ty, location), | ||||
|             DebugMetadata::VarAssignment => todo!(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Display for DebugLocation { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         write!(f, "line {}, col {}", self.line, self.column) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Debug for Builder { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.debug_list().entries(self.get_modules().borrow().iter()); | ||||
| @ -29,7 +196,7 @@ pub struct PrintableModule<'ctx> { | ||||
| 
 | ||||
| impl<'ctx> Debug for PrintableModule<'ctx> { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         self.module.fmt(f) | ||||
|         Debug::fmt(&self.module, f) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -108,12 +275,22 @@ impl Debug for InstructionValue { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         write!( | ||||
|             f, | ||||
|             "I[{:0>2}-{:0>2}-{:0>2}-{:0>2}]", | ||||
|             &self.0.0.0.0, &self.0.0.1, &self.0.1, self.1 | ||||
|             "%{}.{}.{}.{}", | ||||
|             self.0.0.0.0, self.0.0.1, self.0.1, self.1 | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // impl Debug for InstructionValue {
 | ||||
| //     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | ||||
| //         write!(
 | ||||
| //             f,
 | ||||
| //             "I[{:0>2}-{:0>2}-{:0>2}-{:0>2}]",
 | ||||
| //             &self.0.0.0.0, &self.0.0.1, &self.0.1, self.1
 | ||||
| //         )
 | ||||
| //     }
 | ||||
| // }
 | ||||
| 
 | ||||
| impl Debug for TypeValue { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         write!(f, "Ty[{:0>2}-{:0>2}]", &self.0.0, self.1) | ||||
|  | ||||
| @ -16,6 +16,7 @@ pub mod builder; | ||||
| pub mod compile; | ||||
| pub mod debug_information; | ||||
| mod fmt; | ||||
| mod pad_adapter; | ||||
| mod util; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
|  | ||||
							
								
								
									
										69
									
								
								reid-llvm-lib/src/pad_adapter.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								reid-llvm-lib/src/pad_adapter.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| //! Copied from
 | ||||
| //! https://github.com/rust-lang/rust/blob/6b3ae3f6e45a33c2d95fa0362c9b2593e567fd34/library/core/src/fmt/builders.rs#L102
 | ||||
| 
 | ||||
| // Copyright (c) The Rust Project Contributors
 | ||||
| //
 | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||
| // of this software and associated documentation files (the "Software"), to deal
 | ||||
| // in the Software without restriction, including without limitation the rights
 | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||
| // copies of the Software, and to permit persons to whom the Software is
 | ||||
| // furnished to do so, subject to the following conditions:
 | ||||
| //
 | ||||
| // The above copyright notice and this permission notice shall be included in
 | ||||
| // all copies or substantial portions of the Software.
 | ||||
| //
 | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | ||||
| // SOFTWARE.
 | ||||
| 
 | ||||
| use std::fmt; | ||||
| 
 | ||||
| pub struct PadAdapter<'buf, 'state> { | ||||
|     buf: &'buf mut (dyn fmt::Write + 'buf), | ||||
|     state: &'state mut PadAdapterState, | ||||
| } | ||||
| 
 | ||||
| pub struct PadAdapterState { | ||||
|     on_newline: bool, | ||||
| } | ||||
| 
 | ||||
| impl Default for PadAdapterState { | ||||
|     fn default() -> Self { | ||||
|         PadAdapterState { on_newline: true } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'buf, 'state> PadAdapter<'buf, 'state> { | ||||
|     pub fn wrap<'slot, 'fmt: 'buf + 'slot>( | ||||
|         fmt: &'buf mut (dyn fmt::Write + 'buf), | ||||
|         state: &'state mut PadAdapterState, | ||||
|     ) -> Self { | ||||
|         PadAdapter { buf: fmt, state } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl fmt::Write for PadAdapter<'_, '_> { | ||||
|     fn write_str(&mut self, s: &str) -> fmt::Result { | ||||
|         for s in s.split_inclusive('\n') { | ||||
|             if self.state.on_newline { | ||||
|                 self.buf.write_str("    ")?; | ||||
|             } | ||||
|             self.state.on_newline = s.ends_with('\n'); | ||||
|             self.buf.write_str(s)?; | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     fn write_char(&mut self, c: char) -> fmt::Result { | ||||
|         if self.state.on_newline { | ||||
|             self.buf.write_str("    ")?; | ||||
|         } | ||||
|         self.state.on_newline = c == '\n'; | ||||
|         self.buf.write_char(c) | ||||
|     } | ||||
| } | ||||
| @ -27,7 +27,7 @@ use crate::{ | ||||
| /// LLIR that can then be finally compiled into LLVM IR.
 | ||||
| #[derive(Debug)] | ||||
| pub struct CodegenContext<'ctx> { | ||||
|     context: &'ctx Context, | ||||
|     pub(crate) context: &'ctx Context, | ||||
| } | ||||
| 
 | ||||
| impl<'ctx> CodegenContext<'ctx> { | ||||
|  | ||||
| @ -123,6 +123,8 @@ pub fn perform_all_passes<'map>( | ||||
| 
 | ||||
|     let state = context.pass(&mut LinkerPass { module_map })?; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     println!("{:-^100}", "LINKER OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     println!("{}", &context); | ||||
|     #[cfg(debug_assertions)] | ||||
| @ -139,6 +141,8 @@ pub fn perform_all_passes<'map>( | ||||
| 
 | ||||
|     let state = context.pass(&mut TypeInference { refs: &refs })?; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     println!("{:-^100}", "TYPE INFERRER OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     dbg!(&refs); | ||||
|     #[cfg(debug_assertions)] | ||||
| @ -159,6 +163,8 @@ pub fn perform_all_passes<'map>( | ||||
| 
 | ||||
|     let state = context.pass(&mut TypeCheck { refs: &refs })?; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     println!("{:-^100}", "TYPECHECKER OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     println!("{}", &context); | ||||
|     #[cfg(debug_assertions)] | ||||
| @ -197,7 +203,7 @@ pub fn compile_and_pass<'map>( | ||||
|     perform_all_passes(&mut mir_context, module_map)?; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     dbg!(&mir_context); | ||||
|     println!("{:-^100}", "FINAL OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     println!("{}", &mir_context); | ||||
| 
 | ||||
| @ -205,7 +211,7 @@ pub fn compile_and_pass<'map>( | ||||
|     let codegen_modules = mir_context.codegen(&mut context, &module_map); | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     dbg!(&codegen_modules); | ||||
|     println!("{}", &codegen_modules.context); | ||||
| 
 | ||||
|     let compiled = codegen_modules.compile(); | ||||
|     Ok(compiled.output()) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user