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

Commit

Permalink
Small improvements (#178)
Browse files Browse the repository at this point in the history
* Revert last 4 arc commits (#179)

* Revert "Basic arc classes (breaks Array, MemoryAddress, References) (#177)"

This reverts commit 6593940.

* Revert "Make string to be arc (#176)"

This reverts commit e3a2298.

* Revert "Make rational to be arc (#175)"

This reverts commit 8c52c17.

* Revert "Pass by ref for integer (#174)"

This reverts commit 584df80.

* Small improvements
  • Loading branch information
gavrilikhin-d authored May 19, 2024
1 parent 84e0102 commit 2fd4aed
Show file tree
Hide file tree
Showing 55 changed files with 5,153 additions and 2,092 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
### Current task
* [ ] Printable trait should take references
---
* [ ] migrate to pass-by-ref (branch `arc`)
* [ ] Prefer candidates with mutable references, when possible
* [ ] Fix problems with to_ir and loading references (especially globals). This causes issues in iterator
* [ ] Benchmark for linear algebra
Expand Down
22 changes: 16 additions & 6 deletions ppl/src/core.ppl
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,13 @@ fn String from <x: Bool> -> String:
//=================================
// Integer
//=================================
type IntegerImpl

@builtin
type Integer
type Integer:
impl: Reference<IntegerImpl>

@builtin
fn default <:Type<Integer>> => 0

@mangle_as("integer_eq_integer")
Expand Down Expand Up @@ -115,18 +119,21 @@ fn <x: Integer> % <y: Integer> -> Integer
@mangle_as("integer_as_string")
fn String from <:Integer> -> String

@mangle_as("clone_integer")
fn clone <:&Integer> -> Integer

@mangle_as("destroy_integer")
fn destroy <:&mut Integer>

@mangle_as("clone_integer")
fn clone <:&Integer> -> Integer
//---------------------------------

//=================================
// Rational
//=================================
type RationalImpl

@builtin
type Rational
type Rational:
impl: Reference<RationalImpl>

fn default <:Type<Rational>> => 0.0

Expand Down Expand Up @@ -167,8 +174,11 @@ fn clone <:&Rational> -> Rational
//=================================
// String
//=================================
type StringImpl

@builtin
type String
type String:
impl: Reference<StringImpl>

fn default <:Type<String>> => ""

Expand Down
10 changes: 9 additions & 1 deletion src/hir/declarations/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,15 @@ impl ClassData {
if let Some(builtin) = &self.builtin {
return builtin.size_in_bytes();
}
return POINTER_SIZE;

if self.is_opaque() {
return POINTER_SIZE;
}

self.members
.iter()
.map(|m| m.ty().size_in_bytes())
.sum::<usize>()
}
}

Expand Down
52 changes: 18 additions & 34 deletions src/ir/to_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,16 +247,24 @@ impl<'llvm, C: Context<'llvm>> ToIR<'llvm, C> for ClassData {
return context.types().f64().into();
}

if self.is_any_reference() {
if self.members.is_empty() {
return context.types().opaque(&self.basename).into();
}

let field_types = self
.members
.iter()
.filter_map(|m| m.ty().to_ir(context).try_into_basic_type().ok())
.collect::<Vec<_>>();
context.types().arc(&self.name(), &field_types).into()
if let Some(ty) = context.llvm().get_struct_type(&self.name()) {
return ty.into();
}

let ty = context.llvm().opaque_struct_type(&self.name());
ty.set_body(
self.members
.iter()
.filter_map(|m| m.ty().to_ir(context).try_into_basic_type().ok())
.collect::<Vec<_>>()
.as_slice(),
false,
);
ty.into()
}
}

