patch List.countGraphemes and List.isEmpty with the byval() attribute

This commit is contained in:
Folkert 2022-03-27 16:20:46 +02:00
parent 0f6e1ab2a2
commit 13ab2010f0
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C

View file

@ -9,14 +9,17 @@ use crate::llvm::refcounting::{
decrement_refcount_layout, increment_n_refcount_layout, increment_refcount_layout,
};
use inkwell::attributes::{Attribute, AttributeLoc};
use inkwell::types::{BasicType, BasicTypeEnum};
use inkwell::context::Context;
use inkwell::types::{AnyType, BasicType, BasicTypeEnum};
use inkwell::values::{BasicValue, BasicValueEnum, CallSiteValue, FunctionValue, InstructionValue};
use inkwell::AddressSpace;
use roc_builtins::bitcode;
use roc_error_macros::internal_error;
use roc_module::symbol::Symbol;
use roc_mono::layout::{LambdaSet, Layout, LayoutIds, UnionLayout};
use super::build::create_entry_block_alloca;
use super::convert::zig_str_type;
use std::convert::TryInto;
@ -98,6 +101,21 @@ pub fn call_void_bitcode_fn<'a, 'ctx, 'env>(
.unwrap_or_else(|| panic!("LLVM error: Tried to call void bitcode function, but got return value from bitcode function, {:?}", fn_name))
}
fn type_attribute<'ctx>(
context: &Context,
name: &str,
basic_type: BasicTypeEnum<'ctx>,
) -> inkwell::attributes::Attribute {
let kind_id = Attribute::get_named_enum_kind_id(name);
context.create_type_attribute(kind_id, basic_type.as_any_type_enum())
}
fn enum_attribute<'ctx>(context: &Context, name: &str) -> inkwell::attributes::Attribute {
let kind_id = Attribute::get_named_enum_kind_id(name);
debug_assert!(kind_id > 0);
context.create_enum_attribute(kind_id, 1)
}
fn call_bitcode_fn_help<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
args: &[BasicValueEnum<'ctx>],
@ -113,6 +131,34 @@ fn call_bitcode_fn_help<'a, 'ctx, 'env>(
let call = env.builder.build_call(fn_val, &arguments, "call_builtin");
match fn_name {
bitcode::STR_NUMBER_OF_BYTES | bitcode::STR_COUNT_GRAPEHEME_CLUSTERS => {
// hacks
let i = 0;
call.add_attribute(
AttributeLoc::Param(0),
type_attribute(env.context, "byval", zig_str_type(env).into()),
);
call.add_attribute(
AttributeLoc::Param(i as u32),
enum_attribute(env.context, "nonnull"),
);
call.add_attribute(
AttributeLoc::Param(i as u32),
enum_attribute(env.context, "nocapture"),
);
call.add_attribute(
AttributeLoc::Param(i as u32),
enum_attribute(env.context, "readonly"),
);
}
_ => {}
}
call.set_call_convention(fn_val.get_call_conventions());
call
}