Skip to content

Commit

Permalink
Merge pull request #775 from candy-lang/stricter-lints-in-inkwell-bac…
Browse files Browse the repository at this point in the history
…kend

Stricter lints in Inkwell Backend
  • Loading branch information
jwbot authored Oct 26, 2023
2 parents d6a655d + 923ecfb commit b89bb23
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 35 deletions.
85 changes: 50 additions & 35 deletions compiler/backend_inkwell/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
#![feature(let_chains)]
#![warn(unused_crate_dependencies)]
#![warn(clippy::nursery, clippy::pedantic, unused_crate_dependencies)]
#![allow(
clippy::cognitive_complexity,
clippy::match_same_arms,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::module_name_repetitions,
clippy::similar_names,
clippy::too_many_lines
)]

use candy_frontend::{
builtin_functions::BuiltinFunction,
Expand Down Expand Up @@ -147,6 +156,7 @@ impl<'ctx> LlvmCandyModule<'ctx> {
}

impl<'ctx> CodeGen<'ctx> {
#[must_use]
pub fn new(context: &'ctx Context, module_name: &str, mir: Arc<Mir>) -> Self {
let module = context.create_module(module_name);
let builder = context.create_builder();
Expand Down Expand Up @@ -320,7 +330,7 @@ impl<'ctx> CodeGen<'ctx> {
function_ctx: &FunctionInfo<'ctx>,
) -> Option<impl BasicValue<'ctx>> {
let mut return_value = None;
for (id, expr) in mir.expressions.iter() {
for (id, expr) in &mir.expressions {
let expr_value = match expr {
Expression::Int(value) => {
// TODO: Use proper BigInts here
Expand All @@ -338,7 +348,7 @@ impl<'ctx> CodeGen<'ctx> {

let global = self.create_global(
&format!("num_{value}"),
id,
*id,
call.try_as_basic_value().unwrap_left(),
);

Expand All @@ -353,15 +363,15 @@ impl<'ctx> CodeGen<'ctx> {

let global = self.create_global(
&format!("text_{text}"),
id,
*id,
call.try_as_basic_value().unwrap_left(),
);

Some(global.as_basic_value_enum())
}
Expression::Tag { symbol, value } => {
let tag_value = match value {
Some(value) => self.get_value_with_id(function_ctx, value).unwrap(),
Some(value) => self.get_value_with_id(function_ctx, *value).unwrap(),
None => self
.candy_value_pointer_type
.const_null()
Expand All @@ -378,7 +388,7 @@ impl<'ctx> CodeGen<'ctx> {

let global = self.create_global(
&format!("tag_{symbol}"),
id,
*id,
call.try_as_basic_value().unwrap_left(),
);

Expand Down Expand Up @@ -411,7 +421,7 @@ impl<'ctx> CodeGen<'ctx> {

let global = self.create_global(
&format!("fun_candy_builtin_{}", builtin.as_ref()),
id,
*id,
call.try_as_basic_value().unwrap_left(),
);

Expand All @@ -426,7 +436,7 @@ impl<'ctx> CodeGen<'ctx> {
"",
);
let values = list.iter().map(|v| {
self.get_value_with_id(function_ctx, v)
self.get_value_with_id(function_ctx, *v)
.unwrap()
.into_pointer_value()
});
Expand Down Expand Up @@ -458,7 +468,7 @@ impl<'ctx> CodeGen<'ctx> {
.build_call(make_candy_list, &[list_array.into()], "");

let global =
self.create_global("", id, candy_list.try_as_basic_value().unwrap_left());
self.create_global("", *id, candy_list.try_as_basic_value().unwrap_left());

Some(global.as_basic_value_enum())
}
Expand All @@ -478,11 +488,11 @@ impl<'ctx> CodeGen<'ctx> {
);
for (idx, (key, value)) in s.iter().enumerate() {
let key = self
.get_value_with_id(function_ctx, key)
.get_value_with_id(function_ctx, *key)
.unwrap()
.into_pointer_value();
let value = self
.get_value_with_id(function_ctx, value)
.get_value_with_id(function_ctx, *value)
.unwrap()
.into_pointer_value();

Expand Down Expand Up @@ -543,7 +553,7 @@ impl<'ctx> CodeGen<'ctx> {
Some(struct_value.into_pointer_value().as_basic_value_enum())
}
Expression::Reference(ref_id) => {
let value = self.get_value_with_id(function_ctx, ref_id).unwrap();
let value = self.get_value_with_id(function_ctx, *ref_id).unwrap();

self.locals.insert(*id, value);
Some(value)
Expand All @@ -558,7 +568,7 @@ impl<'ctx> CodeGen<'ctx> {
.build_call(make_candy_text, &[string.into()], "");

let global =
self.create_global(&text, id, call.try_as_basic_value().unwrap_left());
self.create_global(&text, *id, call.try_as_basic_value().unwrap_left());

Some(global.as_basic_value_enum())
}
Expand Down Expand Up @@ -593,12 +603,17 @@ impl<'ctx> CodeGen<'ctx> {

let env_ptr = self.builder.build_malloc(env_struct_type, "").unwrap();

for (idx, cap_id) in captured_ids.iter().enumerate() {
let value = self.get_value_with_id(function_ctx, cap_id);
for (index, captured_id) in captured_ids.iter().enumerate() {
let value = self.get_value_with_id(function_ctx, *captured_id);

let member = self
.builder
.build_struct_gep(env_struct_type, env_ptr, idx as u32, "")
.build_struct_gep(
env_struct_type,
env_ptr,
index.try_into().unwrap(),
"",
)
.unwrap();
self.builder.build_store(member, value.unwrap());
}
Expand All @@ -617,10 +632,10 @@ impl<'ctx> CodeGen<'ctx> {
let function_info = FunctionInfo {
function_value: function,
captured_ids: captured_ids.clone(),
env_type: if !captured_ids.is_empty() {
Some(env_struct_type)
} else {
env_type: if captured_ids.is_empty() {
None
} else {
Some(env_struct_type)
},
};
self.functions.insert(*id, function_info.clone());
Expand All @@ -643,7 +658,7 @@ impl<'ctx> CodeGen<'ctx> {

let global = self.create_global(
&format!("fun_{name}"),
id,
*id,
call.try_as_basic_value().unwrap_left(),
);

Expand All @@ -664,7 +679,7 @@ impl<'ctx> CodeGen<'ctx> {
self.unrepresented_ids.insert(*responsible);
let mut args: Vec<_> = arguments
.iter()
.map(|arg| self.get_value_with_id(function_ctx, arg).unwrap().into())
.map(|arg| self.get_value_with_id(function_ctx, *arg).unwrap().into())
.collect();

if let Some(FunctionInfo {
Expand Down Expand Up @@ -698,7 +713,7 @@ impl<'ctx> CodeGen<'ctx> {
Some(call_value.as_basic_value_enum())
} else {
let function_value = self
.get_value_with_id(function_ctx, function)
.get_value_with_id(function_ctx, *function)
.unwrap_or_else(|| panic!("There is no function with ID {function}"));

let get_candy_fn_ptr = self
Expand Down Expand Up @@ -740,7 +755,7 @@ impl<'ctx> CodeGen<'ctx> {
Expression::Panic { reason, .. } => {
let panic_fn = self.module.get_function("candy_panic").unwrap();

let reason = self.get_value_with_id(function_ctx, reason).unwrap();
let reason = self.get_value_with_id(function_ctx, *reason).unwrap();

self.builder.build_call(panic_fn, &[reason.into()], "");

Expand Down Expand Up @@ -800,7 +815,7 @@ impl<'ctx> CodeGen<'ctx> {
fn create_global(
&mut self,
name: &str,
id: &Id,
id: Id,
value: impl BasicValue<'ctx>,
) -> GlobalValue<'ctx> {
let global = self
Expand All @@ -809,7 +824,7 @@ impl<'ctx> CodeGen<'ctx> {
self.builder.build_store(global.as_pointer_value(), value);

global.set_initializer(&self.candy_value_pointer_type.const_null());
assert!(self.globals.insert(*id, global).is_none());
assert!(self.globals.insert(id, global).is_none());
global
}

Expand All @@ -835,32 +850,32 @@ impl<'ctx> CodeGen<'ctx> {
fn get_value_with_id(
&self,
function_ctx: &FunctionInfo<'ctx>,
id: &Id,
id: Id,
) -> Option<BasicValueEnum<'ctx>> {
let mut v = self.globals.get(id).map(|a| {
let mut v = self.globals.get(&id).map(|it| {
self.builder
.build_load(self.candy_value_pointer_type, a.as_pointer_value(), "")
.build_load(self.candy_value_pointer_type, it.as_pointer_value(), "")
});
if v.is_none() && let Some(i) = function_ctx.captured_ids.iter().position(|i| i == id) {
if v.is_none() && let Some(index) = function_ctx.captured_ids.iter().position(|i| *i == id) {
let env_ptr = function_ctx.function_value.get_last_param().unwrap();

let env_value = self
.builder
.build_struct_gep(
function_ctx.env_type.unwrap(),
env_ptr.into_pointer_value(),
i as u32,
index.try_into().unwrap(),
"",
)
.unwrap();

v.replace(self.builder.build_load(self.candy_value_pointer_type, env_value, ""));
v = Some(self.builder.build_load(self.candy_value_pointer_type, env_value, ""));
}
if v.is_none() && let Some(value) = self.locals.get(id) {
v.replace(*value);
if v.is_none() && let Some(value) = self.locals.get(&id) {
v = Some(*value);
}
if self.unrepresented_ids.contains(id) {
v.replace(
if self.unrepresented_ids.contains(&id) {
v = Some(
self.candy_value_pointer_type
.const_null()
.as_basic_value_enum(),
Expand Down
1 change: 1 addition & 0 deletions compiler/cli/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub enum ExecutionTargetKind {
MainFunction,
}
impl ExecutionTargetKind {
#[must_use]
const fn resolve(self, module: Module) -> ExecutionTarget {
match self {
Self::Module => ExecutionTarget::Module(module),
Expand Down

1 comment on commit b89bb23

@jwbot
Copy link
Collaborator Author

@jwbot jwbot commented on b89bb23 Oct 26, 2023

Choose a reason for hiding this comment

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

Compiler

Benchmark suite Current: b89bb23 Previous: d6a655d Ratio
Time: Compiler/hello_world 23722881 ns/iter (± 838286) 25224884 ns/iter (± 1854066) 0.94
Time: Compiler/fibonacci 179682613 ns/iter (± 1608607) 211108741 ns/iter (± 6034413) 0.85
Time: VM Runtime/hello_world 54600 ns/iter (± 9566) 45450 ns/iter (± 15258) 1.20
Time: VM Runtime/fibonacci/15 272537661 ns/iter (± 1066050) 301077707 ns/iter (± 6852647) 0.91
Time: VM Runtime/PLB/binarytrees/6 1253537881 ns/iter (± 1865969) 1452710372 ns/iter (± 54560207) 0.86

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.