Compare commits
7 Commits
e1d014bcc2
...
f2c38d42b9
Author | SHA1 | Date | |
---|---|---|---|
f2c38d42b9 | |||
59ce454f91 | |||
94fbd51d35 | |||
a5bca6be82 | |||
e12d0be08b | |||
7c8a123945 | |||
e75c38ad85 |
2
Makefile
2
Makefile
@ -10,7 +10,7 @@ clean:
|
|||||||
rm -f $(BIN) $(SRC:.reid=.o) $(SRC:.reid=.asm) $(SRC:.reid=.ll)
|
rm -f $(BIN) $(SRC:.reid=.o) $(SRC:.reid=.asm) $(SRC:.reid=.ll)
|
||||||
|
|
||||||
$(BIN): $(SRC:.reid=.o)
|
$(BIN): $(SRC:.reid=.o)
|
||||||
$(LD) -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/crt1.o -lc $(LDFLAGS) $< -o$@
|
$(LD) -O0 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/crt1.o -lc $(LDFLAGS) $< -o$@
|
||||||
|
|
||||||
.SUFFIXES: .o .reid
|
.SUFFIXES: .o .reid
|
||||||
.reid.o:
|
.reid.o:
|
||||||
|
@ -8,6 +8,7 @@ use crate::{
|
|||||||
TerminatorKind, Type, TypeData,
|
TerminatorKind, Type, TypeData,
|
||||||
debug_information::{
|
debug_information::{
|
||||||
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
|
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
|
||||||
|
InstructionDebugRecordData,
|
||||||
},
|
},
|
||||||
util::match_types,
|
util::match_types,
|
||||||
};
|
};
|
||||||
@ -60,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) record: Option<InstructionDebugRecordData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -154,7 +156,11 @@ impl Builder {
|
|||||||
let function = module.functions.get_unchecked_mut(block_val.0.1);
|
let function = module.functions.get_unchecked_mut(block_val.0.1);
|
||||||
let block = function.blocks.get_unchecked_mut(block_val.1);
|
let block = function.blocks.get_unchecked_mut(block_val.1);
|
||||||
let value = InstructionValue(block.value, block.instructions.len());
|
let value = InstructionValue(block.value, block.instructions.len());
|
||||||
block.instructions.push(InstructionHolder { value, data });
|
block.instructions.push(InstructionHolder {
|
||||||
|
value,
|
||||||
|
data,
|
||||||
|
record: None,
|
||||||
|
});
|
||||||
|
|
||||||
// Drop modules so that it is no longer mutable borrowed
|
// Drop modules so that it is no longer mutable borrowed
|
||||||
// (check_instruction requires an immutable borrow).
|
// (check_instruction requires an immutable borrow).
|
||||||
@ -195,6 +201,21 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) unsafe fn add_instruction_record(
|
||||||
|
&self,
|
||||||
|
value: &InstructionValue,
|
||||||
|
record: InstructionDebugRecordData,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
let mut modules = self.modules.borrow_mut();
|
||||||
|
let module = modules.get_unchecked_mut(value.0.0.0.0);
|
||||||
|
let function = module.functions.get_unchecked_mut(value.0.0.1);
|
||||||
|
let block = function.blocks.get_unchecked_mut(value.0.1);
|
||||||
|
let instr = block.instructions.get_unchecked_mut(value.1);
|
||||||
|
instr.record = Some(record)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn set_debug_subprogram(
|
pub(crate) unsafe fn set_debug_subprogram(
|
||||||
&self,
|
&self,
|
||||||
value: &FunctionValue,
|
value: &FunctionValue,
|
||||||
|
@ -417,7 +417,6 @@ impl DebugScopeHolder {
|
|||||||
|
|
||||||
impl DebugMetadataHolder {
|
impl DebugMetadataHolder {
|
||||||
unsafe fn compile(&self, debug: &LLVMDebugInformation) -> LLVMMetadataRef {
|
unsafe fn compile(&self, debug: &LLVMDebugInformation) -> LLVMMetadataRef {
|
||||||
dbg!(&self.program);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
match &self.data {
|
match &self.data {
|
||||||
DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable(
|
DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable(
|
||||||
@ -432,7 +431,19 @@ impl DebugMetadataHolder {
|
|||||||
param.always_preserve as i32,
|
param.always_preserve as i32,
|
||||||
param.flags.as_llvm(),
|
param.flags.as_llvm(),
|
||||||
),
|
),
|
||||||
DebugMetadata::LocalVar(debug_local_variable) => todo!(),
|
DebugMetadata::LocalVar(var) => LLVMDIBuilderCreateAutoVariable(
|
||||||
|
debug.builder,
|
||||||
|
*debug.programs.get(&self.program).unwrap(),
|
||||||
|
into_cstring(var.name.clone()).as_ptr(),
|
||||||
|
var.name.len(),
|
||||||
|
debug.file_ref,
|
||||||
|
var.location.line,
|
||||||
|
*debug.types.get(&var.ty).unwrap(),
|
||||||
|
var.always_preserve as i32,
|
||||||
|
var.flags.as_llvm(),
|
||||||
|
var.alignment,
|
||||||
|
),
|
||||||
|
DebugMetadata::VarAssignment => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -756,11 +767,14 @@ impl InstructionHolder {
|
|||||||
module.values.get(&ptr).unwrap().value_ref,
|
module.values.get(&ptr).unwrap().value_ref,
|
||||||
c"load".as_ptr(),
|
c"load".as_ptr(),
|
||||||
),
|
),
|
||||||
Store(ptr, val) => LLVMBuildStore(
|
Store(ptr, val) => {
|
||||||
module.builder_ref,
|
let store = LLVMBuildStore(
|
||||||
module.values.get(&val).unwrap().value_ref,
|
module.builder_ref,
|
||||||
module.values.get(&ptr).unwrap().value_ref,
|
module.values.get(&val).unwrap().value_ref,
|
||||||
),
|
module.values.get(&ptr).unwrap().value_ref,
|
||||||
|
);
|
||||||
|
store
|
||||||
|
}
|
||||||
ArrayAlloca(ty, len) => {
|
ArrayAlloca(ty, len) => {
|
||||||
let array_len = ConstValue::U16(*len as u16).as_llvm(module);
|
let array_len = ConstValue::U16(*len as u16).as_llvm(module);
|
||||||
LLVMBuildArrayAlloca(
|
LLVMBuildArrayAlloca(
|
||||||
@ -808,8 +822,51 @@ impl InstructionHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if let Some(record) = &self.record {
|
||||||
|
let debug = module.debug.as_ref().unwrap();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut addr = Vec::<u64>::new();
|
||||||
|
let expr =
|
||||||
|
LLVMDIBuilderCreateExpression(debug.builder, addr.as_mut_ptr(), addr.len());
|
||||||
|
|
||||||
|
let location = LLVMDIBuilderCreateDebugLocation(
|
||||||
|
module.context_ref,
|
||||||
|
record.location.line,
|
||||||
|
record.location.column,
|
||||||
|
*debug.programs.get(&record.scope).unwrap(),
|
||||||
|
null_mut(),
|
||||||
|
);
|
||||||
|
|
||||||
|
match record.kind {
|
||||||
|
DebugRecordKind::Declare(instruction_value) => {
|
||||||
|
dbg!(&self.value, &instruction_value);
|
||||||
|
|
||||||
|
LLVMDIBuilderInsertDeclareRecordBefore(
|
||||||
|
debug.builder,
|
||||||
|
module.values.get(&instruction_value).unwrap().value_ref,
|
||||||
|
*debug.metadata.get(&record.variable).unwrap(),
|
||||||
|
expr,
|
||||||
|
location,
|
||||||
|
val,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
DebugRecordKind::Value(instruction_value) => {
|
||||||
|
LLVMDIBuilderInsertDbgValueRecordBefore(
|
||||||
|
debug.builder,
|
||||||
|
module.values.get(&instruction_value).unwrap().value_ref,
|
||||||
|
*debug.metadata.get(&record.variable).unwrap(),
|
||||||
|
expr,
|
||||||
|
location,
|
||||||
|
val,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
if let Some(location) = &self.data.location {
|
if let Some(location) = &self.data.location {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// dbg!(&self.data.kind, LLVMGetValueKind(val));
|
||||||
match LLVMGetValueKind(val) {
|
match LLVMGetValueKind(val) {
|
||||||
LLVMValueKind::LLVMInstructionValueKind
|
LLVMValueKind::LLVMInstructionValueKind
|
||||||
| LLVMValueKind::LLVMMemoryDefValueKind
|
| LLVMValueKind::LLVMMemoryDefValueKind
|
||||||
@ -835,6 +892,26 @@ impl InstructionHolder {
|
|||||||
value_ref: val,
|
value_ref: val,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_inner_value(&self) -> Option<InstructionValue> {
|
||||||
|
match &self.data.kind {
|
||||||
|
crate::Instr::Param(_) => None,
|
||||||
|
crate::Instr::Constant(_) => None,
|
||||||
|
crate::Instr::Add(_, _) => None,
|
||||||
|
crate::Instr::Sub(_, _) => None,
|
||||||
|
crate::Instr::Mult(_, _) => None,
|
||||||
|
crate::Instr::And(_, _) => None,
|
||||||
|
crate::Instr::Phi(_) => None,
|
||||||
|
crate::Instr::Alloca(_, _) => todo!(),
|
||||||
|
crate::Instr::Load(_, _) => None,
|
||||||
|
crate::Instr::Store(_, val) => Some(*val),
|
||||||
|
crate::Instr::ArrayAlloca(_, _) => None,
|
||||||
|
crate::Instr::GetElemPtr(_, _) => None,
|
||||||
|
crate::Instr::GetStructElemPtr(_, _) => None,
|
||||||
|
crate::Instr::ICmp(_, _, _) => None,
|
||||||
|
crate::Instr::FunctionCall(_, _) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminatorKind {
|
impl TerminatorKind {
|
||||||
|
@ -6,8 +6,13 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CmpPredicate, Instr, InstructionData, TerminatorKind, builder::*,
|
CmpPredicate, Instr, InstructionData, TerminatorKind,
|
||||||
debug_information::DebugLocationValue,
|
builder::*,
|
||||||
|
debug_information::{
|
||||||
|
DebugBasicType, DebugLocation, DebugLocationValue, DebugMetadataHolder, DebugMetadataValue,
|
||||||
|
DebugProgramValue, DebugScopeValue, DebugSubprogramType, DebugTypeData, DebugTypeHolder,
|
||||||
|
DebugTypeValue,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Debug for Builder {
|
impl Debug for Builder {
|
||||||
@ -80,15 +85,6 @@ impl Debug for InstructionData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for DebugLocationValue {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_tuple("DebugLocationValue")
|
|
||||||
.field(&self.0)
|
|
||||||
.field(&self.1)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for ModuleValue {
|
impl Debug for ModuleValue {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "M[{:0>2}]", self.0)
|
write!(f, "M[{:0>2}]", self.0)
|
||||||
@ -229,3 +225,84 @@ impl Debug for TerminatorKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugTypeHolder {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_tuple(&format!("DebugTypeHolder {:?}", self.value))
|
||||||
|
.field(&self.data)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugTypeData {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Basic(basic) => Debug::fmt(basic, f),
|
||||||
|
Self::Subprogram(subprogram) => Debug::fmt(subprogram, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugBasicType {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_tuple("BasicType")
|
||||||
|
.field(&self.name)
|
||||||
|
.field(&self.size_bits)
|
||||||
|
.field(&self.encoding)
|
||||||
|
.field(&self.flags)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugSubprogramType {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_tuple("Subprogram")
|
||||||
|
.field(&self.params)
|
||||||
|
.field(&self.flags)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugMetadataValue {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "Meta[{}]", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugScopeValue {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Scope[{}]",
|
||||||
|
self.0
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugTypeValue {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "Type[{}]", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugProgramValue {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "Subprogram[{}]", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugLocationValue {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "Value[{:?}][{}]", self.0, self.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for DebugLocation {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "ln {}, col {}", self.line, self.column)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
use crate::builder::InstructionValue;
|
||||||
|
|
||||||
|
#[derive(Clone, Hash, PartialEq, Eq)]
|
||||||
pub struct DebugScopeValue(pub Vec<usize>);
|
pub struct DebugScopeValue(pub Vec<usize>);
|
||||||
|
|
||||||
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
||||||
pub struct DebugLocationValue(pub DebugProgramValue, pub usize);
|
pub struct DebugLocationValue(pub DebugProgramValue, pub usize);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
||||||
pub struct DebugTypeValue(pub usize);
|
pub struct DebugTypeValue(pub usize);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
||||||
pub struct DebugMetadataValue(pub usize);
|
pub struct DebugMetadataValue(pub usize);
|
||||||
|
|
||||||
/// Represents either a subprogram, or the compilation context
|
/// Represents either a subprogram, or the compilation context
|
||||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
||||||
pub struct DebugProgramValue(pub usize);
|
pub struct DebugProgramValue(pub usize);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -37,7 +39,7 @@ pub struct DebugMetadataHolder {
|
|||||||
pub(crate) data: DebugMetadata,
|
pub(crate) data: DebugMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DebugTypeHolder {
|
pub struct DebugTypeHolder {
|
||||||
pub(crate) value: DebugTypeValue,
|
pub(crate) value: DebugTypeValue,
|
||||||
pub(crate) data: DebugTypeData,
|
pub(crate) data: DebugTypeData,
|
||||||
@ -153,6 +155,7 @@ impl DebugInformation {
|
|||||||
match &metadata {
|
match &metadata {
|
||||||
DebugMetadata::ParamVar(debug_param_variable) => todo!(),
|
DebugMetadata::ParamVar(debug_param_variable) => todo!(),
|
||||||
DebugMetadata::LocalVar(debug_local_variable) => todo!(),
|
DebugMetadata::LocalVar(debug_local_variable) => todo!(),
|
||||||
|
DebugMetadata::VarAssignment => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +200,7 @@ impl DebugInformation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct DebugLocation {
|
pub struct DebugLocation {
|
||||||
pub line: u32,
|
pub line: u32,
|
||||||
pub column: u32,
|
pub column: u32,
|
||||||
@ -207,6 +210,7 @@ pub struct DebugLocation {
|
|||||||
pub enum DebugMetadata {
|
pub enum DebugMetadata {
|
||||||
ParamVar(DebugParamVariable),
|
ParamVar(DebugParamVariable),
|
||||||
LocalVar(DebugLocalVariable),
|
LocalVar(DebugLocalVariable),
|
||||||
|
VarAssignment,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -229,9 +233,10 @@ pub struct DebugParamVariable {
|
|||||||
pub struct DebugLocalVariable {
|
pub struct DebugLocalVariable {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub location: DebugLocation,
|
pub location: DebugLocation,
|
||||||
pub ty: DebugMetadataValue,
|
pub ty: DebugTypeValue,
|
||||||
pub always_preserve: bool,
|
pub always_preserve: bool,
|
||||||
pub alignment: u32,
|
pub alignment: u32,
|
||||||
|
pub flags: DwarfFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DebugSubprogramOptionals {
|
impl Default for DebugSubprogramOptionals {
|
||||||
@ -249,13 +254,13 @@ impl Default for DebugSubprogramOptionals {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DwarfFlags;
|
pub struct DwarfFlags;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone)]
|
||||||
pub enum DebugTypeData {
|
pub enum DebugTypeData {
|
||||||
Basic(DebugBasicType),
|
Basic(DebugBasicType),
|
||||||
Subprogram(DebugSubprogramTypeData),
|
Subprogram(DebugSubprogramTypeData),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DebugBasicType {
|
pub struct DebugBasicType {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
/// Size of the type.
|
/// Size of the type.
|
||||||
@ -311,3 +316,17 @@ pub struct DebugSubprogramOptionals {
|
|||||||
/// prototyped or not.
|
/// prototyped or not.
|
||||||
pub flags: DwarfFlags,
|
pub flags: DwarfFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct InstructionDebugRecordData {
|
||||||
|
pub scope: DebugProgramValue,
|
||||||
|
pub variable: DebugMetadataValue,
|
||||||
|
pub location: DebugLocation,
|
||||||
|
pub kind: DebugRecordKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum DebugRecordKind {
|
||||||
|
Declare(InstructionValue),
|
||||||
|
Value(InstructionValue),
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue,
|
|||||||
use debug::PrintableModule;
|
use debug::PrintableModule;
|
||||||
use debug_information::{
|
use debug_information::{
|
||||||
DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
|
DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
|
||||||
|
InstructionDebugRecordData,
|
||||||
};
|
};
|
||||||
use util::match_types;
|
use util::match_types;
|
||||||
|
|
||||||
@ -275,6 +276,12 @@ impl InstructionValue {
|
|||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_record(&self, block: &mut Block, record: InstructionDebugRecordData) {
|
||||||
|
unsafe {
|
||||||
|
block.builder.add_instruction_record(self, record);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -4,10 +4,10 @@ use reid_lib::{
|
|||||||
builder::{InstructionValue, TypeValue},
|
builder::{InstructionValue, TypeValue},
|
||||||
compile::CompiledModule,
|
compile::CompiledModule,
|
||||||
debug_information::{
|
debug_information::{
|
||||||
DebugBasicType, DebugFileData, DebugInformation, DebugLocation, DebugMetadata,
|
DebugBasicType, DebugFileData, DebugInformation, DebugLocalVariable, DebugLocation,
|
||||||
DebugMetadataValue, DebugParamVariable, DebugProgramValue, DebugScopeValue,
|
DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugProgramValue, DebugRecordKind,
|
||||||
DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramTypeData, DebugTypeData,
|
DebugScopeValue, DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramTypeData,
|
||||||
DebugTypeValue, DwarfEncoding, DwarfFlags,
|
DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags, InstructionDebugRecordData,
|
||||||
},
|
},
|
||||||
Block, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr,
|
Block, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr,
|
||||||
Module, NamedStruct, TerminatorKind as Term, Type,
|
Module, NamedStruct, TerminatorKind as Term, Type,
|
||||||
@ -97,7 +97,7 @@ pub struct StackFunction<'ctx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct StackValue(StackValueKind, Type);
|
pub struct StackValue(StackValueKind, TypeKind);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum StackValueKind {
|
pub enum StackValueKind {
|
||||||
@ -106,6 +106,16 @@ pub enum StackValueKind {
|
|||||||
Any(InstructionValue),
|
Any(InstructionValue),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StackValueKind {
|
||||||
|
unsafe fn get_inner(&self) -> InstructionValue {
|
||||||
|
match &self {
|
||||||
|
StackValueKind::Immutable(val) => *val,
|
||||||
|
StackValueKind::Mutable(val) => *val,
|
||||||
|
StackValueKind::Any(val) => *val,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'ctx, 'a> Scope<'ctx, 'a> {
|
impl<'ctx, 'a> Scope<'ctx, 'a> {
|
||||||
fn with_block(&self, block: Block<'ctx>) -> Scope<'ctx, 'a> {
|
fn with_block(&self, block: Block<'ctx>) -> Scope<'ctx, 'a> {
|
||||||
Scope {
|
Scope {
|
||||||
@ -285,12 +295,17 @@ 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 alloca = entry
|
||||||
|
.build(Instr::Alloca(
|
||||||
|
p_name.clone(),
|
||||||
|
p_ty.get_type(&type_values, &types),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
entry.build(Instr::Store(alloca, param)).unwrap();
|
||||||
stack_values.insert(
|
stack_values.insert(
|
||||||
p_name.clone(),
|
p_name.clone(),
|
||||||
StackValue(
|
StackValue(StackValueKind::Immutable(alloca), p_ty.clone()),
|
||||||
StackValueKind::Immutable(entry.build(Instr::Param(i)).unwrap()),
|
|
||||||
p_ty.get_type(&type_values, &types),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Generate debug info
|
// Generate debug info
|
||||||
@ -394,41 +409,68 @@ impl mir::Statement {
|
|||||||
scope: &mut Scope<'ctx, 'a>,
|
scope: &mut Scope<'ctx, 'a>,
|
||||||
state: &State,
|
state: &State,
|
||||||
) -> Option<InstructionValue> {
|
) -> Option<InstructionValue> {
|
||||||
|
let location = self.1.into_debug(scope.tokens).unwrap();
|
||||||
|
let location = scope
|
||||||
|
.debug
|
||||||
|
.as_ref()
|
||||||
|
.map(|d| d.info.location(&d.scope, location));
|
||||||
|
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
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();
|
||||||
scope.stack_values.insert(
|
|
||||||
name.clone(),
|
let alloca = scope
|
||||||
StackValue(
|
.block
|
||||||
match mutable {
|
.build(Instr::Alloca(
|
||||||
false => StackValueKind::Immutable(value),
|
name.clone(),
|
||||||
true => match ty {
|
|
||||||
// Struct is already allocated at initialization
|
|
||||||
TypeKind::Array(_, _) => StackValueKind::Mutable(value),
|
|
||||||
TypeKind::CustomType(n) => match scope
|
|
||||||
.types
|
|
||||||
.get(scope.type_values.get(n).unwrap())
|
|
||||||
.unwrap()
|
|
||||||
{
|
|
||||||
// Struct also is allocated at initialization
|
|
||||||
TypeDefinitionKind::Struct(_) => StackValueKind::Mutable(value),
|
|
||||||
},
|
|
||||||
_ => StackValueKind::Mutable({
|
|
||||||
let alloca = scope
|
|
||||||
.block
|
|
||||||
.build(Instr::Alloca(
|
|
||||||
name.clone(),
|
|
||||||
ty.get_type(scope.type_values, scope.types),
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
scope.block.build(Instr::Store(alloca, value)).unwrap();
|
|
||||||
alloca
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ty.get_type(scope.type_values, scope.types),
|
ty.get_type(scope.type_values, scope.types),
|
||||||
),
|
))
|
||||||
);
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
|
let store = scope
|
||||||
|
.block
|
||||||
|
.build(Instr::Store(alloca, value))
|
||||||
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
|
let stack_value = match mutable {
|
||||||
|
true => StackValueKind::Mutable(alloca),
|
||||||
|
false => StackValueKind::Immutable(alloca),
|
||||||
|
};
|
||||||
|
|
||||||
|
scope
|
||||||
|
.stack_values
|
||||||
|
.insert(name.clone(), StackValue(stack_value, ty.clone()));
|
||||||
|
if let Some(debug) = &scope.debug {
|
||||||
|
match stack_value {
|
||||||
|
StackValueKind::Immutable(_) => {}
|
||||||
|
StackValueKind::Mutable(_) => {
|
||||||
|
let location = self.1.into_debug(scope.tokens).unwrap();
|
||||||
|
let var = debug.info.metadata(
|
||||||
|
&debug.scope,
|
||||||
|
DebugMetadata::LocalVar(DebugLocalVariable {
|
||||||
|
name: name.clone(),
|
||||||
|
location,
|
||||||
|
ty: scope.debug_const_tys.get(&TypeKind::U32).unwrap().clone(),
|
||||||
|
always_preserve: true,
|
||||||
|
alignment: 32,
|
||||||
|
flags: DwarfFlags,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
store.add_record(
|
||||||
|
&mut scope.block,
|
||||||
|
InstructionDebugRecordData {
|
||||||
|
variable: var,
|
||||||
|
location,
|
||||||
|
kind: DebugRecordKind::Declare(value),
|
||||||
|
scope: debug.scope,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
StackValueKind::Any(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
mir::StmtKind::Set(lhs, rhs) => {
|
mir::StmtKind::Set(lhs, rhs) => {
|
||||||
@ -442,7 +484,8 @@ impl mir::Statement {
|
|||||||
scope
|
scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Store(lhs_value, rhs_value))
|
.build(Instr::Store(lhs_value, rhs_value))
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
mir::StmtKind::Import(_) => todo!(),
|
mir::StmtKind::Import(_) => todo!(),
|
||||||
@ -474,19 +517,15 @@ impl mir::Expression {
|
|||||||
.stack_values
|
.stack_values
|
||||||
.get(&varref.1)
|
.get(&varref.1)
|
||||||
.expect("Variable reference not found?!");
|
.expect("Variable reference not found?!");
|
||||||
|
dbg!(varref);
|
||||||
Some(match v.0 {
|
Some(match v.0 {
|
||||||
StackValueKind::Immutable(val) => val.clone(),
|
StackValueKind::Immutable(val) | StackValueKind::Mutable(val) => scope
|
||||||
StackValueKind::Mutable(val) => {
|
.block
|
||||||
if state.should_load {
|
.build(Instr::Load(
|
||||||
match v.1 {
|
val,
|
||||||
// TODO probably wrong ..?
|
v.1.get_type(scope.type_values, scope.types),
|
||||||
Type::Ptr(_) => val,
|
))
|
||||||
_ => scope.block.build(Instr::Load(val, v.1.clone())).unwrap(),
|
.unwrap(),
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => panic!("Found an unknown-mutable variable!"),
|
_ => panic!("Found an unknown-mutable variable!"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -567,7 +606,8 @@ impl mir::Expression {
|
|||||||
let mut ptr = scope
|
let mut ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetElemPtr(array, vec![idx]))
|
.build(Instr::GetElemPtr(array, vec![idx]))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
if state.should_load {
|
if state.should_load {
|
||||||
ptr = scope
|
ptr = scope
|
||||||
@ -576,7 +616,8 @@ impl mir::Expression {
|
|||||||
ptr,
|
ptr,
|
||||||
val_t.get_type(scope.type_values, scope.types),
|
val_t.get_type(scope.type_values, scope.types),
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ptr)
|
Some(ptr)
|
||||||
@ -598,7 +639,8 @@ impl mir::Expression {
|
|||||||
instr_t.get_type(scope.type_values, scope.types),
|
instr_t.get_type(scope.type_values, scope.types),
|
||||||
instr_list.len() as u32,
|
instr_list.len() as u32,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
for (index, instr) in instr_list.iter().enumerate() {
|
for (index, instr) in instr_list.iter().enumerate() {
|
||||||
let index_expr = scope
|
let index_expr = scope
|
||||||
@ -608,8 +650,13 @@ impl mir::Expression {
|
|||||||
let ptr = scope
|
let ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetElemPtr(array, vec![index_expr]))
|
.build(Instr::GetElemPtr(array, vec![index_expr]))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
scope.block.build(Instr::Store(ptr, *instr)).unwrap();
|
.maybe_location(&mut scope.block, location);
|
||||||
|
scope
|
||||||
|
.block
|
||||||
|
.build(Instr::Store(ptr, *instr))
|
||||||
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(array)
|
Some(array)
|
||||||
@ -629,12 +676,11 @@ impl mir::Expression {
|
|||||||
let TypeDefinitionKind::Struct(struct_ty) = scope.get_typedef(&name).unwrap();
|
let TypeDefinitionKind::Struct(struct_ty) = scope.get_typedef(&name).unwrap();
|
||||||
let idx = struct_ty.find_index(field).unwrap();
|
let idx = struct_ty.find_index(field).unwrap();
|
||||||
|
|
||||||
dbg!(&scope.context);
|
|
||||||
dbg!(&struct_val);
|
|
||||||
let mut value = scope
|
let mut value = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetStructElemPtr(struct_val, idx as u32))
|
.build(Instr::GetStructElemPtr(struct_val, idx as u32))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
if state.should_load {
|
if state.should_load {
|
||||||
value = scope
|
value = scope
|
||||||
@ -655,15 +701,21 @@ impl mir::Expression {
|
|||||||
name.clone(),
|
name.clone(),
|
||||||
Type::CustomType(*scope.type_values.get(name)?),
|
Type::CustomType(*scope.type_values.get(name)?),
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
|
|
||||||
for (i, (_, exp)) in items.iter().enumerate() {
|
for (i, (_, exp)) in items.iter().enumerate() {
|
||||||
let elem_ptr = scope
|
let elem_ptr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::GetStructElemPtr(struct_ptr, i as u32))
|
.build(Instr::GetStructElemPtr(struct_ptr, i as u32))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
if let Some(val) = exp.codegen(scope, state) {
|
if let Some(val) = exp.codegen(scope, state) {
|
||||||
scope.block.build(Instr::Store(elem_ptr, val)).unwrap();
|
scope
|
||||||
|
.block
|
||||||
|
.build(Instr::Store(elem_ptr, val))
|
||||||
|
.unwrap()
|
||||||
|
.maybe_location(&mut scope.block, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user