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

Move variables to ELF sections with mangled names #1198

Merged
merged 4 commits into from
Jun 12, 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 @@ -5,8 +5,8 @@ expression: "results.join(\"\\n\")"
; ModuleID = 'main.st'
source_filename = "main.st"

@x = external global i16
@y = external global i16
@x = external global i16, section "var-x:i16"
@y = external global i16, section "var-y:i16"

define i16 @main() section "fn-main:i16" {
entry:
Expand All @@ -24,7 +24,7 @@ declare i16 @external() section "fn-external:i16"
; ModuleID = 'external.st'
source_filename = "external.st"

@x = external global i16
@y = external global i16
@x = external global i16, section "var-x:i16"
@y = external global i16, section "var-y:i16"

declare i16 @external() section "fn-external:i16"
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, !dbg !0
@mainProg_instance = external global %mainProg, section "var-mainProg_instance:v", !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, !dbg !0
@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:v", !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, !dbg !0
@mainProg_instance = external global %mainProg, section "var-mainProg_instance:v", !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, !dbg !0
@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:v", !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
@mainProg_instance = external global %mainProg, section "var-mainProg_instance:v"

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
@mainProg_instance = global %mainProg zeroinitializer, section "var-mainProg_instance:v"

define void @mainProg(%mainProg* %0) section "fn-mainProg:v" {
entry:
Expand Down
6 changes: 4 additions & 2 deletions compiler/section_mangler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,11 @@ impl SectionMangler {
}
}

pub fn with_return_type(self, return_type: Option<Type>) -> SectionMangler {
pub fn with_return_type(self, return_type: Type) -> SectionMangler {
match self {
SectionMangler::Function(f) => SectionMangler::Function(FunctionMangler { return_type, ..f }),
SectionMangler::Function(f) => {
SectionMangler::Function(FunctionMangler { return_type: Some(return_type), ..f })
}
SectionMangler::Variable(_) => unreachable!("global variables do not have a return type."),
}
}
Expand Down
22 changes: 13 additions & 9 deletions src/codegen/generators/pou_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,33 +153,37 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> {
PouGenerator { llvm, index, annotations, llvm_index }
}

fn mangle_function(&self, implementation: &ImplementationIndexEntry) -> String {
fn mangle_function(&self, implementation: &ImplementationIndexEntry) -> Result<String, Diagnostic> {
let ctx = SectionMangler::function(implementation.get_call_name());

let params = self.index.get_declared_parameters(implementation.get_call_name());

let ctx = params.into_iter().fold(ctx, |ctx, param| {
// FIXME: Can we unwrap here?
let ctx = params.into_iter().try_fold(ctx, |ctx, param| -> Result<SectionMangler, Diagnostic> {
let ty = section_names::mangle_type(
self.index,
self.index.get_effective_type_by_name(&param.data_type_name).unwrap(),
);
self.index.get_effective_type_by_name(&param.data_type_name)?,
)?;
let parameter = match param.argument_type {
// TODO: We need to handle the `VariableType` enum as well - this describes the mode of
// argument passing, e.g. inout
index::ArgumentType::ByVal(_) => FunctionArgument::ByValue(ty),
index::ArgumentType::ByRef(_) => FunctionArgument::ByRef(ty),
};

ctx.with_parameter(parameter)
});
Ok(ctx.with_parameter(parameter))
})?;

let return_ty = self
.index
.find_return_type(implementation.get_type_name())
.map(|ty| section_names::mangle_type(self.index, ty));

ctx.with_return_type(return_ty).mangle()
let ctx = match return_ty {
Some(rty) => ctx.with_return_type(rty?),
None => ctx,
};

Ok(ctx.mangle())
}

/// generates an empty llvm function for the given implementation, including all parameters and the return type
Expand Down Expand Up @@ -281,7 +285,7 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> {

let curr_f = module.add_function(implementation.get_call_name(), function_declaration, None);

let section_name = self.mangle_function(implementation);
let section_name = self.mangle_function(implementation)?;
curr_f.set_section(Some(&section_name));

let pou_name = implementation.get_call_name();
Expand Down
11 changes: 7 additions & 4 deletions src/codegen/generators/section_names.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::index::Index;
use crate::typesystem::{self, DataTypeInformation, StringEncoding, TypeSize};
use plc_diagnostics::diagnostics::Diagnostic;
use section_mangler::{StringEncoding as SectionStringEncoding, Type};

pub fn mangle_type(index: &Index, ty: &typesystem::DataType) -> section_mangler::Type {
pub fn mangle_type(index: &Index, ty: &typesystem::DataType) -> Result<section_mangler::Type, Diagnostic> {
// 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
// have a lifetime generic parameter, e.g. `section_mangler::Type<'a>` - which is also
// annoying.
match ty.get_type_information() {
let mangled = match ty.get_type_information() {
DataTypeInformation::Void => Type::Void,
DataTypeInformation::Integer { signed, size, semantic_size, .. } => {
Type::Integer { signed: *signed, size: *size, semantic_size: *semantic_size }
Expand All @@ -23,11 +24,13 @@ pub fn mangle_type(index: &Index, ty: &typesystem::DataType) -> section_mangler:
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).unwrap())),
inner: Box::new(mangle_type(index, index.get_effective_type_by_name(inner_type_name)?)?),
},
// 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,
}
};

Ok(mangled)
}
12 changes: 12 additions & 0 deletions src/codegen/generators/variable_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use super::{
data_type_generator::get_default_for,
expression_generator::ExpressionCodeGenerator,
llvm::{GlobalValueExt, Llvm},
section_names,
};
use crate::codegen::debug::DebugBuilderEnum;
use crate::index::FxIndexSet;
Expand Down Expand Up @@ -170,6 +171,17 @@ impl<'ctx, 'b> VariableGenerator<'ctx, 'b> {
}
}

let section = section_mangler::SectionMangler::variable(
global_variable.get_name(),
section_names::mangle_type(
self.global_index,
self.global_index.get_effective_type_by_name(global_variable.get_type_name())?,
)?,
)
.mangle();

global_ir_variable.set_section(Some(&section));

Ok(global_ir_variable)
}
}
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, !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, !dbg !5
@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

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, !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, !dbg !5
@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

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, !dbg !0
@__fb__init = unnamed_addr constant %fb zeroinitializer, !dbg !7
@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

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 @@ -5,7 +5,7 @@ expression: result
; ModuleID = 'main'
source_filename = "main"

@a = global [65 x i8] zeroinitializer, !dbg !0
@a = global [65 x i8] zeroinitializer, section "var-a:s8u65", !dbg !0

!llvm.module.flags = !{!7, !8}
!llvm.dbg.cu = !{!9}
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, !dbg !0
@__myFb__init = unnamed_addr constant %myFb zeroinitializer, !dbg !9
@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

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 }
@__commands__init = unnamed_addr constant %commands { i8 1, i8 0 }, section "var-__commands__init:v"

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
@__commands__init = unnamed_addr constant %commands zeroinitializer, section "var-__commands__init:v"
@__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
@@ -1,28 +1,25 @@
---
source: src/codegen/tests/initialization_test/global_initializers.rs
assertion_line: 38
expression: result

---
; ModuleID = 'main'
source_filename = "main"

@c_INT = unnamed_addr constant i16 7
@c_3c = unnamed_addr constant i16 21
@c_BOOL = unnamed_addr constant i8 1
@c_not = unnamed_addr constant i8 0
@c_str = unnamed_addr constant [11 x i8] c"Hello\00\00\00\00\00\00"
@c_wstr = unnamed_addr constant [11 x i16] [i16 87, i16 111, i16 114, i16 108, i16 100, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0]
@c_real = unnamed_addr constant float 0x40091EB860000000
@c_lreal = unnamed_addr constant double 3.141500e+00
@x = unnamed_addr constant i16 7
@y = unnamed_addr constant i16 14
@z = unnamed_addr constant i16 32
@b = unnamed_addr constant i8 1
@nb = unnamed_addr constant i8 0
@bb = unnamed_addr constant i8 0
@str = unnamed_addr constant [11 x i8] c"Hello\00\00\00\00\00\00"
@wstr = unnamed_addr constant [11 x i16] [i16 87, i16 111, i16 114, i16 108, i16 100, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0]
@r = unnamed_addr constant float 0x3FF91EB860000000
@tau = unnamed_addr constant double 6.283000e+00

@c_INT = unnamed_addr constant i16 7, section "var-c_INT:i16"
@c_3c = unnamed_addr constant i16 21, section "var-c_3c:i16"
@c_BOOL = unnamed_addr constant i8 1, section "var-c_BOOL:u8"
@c_not = unnamed_addr constant i8 0, section "var-c_not:u8"
@c_str = unnamed_addr constant [11 x i8] c"Hello\00\00\00\00\00\00", section "var-c_str:s8u11"
@c_wstr = unnamed_addr constant [11 x i16] [i16 87, i16 111, i16 114, i16 108, i16 100, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0], section "var-c_wstr:s16u11"
@c_real = unnamed_addr constant float 0x40091EB860000000, section "var-c_real:f32"
@c_lreal = unnamed_addr constant double 3.141500e+00, section "var-c_lreal:f64"
@x = unnamed_addr constant i16 7, section "var-x:i16"
@y = unnamed_addr constant i16 14, section "var-y:i16"
@z = unnamed_addr constant i16 32, section "var-z:i16"
@b = unnamed_addr constant i8 1, section "var-b:u8"
@nb = unnamed_addr constant i8 0, section "var-nb:u8"
@bb = unnamed_addr constant i8 0, section "var-bb:u8"
@str = unnamed_addr constant [11 x i8] c"Hello\00\00\00\00\00\00", section "var-str:s8u11"
@wstr = unnamed_addr constant [11 x i16] [i16 87, i16 111, i16 114, i16 108, i16 100, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0], section "var-wstr:s16u11"
@r = unnamed_addr constant float 0x3FF91EB860000000, section "var-r:f32"
@tau = unnamed_addr constant double 6.283000e+00, section "var-tau:f64"
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
---
source: src/codegen/tests/initialization_test/global_initializers.rs
assertion_line: 53
expression: result

---
; ModuleID = 'main'
source_filename = "main"

@x = global i16 7
@y = global i8 1
@z = global float 0x400921CAC0000000

@x = global i16 7, section "var-x:i16"
@y = global i8 1, section "var-y:u8"
@z = global float 0x400921CAC0000000, section "var-z:f32"
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 }
@__MyFB__init = unnamed_addr constant %MyFB { i16 77 }
@prg_instance = global %prg { %MyFB { i16 77 } }
@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"

define void @MyFB(%MyFB* %0) section "fn-MyFB:v" {
entry:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
---
source: src/codegen/tests/initialization_test/global_initializers.rs
expression: result

---
; ModuleID = 'main'
source_filename = "main"

@a = global [2 x i8] zeroinitializer

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

@__fb__init = unnamed_addr constant %fb { i16 9 }
@main_instance = global %main { %fb { i16 9 } }
@__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"

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

@x = global i32 10
@__foo_position.x = unnamed_addr constant i32 1
@__bar_position.x = unnamed_addr constant i32 3
@__foo_position.y = unnamed_addr constant i32 2
@__bar_position.y = unnamed_addr constant i32 4
@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"

define i32 @foo() section "fn-foo:i32" {
entry:
Expand Down
Loading
Loading