Skip to content

Commit

Permalink
Merge branch 'master' into volsa/validate-fn-arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
ghaith authored Jun 12, 2024
2 parents 6533748 + 92e586a commit 87ba98f
Show file tree
Hide file tree
Showing 360 changed files with 2,162 additions and 949 deletions.
4 changes: 0 additions & 4 deletions compiler/plc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,6 @@ pub enum AstStatement {
DefaultValue(DefaultValue),
// Literals
Literal(AstLiteral),
CastStatement(CastStatement),
MultipliedStatement(MultipliedStatement),
// Expressions
ReferenceExpr(ReferenceExpr),
Expand Down Expand Up @@ -735,9 +734,6 @@ impl Debug for AstNode {
}
AstStatement::ContinueStatement(..) => f.debug_struct("ContinueStatement").finish(),
AstStatement::ExitStatement(..) => f.debug_struct("ExitStatement").finish(),
AstStatement::CastStatement(CastStatement { target, type_name }) => {
f.debug_struct("CastStatement").field("type_name", type_name).field("target", target).finish()
}
AstStatement::ReferenceExpr(ReferenceExpr { access, base }) => {
f.debug_struct("ReferenceExpr").field("kind", access).field("base", base).finish()
}
Expand Down
1 change: 1 addition & 0 deletions compiler/plc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pub mod control_statements;
pub mod literals;
mod pre_processor;
pub mod provider;
pub mod visitor;
714 changes: 714 additions & 0 deletions compiler/plc_ast/src/visitor.rs

Large diffs are not rendered by default.

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
14 changes: 0 additions & 14 deletions src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,20 +846,6 @@ fn generate_variable_length_array_bound_function<'ink>(
let offset = if is_lower { (value - 1) as u64 * 2 } else { (value - 1) as u64 * 2 + 1 };
llvm.i32_type().const_int(offset, false)
}
AstStatement::CastStatement(data) => {
let ExpressionValue::RValue(value) = generator.generate_expression_value(&data.target)? else {
unreachable!()
};

if !value.is_int_value() {
return Err(Diagnostic::codegen_error(
format!("Expected INT value, found {}", value.get_type()),
location,
));
};

value.into_int_value()
}
// e.g. LOWER_BOUND(arr, idx + 3)
_ => {
let expression_value = generator.generate_expression(params[1])?;
Expand Down
1 change: 0 additions & 1 deletion src/codegen/generators/expression_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1751,7 +1751,6 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
}
// if there is just one assignment, this may be an struct-initialization (TODO this is not very elegant :-/ )
AstStatement::Assignment { .. } => self.generate_literal_struct(literal_statement),
AstStatement::CastStatement(data) => self.generate_expression_value(&data.target),
_ => Err(cannot_generate_literal()),
}
}
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"
Loading

0 comments on commit 87ba98f

Please sign in to comment.