Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encode complex types in section mangling #1199

Merged
merged 6 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ source_filename = "app/file1.st"

%mainProg = type {}

@mainProg_instance = external global %mainProg, section "var-mainProg_instance:v", !dbg !0
@mainProg_instance = external global %mainProg, section "var-mainProg_instance:r0", !dbg !0

define i16 @main() section "fn-main:i16" !dbg !10 {
entry:
Expand Down Expand Up @@ -54,7 +54,7 @@ source_filename = "lib/file2.st"

%mainProg = type {}

@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:v", !dbg !0
@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:r0", !dbg !0

define void @mainProg(%mainProg* %0) section "fn-mainProg:v" !dbg !10 {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ source_filename = "file1.st"

%mainProg = type {}

@mainProg_instance = external global %mainProg, section "var-mainProg_instance:v", !dbg !0
@mainProg_instance = external global %mainProg, section "var-mainProg_instance:r0", !dbg !0

define i16 @main() section "fn-main:i16" !dbg !10 {
entry:
Expand Down Expand Up @@ -54,7 +54,7 @@ source_filename = "file2.st"

%mainProg = type {}

@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:v", !dbg !0
@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:r0", !dbg !0

define void @mainProg(%mainProg* %0) section "fn-mainProg:v" !dbg !10 {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ source_filename = "external_file1.st"

%mainProg = type {}

@mainProg_instance = external global %mainProg, section "var-mainProg_instance:v"
@mainProg_instance = external global %mainProg, section "var-mainProg_instance:r0"

define i16 @main() section "fn-main:i16" {
entry:
Expand All @@ -25,7 +25,7 @@ source_filename = "external_file2.st"

%mainProg = type {}

@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:v"
@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:r0"

define void @mainProg(%mainProg* %0) section "fn-mainProg:v" {
entry:
Expand Down
34 changes: 16 additions & 18 deletions compiler/section_mangler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ pub enum Type {
semantic_size: Option<u32>,
},
/// Encoded as `f<size>`
Float { size: u32 },
Float {
size: u32,
},
/// Encoded as `s<encoding><size>`
String {
size: usize, // FIXME: Is that okay? will all the constant expressions be folded at that point? Can we have TypeSize::Undetermined still?
Expand All @@ -172,23 +174,12 @@ pub enum Type {
// TODO: Is changing the `auto_deref` mode an ABI break?
// auto_deref: bool,
},

// --- UNIMPLEMENTED

// FIXME: Do we need any info here? How are structs codegened?
Struct {
// name: TypeId,
// members: Vec<VariableIndexEntry>,
// source: StructSource,
members: Vec<Type>,
},

// FIXME: Same here
Enum {
// name: TypeId,
// referenced_type: TypeId,
// // TODO: Would it make sense to store `VariableIndexEntry`s similar to how the `Struct` variant does?
// // This would allow us to pattern match in the index `find_member` method
// elements: Vec<String>,
referenced_type: Box<Type>,
elements: usize,
},
Array {
inner: Box<Type>,
Expand Down Expand Up @@ -226,10 +217,17 @@ impl fmt::Display for Type {
Type::Float { size } => write!(f, "f{size}"),
Type::String { size, encoding } => write!(f, "s{encoding}{size}",),
Type::Pointer { inner } => write!(f, "p{}", inner),
Type::Struct { members } => {
write!(
f,
"r{}{}",
members.len(),
members.iter().fold(String::new(), |acc, m| format!("{acc}{m}"))
)
}
Type::Enum { referenced_type, elements } => write!(f, "e{elements}{referenced_type}"),
Type::Array { inner } => write!(f, "a{inner}"),
// -- Unimplemented
Type::Struct {} => todo!(),
Type::Enum {} => todo!(),
Type::Array { .. } => todo!(),
Type::SubRange {} => todo!(),
Type::Alias {} => todo!(),
Type::Generic {} => todo!(),
Expand Down
34 changes: 31 additions & 3 deletions src/codegen/generators/section_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use plc_diagnostics::diagnostics::Diagnostic;
use section_mangler::{StringEncoding as SectionStringEncoding, Type};

pub fn mangle_type(index: &Index, ty: &typesystem::DataType) -> Result<section_mangler::Type, Diagnostic> {
let access_inner = |ty_name| mangle_type(index, index.get_effective_type_by_name(ty_name)?);

// TODO: This is a bit ugly because we keep dereferencing references to Copy types like
// bool, u32, etc, because `DataTypeInformation::Pointer` keeps a `String` which is not
// Copy. the alternative is for section_mangle::Type to keep references everywhere, and
Expand All @@ -23,10 +25,36 @@ pub fn mangle_type(index: &Index, ty: &typesystem::DataType) -> Result<section_m

Type::String { size: *size as usize, encoding }
}
DataTypeInformation::Pointer { inner_type_name, .. } => Type::Pointer {
inner: Box::new(mangle_type(index, index.get_effective_type_by_name(inner_type_name)?)?),
DataTypeInformation::Pointer { inner_type_name, .. } => {
Type::Pointer { inner: Box::new(access_inner(inner_type_name)?) }
}
DataTypeInformation::Enum { referenced_type, variants, .. } => {
Type::Enum { referenced_type: Box::new(access_inner(referenced_type)?), elements: variants.len() }
}
DataTypeInformation::Struct { members, .. } => Type::Struct {
members: members.iter().try_fold(Vec::new(), |mut acc, m| -> Result<Vec<Type>, Diagnostic> {
let inner = access_inner(m.get_type_name())?;

acc.push(inner);

Ok(acc)
})?,
},
// FIXME: For now, encode all unknown types as "void" since this is not required for
DataTypeInformation::Array { inner_type_name, .. } => {
Type::Array { inner: Box::new(access_inner(inner_type_name)?) }
}
// FIXME: Is that correct?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the range is only relevant at compile time AFAIK.
Technically the norm allows for different runtime behaviour if a value is out of range, but this would still not affect the generated type, only some functions that the user needs to have.
The subrange has an implicit method that gives the upper and lower bounds but this is resolved on compile time as well since the range is known.

// For code generation, the actual range does not matter - it is not a breaking change
// if a variable's range changes, at least not for codegen, since the underlying type will stay
// the same. Therefore, only encode it as its underlying type.
DataTypeInformation::SubRange { referenced_type, .. }
// Similarly, we do not care about the alias - only the type which is being codegen'd
| DataTypeInformation::Alias { referenced_type, .. } => access_inner(referenced_type)?,
DataTypeInformation::Generic { .. } => {
// FIXME: Is that correct?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, generics and aliases will be resolved to the correct types during the resolve phase.

unreachable!("generic types should not exist at codegen")
}
// FIXME: For now, encode all unknown types as "void" since this is not required for
// execution. Not doing so (and doing an `unreachable!()` for example) obviously causes
// failures, because complex types are already implemented in the compiler.
_ => Type::Void,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ source_filename = "main"
%myPrg = type {}
%myFb = type {}

@myPrg_instance = external global %myPrg, section "var-myPrg_instance:v", !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, section "var-__myFb__init:v", !dbg !5
@myPrg_instance = external global %myPrg, section "var-myPrg_instance:r0", !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, section "var-__myFb__init:r0", !dbg !5

declare i32 @myFunc() section "fn-myFunc:i32"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ source_filename = "main"
%myPrg = type {}
%myFb = type {}

@myPrg_instance = global %myPrg zeroinitializer, section "var-myPrg_instance:v", !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, section "var-__myFb__init:v", !dbg !5
@myPrg_instance = global %myPrg zeroinitializer, section "var-myPrg_instance:r0", !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, section "var-__myFb__init:r0", !dbg !5

define i32 @myFunc() section "fn-myFunc:i32" !dbg !12 {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ source_filename = "main"
%myProg = type { i32 }
%fb = type { i32 }

@myProg_instance = global %myProg zeroinitializer, section "var-myProg_instance:v", !dbg !0
@__fb__init = unnamed_addr constant %fb zeroinitializer, section "var-__fb__init:v", !dbg !7
@myProg_instance = global %myProg zeroinitializer, section "var-myProg_instance:r1i32", !dbg !0
@__fb__init = unnamed_addr constant %fb zeroinitializer, section "var-__fb__init:r1i32", !dbg !7

define void @myProg(%myProg* %0) section "fn-myProg:v[i32]" !dbg !16 {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ source_filename = "main"
%myPrg = type {}
%myFb = type {}

@myPrg_instance = global %myPrg zeroinitializer, section "var-myPrg_instance:v", !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, section "var-__myFb__init:v", !dbg !9
@myPrg_instance = global %myPrg zeroinitializer, section "var-myPrg_instance:r3i32i32i32", !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, section "var-__myFb__init:r3i32i32i32", !dbg !9

define i32 @myFunc() section "fn-myFunc:i32" !dbg !20 {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ source_filename = "main"

%commands = type { i8, i8 }

@__commands__init = unnamed_addr constant %commands { i8 1, i8 0 }, section "var-__commands__init:v"
@__commands__init = unnamed_addr constant %commands { i8 1, i8 0 }, section "var-__commands__init:r2u8u8"

define i32 @main() section "fn-main:i32" {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ source_filename = "main"

%commands = type { i8, i8 }

@__commands__init = unnamed_addr constant %commands zeroinitializer, section "var-__commands__init:v"
@__commands__init = unnamed_addr constant %commands zeroinitializer, section "var-__commands__init:r2u8u8"
@__main.myStr1__init = unnamed_addr constant [81 x i8] zeroinitializer

define i32 @main() section "fn-main:i32" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ source_filename = "main"
%MyFB = type { i16 }
%prg = type { %MyFB }

@x = global %MyFB { i16 77 }, section "var-x:v"
@__MyFB__init = unnamed_addr constant %MyFB { i16 77 }, section "var-__MyFB__init:v"
@prg_instance = global %prg { %MyFB { i16 77 } }, section "var-prg_instance:v"
@x = global %MyFB { i16 77 }, section "var-x:r1i16"
@__MyFB__init = unnamed_addr constant %MyFB { i16 77 }, section "var-__MyFB__init:r1i16"
@prg_instance = global %prg { %MyFB { i16 77 } }, section "var-prg_instance:r1r1i16"

define void @MyFB(%MyFB* %0) section "fn-MyFB:v" {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ expression: result
; ModuleID = 'main'
source_filename = "main"

@a = global [2 x i8] zeroinitializer, section "var-a:v"
@a = global [2 x i8] zeroinitializer, section "var-a:au8"
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ source_filename = "main"
%fb = type { i16 }
%main = type { %fb }

@__fb__init = unnamed_addr constant %fb { i16 9 }, section "var-__fb__init:v"
@main_instance = global %main { %fb { i16 9 } }, section "var-main_instance:v"
@__fb__init = unnamed_addr constant %fb { i16 9 }, section "var-__fb__init:r1i16"
@main_instance = global %main { %fb { i16 9 } }, section "var-main_instance:r1r1i16"

define void @fb(%fb* %0) section "fn-fb:v" {
entry:
%a = getelementptr inbounds %fb, %fb* %0, i32 0, i32 0
ret void
}

define i32 @func(%fb* %0) section "fn-func:i32[v]" {
define i32 @func(%fb* %0) section "fn-func:i32[r1i16]" {
entry:
%func = alloca i32, align 4
%in = alloca %fb, align 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ expression: function
source_filename = "main"

@x = global i32 10, section "var-x:i32"
@__foo_position.x = unnamed_addr constant i32 1, section "var-x:v"
@__bar_position.x = unnamed_addr constant i32 3, section "var-x:v"
@__foo_position.y = unnamed_addr constant i32 2, section "var-y:v"
@__bar_position.y = unnamed_addr constant i32 4, section "var-y:v"
@__foo_position.x = unnamed_addr constant i32 1, section "var-x:e2i32"
@__bar_position.x = unnamed_addr constant i32 3, section "var-x:e2i32"
@__foo_position.y = unnamed_addr constant i32 2, section "var-y:e2i32"
@__bar_position.y = unnamed_addr constant i32 4, section "var-y:e2i32"

define i32 @foo() section "fn-foo:i32" {
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ source_filename = "main"
%fb = type {}
%main = type { %fb }

@__fb__init = unnamed_addr constant %fb zeroinitializer, section "var-__fb__init:v"
@main_instance = global %main zeroinitializer, section "var-main_instance:v"
@__fb__init = unnamed_addr constant %fb zeroinitializer, section "var-__fb__init:r0"
@main_instance = global %main zeroinitializer, section "var-main_instance:r1r0"

define void @fb(%fb* %0) section "fn-fb:v" {
entry:
ret void
}

define i32 @func(%fb* %0) section "fn-func:i32[v]" {
define i32 @func(%fb* %0) section "fn-func:i32[r0]" {
entry:
%func = alloca i32, align 4
%in = alloca %fb, align 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ source_filename = "main"

%MyStruct = type { i32, i16 }

@__MyStruct__init = unnamed_addr constant %MyStruct zeroinitializer, section "var-__MyStruct__init:v"
@__MyStruct__init = unnamed_addr constant %MyStruct zeroinitializer, section "var-__MyStruct__init:r2i32i16"

define i16 @foo_int() section "fn-foo_int:i16" {
entry:
Expand All @@ -27,7 +27,7 @@ entry:
ret void
}

define void @foo_arr([10 x float]* %0) section "fn-foo_arr:v" {
define void @foo_arr([10 x float]* %0) section "fn-foo_arr:af32" {
entry:
%foo_arr = alloca [10 x float]*, align 8
store [10 x float]* %0, [10 x float]** %foo_arr, align 8
Expand All @@ -37,7 +37,7 @@ entry:
ret void
}

define void @foo_struct(%MyStruct* %0) section "fn-foo_struct:v" {
define void @foo_struct(%MyStruct* %0) section "fn-foo_struct:r2i32i16" {
entry:
%foo_struct = alloca %MyStruct*, align 8
store %MyStruct* %0, %MyStruct** %foo_struct, align 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ source_filename = "main"

%main = type { [4 x i32], [4 x i32] }

@main_instance = global %main zeroinitializer, section "var-main_instance:v"
@__myArray__init = unnamed_addr constant [4 x i32] [i32 1, i32 2, i32 3, i32 4], section "var-__myArray__init:v"
@main_instance = global %main zeroinitializer, section "var-main_instance:r2ai32ai32"
@__myArray__init = unnamed_addr constant [4 x i32] [i32 1, i32 2, i32 3, i32 4], section "var-__myArray__init:ai32"

define void @target([4 x i32]* %0) section "fn-target:v" {
define void @target([4 x i32]* %0) section "fn-target:ai32" {
entry:
%target = alloca [4 x i32]*, align 8
store [4 x i32]* %0, [4 x i32]** %target, align 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ source_filename = "main"
%MyStrct = type { i32, i32, i32 }

@__MyStr__init = unnamed_addr constant [11 x i8] c"init\00\00\00\00\00\00\00", section "var-__MyStr__init:s8u11"
@__MyArr__init = unnamed_addr constant [10 x float] [float 0.000000e+00, float 0x3FF19999A0000000, float 0x40019999A0000000, float 0x400A666660000000, float 0x40119999A0000000, float 5.500000e+00, float 0x401A666660000000, float 0x401ECCCCC0000000, float 0x40219999A0000000, float 0x4023CCCCC0000000], section "var-__MyArr__init:v"
@__MyStrct__init = unnamed_addr constant %MyStrct { i32 1, i32 2, i32 3 }, section "var-__MyStrct__init:v"
@__MyArr__init = unnamed_addr constant [10 x float] [float 0.000000e+00, float 0x3FF19999A0000000, float 0x40019999A0000000, float 0x400A666660000000, float 0x40119999A0000000, float 5.500000e+00, float 0x401A666660000000, float 0x401ECCCCC0000000, float 0x40219999A0000000, float 0x4023CCCCC0000000], section "var-__MyArr__init:af32"
@__MyStrct__init = unnamed_addr constant %MyStrct { i32 1, i32 2, i32 3 }, section "var-__MyStrct__init:r3i32i32i32"

define i16 @foo_int() section "fn-foo_int:v" {
define i16 @foo_int() section "fn-foo_int:i16" {
entry:
%foo_int = alloca i16, align 2
store i16 7, i16* %foo_int, align 2
Expand All @@ -29,7 +29,7 @@ entry:
ret void
}

define void @foo_arr([10 x float]* %0) section "fn-foo_arr:v" {
define void @foo_arr([10 x float]* %0) section "fn-foo_arr:af32" {
entry:
%foo_arr = alloca [10 x float]*, align 8
store [10 x float]* %0, [10 x float]** %foo_arr, align 8
Expand All @@ -39,7 +39,7 @@ entry:
ret void
}

define void @foo_strct(%MyStrct* %0) section "fn-foo_strct:v" {
define void @foo_strct(%MyStrct* %0) section "fn-foo_strct:r3i32i32i32" {
entry:
%foo_strct = alloca %MyStrct*, align 8
store %MyStrct* %0, %MyStrct** %foo_strct, align 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ source_filename = "main"

%MyStrct = type { i32, i32, i32 }

@__MyStrct__init = unnamed_addr constant %MyStrct zeroinitializer, section "var-__MyStrct__init:v"
@__MyStrct__init = unnamed_addr constant %MyStrct zeroinitializer, section "var-__MyStrct__init:r3i32i32i32"

define i16 @foo_int() section "fn-foo_int:v" {
define i16 @foo_int() section "fn-foo_int:i16" {
entry:
%foo_int = alloca i16, align 2
store i16 0, i16* %foo_int, align 2
Expand All @@ -27,7 +27,7 @@ entry:
ret void
}

define void @foo_arr([10 x float]* %0) section "fn-foo_arr:v" {
define void @foo_arr([10 x float]* %0) section "fn-foo_arr:af32" {
entry:
%foo_arr = alloca [10 x float]*, align 8
store [10 x float]* %0, [10 x float]** %foo_arr, align 8
Expand All @@ -37,7 +37,7 @@ entry:
ret void
}

define void @foo_strct(%MyStrct* %0) section "fn-foo_strct:v" {
define void @foo_strct(%MyStrct* %0) section "fn-foo_strct:r3i32i32i32" {
entry:
%foo_strct = alloca %MyStrct*, align 8
store %MyStrct* %0, %MyStrct** %foo_strct, align 8
Expand Down
Loading
Loading