mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
Use precision in mono/ir to determine which number to generate
This commit is contained in:
parent
48f964adf4
commit
791a0e9404
8 changed files with 183 additions and 61 deletions
|
@ -14,6 +14,26 @@ use roc_types::subs::{Content, FlatType, Subs, Variable};
|
|||
use std::collections::HashMap;
|
||||
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder};
|
||||
|
||||
// Function return type does not match operand type of return inst!
|
||||
// ret i64 %f1, !dbg !521
|
||||
// i32define private fastcc i32 @"#UserApp_main_1"() !dbg !517 {
|
||||
// entry:
|
||||
// %f = alloca i64
|
||||
// store i64 291, i64* %f, !dbg !521
|
||||
// %f1 = load i64, i64* %f, !dbg !521
|
||||
// ret i64 %f1, !dbg !521
|
||||
// }
|
||||
|
||||
// Function return type does not match operand type of return inst!
|
||||
// ret i32 %f1, !dbg !521
|
||||
// i64define private fastcc i64 @"#UserApp_main_1"() !dbg !517 {
|
||||
// entry:
|
||||
// %f = alloca i32
|
||||
// store i32 291, i32* %f, !dbg !521
|
||||
// %f1 = load i32, i32* %f, !dbg !521
|
||||
// ret i32 %f1, !dbg !521
|
||||
// }
|
||||
|
||||
pub const PRETTY_PRINT_IR_SYMBOLS: bool = false;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
|
@ -2245,19 +2265,37 @@ pub fn with_hole<'a>(
|
|||
let arena = env.arena;
|
||||
|
||||
match can_expr {
|
||||
Int(_, _, num) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(num)),
|
||||
Layout::Builtin(Builtin::Int64),
|
||||
hole,
|
||||
),
|
||||
Int(_, precision, num) => match num_argument_to_int_or_float(env.subs, precision) {
|
||||
IntOrFloat::SignedIntType(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(num)),
|
||||
Layout::Builtin(int_precision_to_builtin(precision)),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::UnsignedIntType(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(num)),
|
||||
Layout::Builtin(int_precision_to_builtin(precision)),
|
||||
hole,
|
||||
),
|
||||
_ => unreachable!("unexpected float precision for integer"),
|
||||
},
|
||||
|
||||
Float(_, _, num) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Float(num)),
|
||||
Layout::Builtin(Builtin::Float64),
|
||||
hole,
|
||||
),
|
||||
Float(_, precision, num) => match num_argument_to_int_or_float(env.subs, precision) {
|
||||
IntOrFloat::BinaryFloatType(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Float(num as f64)),
|
||||
Layout::Builtin(float_precision_to_builtin(precision)),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::DecimalFloatType(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Float(num as f64)),
|
||||
Layout::Builtin(float_precision_to_builtin(precision)),
|
||||
hole,
|
||||
),
|
||||
_ => unreachable!("unexpected float precision for integer"),
|
||||
},
|
||||
|
||||
Str(string) => Stmt::Let(
|
||||
assigned,
|
||||
|
@ -2267,16 +2305,28 @@ pub fn with_hole<'a>(
|
|||
),
|
||||
|
||||
Num(var, num) => match num_argument_to_int_or_float(env.subs, var) {
|
||||
IntOrFloat::IntType => Stmt::Let(
|
||||
IntOrFloat::SignedIntType(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(num)),
|
||||
Layout::Builtin(Builtin::Int64),
|
||||
Layout::Builtin(int_precision_to_builtin(precision)),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::FloatType => Stmt::Let(
|
||||
IntOrFloat::UnsignedIntType(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(num)),
|
||||
Layout::Builtin(int_precision_to_builtin(precision)),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::BinaryFloatType(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Float(num as f64)),
|
||||
Layout::Builtin(Builtin::Float64),
|
||||
Layout::Builtin(float_precision_to_builtin(precision)),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::DecimalFloatType(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Float(num as f64)),
|
||||
Layout::Builtin(float_precision_to_builtin(precision)),
|
||||
hole,
|
||||
),
|
||||
},
|
||||
|
@ -5478,8 +5528,10 @@ pub fn from_can_pattern<'a>(
|
|||
Pattern::UnsupportedPattern(*region)
|
||||
}
|
||||
NumLiteral(var, num) => match num_argument_to_int_or_float(env.subs, *var) {
|
||||
IntOrFloat::IntType => Pattern::IntLiteral(*num),
|
||||
IntOrFloat::FloatType => Pattern::FloatLiteral(*var, *num as u64),
|
||||
IntOrFloat::SignedIntType(_) => Pattern::IntLiteral(*num),
|
||||
IntOrFloat::UnsignedIntType(_) => Pattern::IntLiteral(*num),
|
||||
IntOrFloat::BinaryFloatType(_) => Pattern::FloatLiteral(*var, *num as u64),
|
||||
IntOrFloat::DecimalFloatType(_) => Pattern::FloatLiteral(*var, *num as u64),
|
||||
},
|
||||
|
||||
AppliedTag {
|
||||
|
@ -5854,29 +5906,100 @@ fn optimize_low_level(
|
|||
}
|
||||
}
|
||||
|
||||
pub enum IntPrecision {
|
||||
I128,
|
||||
I64,
|
||||
I32,
|
||||
I16,
|
||||
I8,
|
||||
}
|
||||
|
||||
pub enum FloatPrecision {
|
||||
F64,
|
||||
F32,
|
||||
}
|
||||
|
||||
pub enum IntOrFloat {
|
||||
IntType,
|
||||
FloatType,
|
||||
SignedIntType(IntPrecision),
|
||||
UnsignedIntType(IntPrecision),
|
||||
BinaryFloatType(FloatPrecision),
|
||||
DecimalFloatType(FloatPrecision),
|
||||
}
|
||||
|
||||
fn float_precision_to_builtin(precision: FloatPrecision) -> Builtin<'static> {
|
||||
use FloatPrecision::*;
|
||||
match precision {
|
||||
F64 => Builtin::Float64,
|
||||
F32 => Builtin::Float32,
|
||||
}
|
||||
}
|
||||
|
||||
fn int_precision_to_builtin(precision: IntPrecision) -> Builtin<'static> {
|
||||
use IntPrecision::*;
|
||||
match precision {
|
||||
I128 => Builtin::Int128,
|
||||
I64 => Builtin::Int64,
|
||||
I32 => Builtin::Int32,
|
||||
I16 => Builtin::Int16,
|
||||
I8 => Builtin::Int8,
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the `a` in `Num a`, determines whether it's an int or a float
|
||||
pub fn num_argument_to_int_or_float(subs: &Subs, var: Variable) -> IntOrFloat {
|
||||
match subs.get_without_compacting(var).content {
|
||||
Content::Alias(Symbol::NUM_INTEGER, args, _) => {
|
||||
debug_assert!(args.len() == 1);
|
||||
|
||||
// TODO: we probably need to match on the type of the arg
|
||||
IntOrFloat::IntType
|
||||
Content::FlexVar(_) => IntOrFloat::SignedIntType(IntPrecision::I64), // We default (Num *) to I64
|
||||
Content::Alias(Symbol::NUM_I128, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED128, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED128, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I128)
|
||||
}
|
||||
Content::FlexVar(_) => {
|
||||
// If this was still a (Num *), assume compiling it to an Int
|
||||
IntOrFloat::IntType
|
||||
Content::Alias(Symbol::NUM_INTEGER, _, _) // We default Integer to I64
|
||||
| Content::Alias(Symbol::NUM_I64, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED64, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED64, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I64)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_FLOATINGPOINT, args, _) => {
|
||||
debug_assert!(args.len() == 1);
|
||||
|
||||
// TODO: we probably need to match on the type of the arg
|
||||
IntOrFloat::FloatType
|
||||
// TODO: Add ors for aall NUM_SIGNED, NUM_BINARY (maybe NUM_AT_*)
|
||||
Content::Alias(Symbol::NUM_I32, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED32, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED32, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I32)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_I16, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED16, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED16, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I16)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_I8, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED8, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED8, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I8)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U128, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED128, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED128, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I128)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U64, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED64, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED64, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I64)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U32, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED32, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED32, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I32)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U16, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED16, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED16, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I16)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U8, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED8, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED8, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I8)
|
||||
}
|
||||
Content::Structure(FlatType::Apply(Symbol::ATTR_ATTR, attr_args)) => {
|
||||
debug_assert!(attr_args.len() == 2);
|
||||
|
@ -5884,10 +6007,16 @@ pub fn num_argument_to_int_or_float(subs: &Subs, var: Variable) -> IntOrFloat {
|
|||
// Recurse on the second argument
|
||||
num_argument_to_int_or_float(subs, attr_args[1])
|
||||
}
|
||||
Content::Alias(Symbol::NUM_F64, args, _) | Content::Alias(Symbol::NUM_F32, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
|
||||
IntOrFloat::FloatType
|
||||
Content::Alias(Symbol::NUM_FLOATINGPOINT, _, _) // We default FloatingPoint to F64
|
||||
| Content::Alias(Symbol::NUM_F64, _, _)
|
||||
| Content::Alias(Symbol::NUM_BINARY64, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_BINARY64, _, _) => {
|
||||
IntOrFloat::BinaryFloatType(FloatPrecision::F64)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_F32, _, _)
|
||||
| Content::Alias(Symbol::NUM_BINARY32, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_BINARY32, _, _) => {
|
||||
IntOrFloat::BinaryFloatType(FloatPrecision::F32)
|
||||
}
|
||||
other => {
|
||||
panic!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue