Skip to content

Commit

Permalink
Merge pull request rust-lang#47 from cpdt/feature/45-vector-math-ops
Browse files Browse the repository at this point in the history
Support vector types in math ops, fixes rust-lang#45
  • Loading branch information
TheDan64 authored Jun 25, 2018
2 parents ce4519b + 8cbc981 commit 50e94ee
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 141 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ fn jit_compile_sum(
let y = function.get_nth_param(1)?.into_int_value();
let z = function.get_nth_param(2)?.into_int_value();

let sum = builder.build_int_add(&x, &y, "sum");
let sum = builder.build_int_add(&sum, &z, "sum");
let sum = builder.build_int_add(x, y, "sum");
let sum = builder.build_int_add(sum, z, "sum");

builder.build_return(Some(&sum));

Expand Down
4 changes: 2 additions & 2 deletions examples/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ fn jit_compile_sum(
let y = function.get_nth_param(1)?.into_int_value();
let z = function.get_nth_param(2)?.into_int_value();

let sum = builder.build_int_add(&x, &y, "sum");
let sum = builder.build_int_add(&sum, &z, "sum");
let sum = builder.build_int_add(x, y, "sum");
let sum = builder.build_int_add(sum, z, "sum");

builder.build_return(Some(&sum));

Expand Down
22 changes: 11 additions & 11 deletions examples/kaleidoscope/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -941,19 +941,19 @@ impl<'a> Compiler<'a> {
let rhs = self.compile_expr(right)?;

match op {
'+' => Ok(self.builder.build_float_add(&lhs, &rhs, "tmpadd")),
'-' => Ok(self.builder.build_float_sub(&lhs, &rhs, "tmpsub")),
'*' => Ok(self.builder.build_float_mul(&lhs, &rhs, "tmpmul")),
'/' => Ok(self.builder.build_float_div(&lhs, &rhs, "tmpdiv")),
'+' => Ok(self.builder.build_float_add(lhs, rhs, "tmpadd")),
'-' => Ok(self.builder.build_float_sub(lhs, rhs, "tmpsub")),
'*' => Ok(self.builder.build_float_mul(lhs, rhs, "tmpmul")),
'/' => Ok(self.builder.build_float_div(lhs, rhs, "tmpdiv")),
'<' => Ok({
let cmp = self.builder.build_float_compare(FloatPredicate::ULT, &lhs, &rhs, "tmpcmp");
let cmp = self.builder.build_float_compare(FloatPredicate::ULT, lhs, rhs, "tmpcmp");

self.builder.build_unsigned_int_to_float(&cmp, &self.context.f64_type(), "tmpbool")
self.builder.build_unsigned_int_to_float(cmp, self.context.f64_type(), "tmpbool")
}),
'>' => Ok({
let cmp = self.builder.build_float_compare(FloatPredicate::ULT, &rhs, &lhs, "tmpcmp");
let cmp = self.builder.build_float_compare(FloatPredicate::ULT, rhs, lhs, "tmpcmp");

self.builder.build_unsigned_int_to_float(&cmp, &self.context.f64_type(), "tmpbool")
self.builder.build_unsigned_int_to_float(cmp, self.context.f64_type(), "tmpbool")
}),

custom => {
Expand Down Expand Up @@ -1002,7 +1002,7 @@ impl<'a> Compiler<'a> {

// create condition by comparing without 0.0 and returning an int
let cond = self.compile_expr(cond)?;
let cond = self.builder.build_float_compare(FloatPredicate::ONE, &cond, &zero_const, "ifcond");
let cond = self.builder.build_float_compare(FloatPredicate::ONE, cond, zero_const, "ifcond");

// build branch
let then_bb = self.context.append_basic_block(&parent, "then");
Expand Down Expand Up @@ -1069,11 +1069,11 @@ impl<'a> Compiler<'a> {
let end_cond = self.compile_expr(end)?;

let curr_var = self.builder.build_load(&start_alloca, var_name);
let next_var = self.builder.build_float_add(curr_var.as_float_value(), &step, "nextvar");
let next_var = self.builder.build_float_add(curr_var.into_float_value(), step, "nextvar");

self.builder.build_store(&start_alloca, &next_var);

let end_cond = self.builder.build_float_compare(FloatPredicate::ONE, &end_cond, &self.context.f64_type().const_float(0.0), "loopcond");
let end_cond = self.builder.build_float_compare(FloatPredicate::ONE, end_cond, self.context.f64_type().const_float(0.0), "loopcond");
let after_bb = self.context.append_basic_block(&parent, "afterloop");

self.builder.build_conditional_branch(&end_cond, &loop_bb, &after_bb);
Expand Down
212 changes: 108 additions & 104 deletions src/builder.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use types::fn_type::FunctionType;
pub use types::int_type::IntType;
pub use types::ptr_type::PointerType;
pub use types::struct_type::StructType;
pub use types::traits::{AnyType, BasicType};
pub use types::traits::{AnyType, BasicType, IntMathType, FloatMathType, PointerMathType};
pub use types::vec_type::VectorType;
pub use types::void_type::VoidType;
pub(crate) use types::traits::AsTypeRef;
Expand Down
52 changes: 52 additions & 0 deletions src/types/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::fmt::Debug;

use types::{IntType, FunctionType, FloatType, PointerType, StructType, ArrayType, VectorType, VoidType, Type};
use types::enums::{AnyTypeEnum, BasicTypeEnum};
use values::{IntMathValue, FloatMathValue, PointerMathValue, IntValue, FloatValue, PointerValue, VectorValue};

// This is an ugly privacy hack so that Type can stay private to this module
// and so that super traits using this trait will be not be implementable
Expand Down Expand Up @@ -40,5 +41,56 @@ pub trait BasicType: AnyType {
}
}

/// Represents an LLVM type that can have integer math operations applied to it.
pub trait IntMathType: BasicType {
type ValueType: IntMathValue;
type MathConvType: FloatMathType;
type PtrConvType: PointerMathType;
}

/// Represents an LLVM type that can have floating point math operations applied to it.
pub trait FloatMathType: BasicType {
type ValueType: FloatMathValue;
type MathConvType: IntMathType;
}

/// Represents an LLVM type that can have pointer operations applied to it.
pub trait PointerMathType: BasicType {
type ValueType: PointerMathValue;
type PtrConvType: IntMathType;
}

trait_type_set! {AnyType: AnyTypeEnum, BasicTypeEnum, IntType, FunctionType, FloatType, PointerType, StructType, ArrayType, VoidType, VectorType}
trait_type_set! {BasicType: BasicTypeEnum, IntType, FloatType, PointerType, StructType, ArrayType, VectorType}

impl IntMathType for IntType {
type ValueType = IntValue;
type MathConvType = FloatType;
type PtrConvType = PointerType;
}

impl IntMathType for VectorType {
type ValueType = VectorValue;
type MathConvType = VectorType;
type PtrConvType = VectorType;
}

impl FloatMathType for FloatType {
type ValueType = FloatValue;
type MathConvType = IntType;
}

impl FloatMathType for VectorType {
type ValueType = VectorValue;
type MathConvType = VectorType;
}

impl PointerMathType for PointerType {
type ValueType = PointerValue;
type PtrConvType = IntType;
}

impl PointerMathType for VectorType {
type ValueType = VectorValue;
type PtrConvType = VectorType;
}
2 changes: 1 addition & 1 deletion src/values/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub use values::metadata_value::{MetadataValue, FIRST_CUSTOM_METADATA_KIND_ID};
pub use values::phi_value::PhiValue;
pub use values::ptr_value::PointerValue;
pub use values::struct_value::StructValue;
pub use values::traits::{AnyValue, AggregateValue, BasicValue};
pub use values::traits::{AnyValue, AggregateValue, BasicValue, IntMathValue, FloatMathValue, PointerMathValue};
pub use values::vec_value::VectorValue;
pub(crate) use values::traits::AsValueRef;

Expand Down
34 changes: 34 additions & 0 deletions src/values/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use llvm_sys::prelude::LLVMValueRef;
use std::fmt::Debug;

use values::{ArrayValue, AggregateValueEnum, GlobalValue, StructValue, BasicValueEnum, AnyValueEnum, IntValue, FloatValue, PointerValue, PhiValue, VectorValue, FunctionValue, InstructionValue};
use types::{IntMathType, FloatMathType, PointerMathType, IntType, FloatType, PointerType, VectorType};

// This is an ugly privacy hack so that Type can stay private to this module
// and so that super traits using this trait will be not be implementable
Expand All @@ -22,6 +23,19 @@ macro_rules! trait_value_set {
);
}

macro_rules! math_trait_value_set {
($trait_name:ident: $(($value_type:ident => $base_type:ident)),*) => (
$(
impl $trait_name for $value_type {
type BaseType = $base_type;
fn new(value: LLVMValueRef) -> Self {
$value_type::new(value)
}
}
)*
)
}

/// Represents an aggregate value, built on top of other values.
pub trait AggregateValue: BasicValue {
/// Returns an enum containing a typed version of the `AggregateValue`.
Expand All @@ -38,6 +52,23 @@ pub trait BasicValue: AnyValue {
}
}

/// Represents a value which is permitted in integer math operations
pub trait IntMathValue: BasicValue {
type BaseType: IntMathType;
fn new(value: LLVMValueRef) -> Self;
}

/// Represents a value which is permitted in floating point math operations
pub trait FloatMathValue: BasicValue {
type BaseType: FloatMathType;
fn new(value: LLVMValueRef) -> Self;
}

pub trait PointerMathValue: BasicValue {
type BaseType: PointerMathType;
fn new(value: LLVMValueRef) -> Self;
}

/// Defines any struct wrapping an LLVM value.
pub trait AnyValue: AsValueRef + Debug {
/// Returns an enum containing a typed version of `AnyValue`.
Expand All @@ -49,3 +80,6 @@ pub trait AnyValue: AsValueRef + Debug {
trait_value_set! {AggregateValue: ArrayValue, AggregateValueEnum, StructValue}
trait_value_set! {AnyValue: AnyValueEnum, BasicValueEnum, AggregateValueEnum, ArrayValue, IntValue, FloatValue, GlobalValue, PhiValue, PointerValue, FunctionValue, StructValue, VectorValue, InstructionValue}
trait_value_set! {BasicValue: ArrayValue, BasicValueEnum, AggregateValueEnum, IntValue, FloatValue, GlobalValue, StructValue, PointerValue, VectorValue}
math_trait_value_set! {IntMathValue: (IntValue => IntType), (VectorValue => VectorType)}
math_trait_value_set! {FloatMathValue: (FloatValue => FloatType), (VectorValue => VectorType)}
math_trait_value_set! {PointerMathValue: (PointerValue => PointerType), (VectorValue => VectorType)}
Loading

0 comments on commit 50e94ee

Please sign in to comment.