Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
Fix monomorphizing predeclared (#149)
Browse files Browse the repository at this point in the history
  • Loading branch information
gavrilikhin-d authored May 2, 2024
1 parent 4497c40 commit e2b0344
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 5 deletions.
5 changes: 5 additions & 0 deletions src/hir/declarations/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ pub struct FunctionData {
#[drive(skip)]
pub tr: Option<Trait>,

/// Generic version of this function
#[drive(skip)]
pub generic_version: Option<Function>,

/// Mangled name to use instead of default
#[drive(skip)]
pub(crate) mangled_name: Option<String>,
Expand Down Expand Up @@ -516,6 +520,7 @@ impl FunctionBuilder {
FunctionData {
module: self.module,
tr: None,
generic_version: None,
keyword: self.keyword,
generic_types: self.generic_types,
name_parts: self.name_parts,
Expand Down
5 changes: 5 additions & 0 deletions src/hir/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ pub struct ModuleData {
#[drive(skip)]
pub functions: IndexMap<Format, IndexMap<Name, Function>>,

/// Monomorphized instances of functions
#[drive(skip)]
pub monomorphized_functions: Vec<Function>,

/// Statements in this module
pub statements: Vec<Statement>,
}
Expand All @@ -92,6 +96,7 @@ impl ModuleData {
variables: IndexMap::new(),
types: IndexMap::new(),
functions: IndexMap::new(),
monomorphized_functions: vec![],
statements: vec![],
}
}
Expand Down
30 changes: 29 additions & 1 deletion src/semantics/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,35 @@ impl Declare for ast::FunctionDeclaration {
body = vec![hir::Return::Implicit { value: expr }.into()];
}

declaration.write().unwrap().body = body;
declaration.write().unwrap().body = body.clone();

let instances: Vec<_> = context
.module()
.monomorphized_functions
.iter()
.filter(|f| {
let data = f.read().unwrap();
!data.is_definition() && data.generic_version == Some(declaration.clone())
})
.cloned()
.collect();

for f in instances {
f.write().unwrap().body = body.clone();

let mut context = GenericContext::for_fn(declaration.clone(), context);

f.read()
.unwrap()
.parameters()
.map(|p| p.ty())
.zip(declaration.read().unwrap().parameters().map(|p| p.ty()))
.for_each(|(a, b)| {
a.convertible_to(b).within(&mut context).unwrap();
});

f.write().unwrap().monomorphize(&mut context);
}

Ok(declaration)
}
Expand Down
2 changes: 0 additions & 2 deletions src/semantics/destructors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ fn with_destructors(
range: v.range(),
function: destructor,
generic: None,
// FIXME: create temporary variable,
// if it's complex expr
args: vec![v],
})
.into(),
Expand Down
7 changes: 5 additions & 2 deletions src/semantics/monomorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,13 @@ impl Monomorphize for Call {
let mut f = self.function.read().unwrap().clone();
f.monomorphize(&mut context);

// FIXME: Can't monomorphize while still didn't get all definitions
// We won't receive body update once we've monomorphized it
if *self.function.read().unwrap() != f {
f.generic_version = Some(self.function.clone());
self.function = Function::new(f);
context
.module_mut()
.monomorphized_functions
.push(self.function.clone());
}

debug!(target: "monomorphized-from", "{from}");
Expand Down
12 changes: 12 additions & 0 deletions src/tests/snapshots/ppl__tests__monomorphize_predeclared.hir.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
source: src/tests/mod.rs
expression: hir
---
fn call predeclared -> None:
predeclared 1


fn<T> predeclared <x: T> -> None:
println "called predeclared"

call predeclared
85 changes: 85 additions & 0 deletions src/tests/snapshots/ppl__tests__monomorphize_predeclared.ir.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
source: src/tests/mod.rs
expression: ir
---
; ModuleID = 'main'
source_filename = "src/main.ppl"

%"Type<String>" = type { %String, %Integer }
%String = type { ptr }
%Integer = type { ptr }

@"Type<String>" = private global %"Type<String>" zeroinitializer
@0 = private unnamed_addr constant [7 x i8] c"String\00", align 1
@1 = private unnamed_addr constant [19 x i8] c"called predeclared\00", align 1

define private void @initialize() !dbg !3 {
%1 = alloca %"Type<String>", align 8, !dbg !7
%"Type<String>.name" = getelementptr inbounds %"Type<String>", ptr %1, i32 0, i32 0, !dbg !7
%2 = call %String @string_from_c_string_and_length(ptr @0, i64 6), !dbg !8
store %String %2, ptr %"Type<String>.name", align 8, !dbg !8
%"Type<String>.size" = getelementptr inbounds %"Type<String>", ptr %1, i32 0, i32 1, !dbg !8
%3 = call %Integer @integer_from_i64(i64 8), !dbg !8
store %Integer %3, ptr %"Type<String>.size", align 8, !dbg !8
%4 = load %"Type<String>", ptr %1, align 8, !dbg !8
store %"Type<String>" %4, ptr @"Type<String>", align 8, !dbg !8
br label %return, !dbg !8

return: ; preds = %0
ret void
}

declare %String @string_from_c_string_and_length(ptr, i64)

declare %Integer @integer_from_i64(i64)

define void @main.execute() !dbg !9 {
call void @initialize(), !dbg !10
call void @"call predeclared"(), !dbg !11
br label %return, !dbg !11

return: ; preds = %0
ret void
}

define void @"call predeclared"() !dbg !12 {
%1 = call %Integer @integer_from_i64(i64 1), !dbg !13
call void @"predeclared <:Integer>"(%Integer %1), !dbg !13
br label %return, !dbg !13

return: ; preds = %0
ret void
}

define private void @"predeclared <:Integer>"(%Integer %0) !dbg !14 {
%x = alloca %Integer, align 8
store %Integer %0, ptr %x, align 8
%2 = call %String @string_from_c_string_and_length(ptr @1, i64 18), !dbg !15
call void @"println <:String>"(%String %2), !dbg !15
br label %return, !dbg !15

return: ; preds = %1
ret void
}

declare void @"println <:String>"(%String)

!llvm.module.flags = !{!0}
!llvm.dbg.cu = !{!1}

!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "ppl", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, sysroot: "/")
!2 = !DIFile(filename: "src/main.ppl", directory: ".")
!3 = distinct !DISubprogram(name: "initialize", linkageName: "initialize", scope: !2, file: !2, line: 6, type: !4, spFlags: DISPFlagDefinition, unit: !1)
!4 = !DISubroutineType(types: !5)
!5 = !{!6}
!6 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed)
!7 = !DILocation(line: 6, column: 16, scope: !3)
!8 = !DILocation(line: 0, scope: !3)
!9 = distinct !DISubprogram(name: "main.execute", linkageName: "main.execute", scope: !2, file: !2, type: !4, spFlags: DISPFlagDefinition, unit: !1)
!10 = !DILocation(line: 6, column: 16, scope: !9)
!11 = !DILocation(line: 6, scope: !9)
!12 = distinct !DISubprogram(name: "call predeclared", linkageName: "call predeclared", scope: !9, file: !2, type: !4, spFlags: DISPFlagDefinition, unit: !1)
!13 = !DILocation(line: 1, column: 13, scope: !12)
!14 = distinct !DISubprogram(name: "predeclared <:Integer>", linkageName: "predeclared <:Integer>", scope: !12, file: !2, line: 3, type: !4, spFlags: DISPFlagDefinition, unit: !1)
!15 = !DILocation(line: 4, column: 9, scope: !14)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: src/tests/mod.rs
expression: run_log
---
called predeclared

0 comments on commit e2b0344

Please sign in to comment.