Expand Down Expand Up @@ -559,30 +567,12 @@ impl<'llvm, 'm> ToIR<'llvm, FunctionContext<'llvm, 'm, '_>> for Constructor {
.try_into_basic_type()
.expect("non-basic type constructor");
let alloca = context.builder.build_alloca(ty, "").unwrap();

let ptr = context.builder.build_struct_gep(ty, alloca, 0, "").unwrap();
let data_ty = context
.types()
.arc_data(&self.ty.referenced_type.name())
.unwrap();
let arc = context
.builder
.build_call(
context.functions().create_arc(),
&[data_ty.size_of().unwrap().into()],
"",
)
.unwrap()
.try_as_basic_value()
.left()
.unwrap();
context.builder.build_store(ptr, arc).unwrap();
for init in self.initializers.iter().filter(|i| !i.value.ty().is_none()) {
let field = context
.builder
.build_struct_gep(
data_ty,
ptr,
ty,
alloca,
init.index as u32,
format!("{}.{}", self.ty.referenced_type.name(), init.member.name()).as_str(),
)
Expand Down Expand Up @@ -618,16 +608,10 @@ impl<'llvm, 'm> HIRExpressionLoweringWithoutLoad<'llvm, 'm> for MemberReference

let base = base.unwrap().into_pointer_value();
let ty = self.base.ty().to_ir(context).try_into_basic_type().unwrap();
let ptr = context
.builder
.build_struct_gep(ty, base, 0, "")
.unwrap()
.into();
let data_ty = context.types().arc_data(&self.base.ty().name()).unwrap();
Some(
context
.builder
.build_struct_gep(data_ty, ptr, self.index as u32, &self.member.name())
.build_struct_gep(ty, base, self.index as u32, &self.member.name())
.unwrap()
.into(),
)
Expand Down
22 changes: 6 additions & 16 deletions src/ir/types.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use inkwell::{
context::ContextRef,
types::{BasicTypeEnum, FloatType, IntType, PointerType, StructType, VoidType},
types::{FloatType, IntType, PointerType, StructType, VoidType},
AddressSpace,
};

Expand Down Expand Up @@ -71,26 +71,16 @@ impl<'llvm> Types<'llvm> {
}

/// Get wrapper around pointer to opaque impl
pub fn arc(&self, name: &str, field_types: &[BasicTypeEnum<'llvm>]) -> StructType<'llvm> {
fn with_impl(&self, name: &str) -> StructType<'llvm> {
if let Some(ty) = self.llvm.get_struct_type(name) {
return ty;
}

let data_ty = self.llvm.opaque_struct_type(&format!("{name}Impl"));
if !field_types.is_empty() {
data_ty.set_body(field_types, false);
}

let ty = self.llvm.opaque_struct_type(name);
ty.set_body(&[self.pointer().into()], false);
ty.set_body(&[self.opaque(&format!("{name}Impl")).into()], false);
ty
}

/// Get LLVM struct type for data of ARC type
pub fn arc_data(&self, name: &str) -> Option<StructType<'llvm>> {
self.llvm.get_struct_type(&format!("{name}Impl"))
}

/// LLVM IR for [`Class`](Type::Class) type
pub fn opaque(&self, name: &str) -> PointerType<'llvm> {
self.get_or_add_opaque_struct(name);
Expand All @@ -104,17 +94,17 @@ impl<'llvm> Types<'llvm> {

/// LLVM IR for [`Integer`](Type::Integer) type
pub fn integer(&self) -> StructType<'llvm> {
self.arc("Integer", &[])
self.with_impl("Integer")
}

/// LLVM IR for `Rational` type
pub fn rational(&self) -> StructType<'llvm> {
self.arc("Rational", &[])
self.with_impl("Rational")
}

/// LLVM IR for [`String`](Type::String) type
pub fn string(&self) -> StructType<'llvm> {
self.arc("String", &[])
self.with_impl("String")
}

/// LLVM IR for C string type
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/src/assert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::String;
/// ```
#[no_mangle]
pub extern "C" fn assert(condition: bool, message: &String) {
let message = message.as_ref();
let message = unsafe { message.data.as_ref().unwrap() };
if !condition {
println!("Assertion failed: {message}");
}
Expand Down
28 changes: 16 additions & 12 deletions src/runtime/src/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,40 @@ use std::ffi::c_char;

use rug::ops::Pow;

use crate::{decrement_strong_count, increment_strong_count, Rational, String};

use std::sync::Arc;
use crate::{Rational, String};

/// Big integer number.
/// Wrapper around pointer to [`rug::Integer`].
///
/// # PPL
/// ```no_run
/// type IntegerImpl
///
/// @builtin
/// type Integer
/// type Integer:
/// impl: Reference<IntegerImpl>
/// ```
#[repr(C)]
pub struct Integer(pub *const rug::Integer);
pub struct Integer {
pub data: *mut rug::Integer,
}

impl Clone for Integer {
fn clone(&self) -> Self {
increment_strong_count(self.0 as *const _);
Self(self.0)
self.as_ref().into()
}
}

impl Drop for Integer {
fn drop(&mut self) {
decrement_strong_count(self.0 as *const _);
let _ = unsafe { Box::from_raw(self.data) };
}
}

impl Integer {
/// Get the inner value
pub fn as_ref(&self) -> &rug::Integer {
unsafe { &*self.0 }
unsafe { &*self.data }
}
}

Expand All @@ -42,8 +44,10 @@ where
rug::Integer: From<T>,
{
fn from(x: T) -> Self {
let this = Arc::new(rug::Integer::from(x));
Self(Arc::into_raw(this))
let this = Box::new(rug::Integer::from(x));
Self {
data: Box::into_raw(this),
}
}
}

Expand Down Expand Up @@ -215,7 +219,7 @@ pub extern "C" fn integer_mod_integer(x: Integer, y: Integer) -> Integer {
/// ```
#[no_mangle]
pub extern "C" fn destroy_integer(x: &mut Integer) {
decrement_strong_count(x.0 as *const _);
let _ = unsafe { Box::from_raw(x.data) };
}

/// # PPL
Expand Down
18 changes: 0 additions & 18 deletions src/runtime/src/memory.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::sync::Arc;

use libc::{c_void, malloc, memcpy, size_t};

use crate::{integer_from_i64, integer_from_u64, Integer, String, Type};
Expand Down Expand Up @@ -108,19 +106,3 @@ pub extern "C" fn copy_bytes(n: &Integer, src: &MemoryAddress, dst: &MemoryAddre
let n = n.as_ref().to_usize().unwrap() as size_t;
unsafe { memcpy(dest, src, n) };
}

#[no_mangle]
pub extern "C" fn create_arc(bytes: usize) -> *const c_void {
let bytes = unsafe { Arc::<[u8]>::new_zeroed_slice(bytes).assume_init() };
Arc::into_raw(bytes) as *const c_void
}

#[no_mangle]
pub extern "C" fn increment_strong_count(ptr: *const c_void) {
unsafe { Arc::increment_strong_count(ptr) }
}

#[no_mangle]
pub extern "C" fn decrement_strong_count(ptr: *const c_void) {
unsafe { Arc::decrement_strong_count(ptr) }
}
23 changes: 13 additions & 10 deletions src/runtime/src/rational.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{ffi::c_char, sync::Arc};
use std::ffi::c_char;

use rug::{ops::Pow, Integer};

use crate::{decrement_strong_count, increment_strong_count, String};
use crate::String;

/// Rational number.
/// Wrapper around pointer to [`rug::Rational`].
Expand All @@ -16,25 +16,26 @@ use crate::{decrement_strong_count, increment_strong_count, String};
/// impl: Reference<RationalImpl>
/// ```
#[repr(C)]
pub struct Rational(pub *const rug::Rational);
pub struct Rational {
pub data: *mut rug::Rational,
}

impl Clone for Rational {
fn clone(&self) -> Self {
increment_strong_count(self.0 as *const _);
Self(self.0)
self.as_ref().into()
}
}

impl Drop for Rational {
fn drop(&mut self) {
decrement_strong_count(self.0 as *const _);
let _ = unsafe { Box::from_raw(self.data) };
}
}

impl Rational {
/// Get the inner value
pub fn as_ref(&self) -> &rug::Rational {
unsafe { &*self.0 }
unsafe { &*self.data }
}
}

Expand All @@ -43,8 +44,10 @@ where
rug::Rational: From<T>,
{
fn from(x: T) -> Self {
let this = Arc::new(rug::Rational::from(x));
Self(Arc::into_raw(this))
let this = Box::new(rug::Rational::from(x));
Self {
data: Box::into_raw(this),
}
}
}

Expand Down Expand Up @@ -156,7 +159,7 @@ pub extern "C" fn rational_less_rational(x: Rational, y: Rational) -> bool {
/// ```
#[no_mangle]
pub extern "C" fn destroy_rational(x: &mut Rational) {
decrement_strong_count(x.0 as *const _);
let _ = unsafe { Box::from_raw(x.data) };
}

/// # PPL
Expand Down
Loading

0 comments on commit 2fd4aed

Please sign in to comment.