# HG changeset patch # User Max Brister # Date 1340745330 18000 # Node ID 2960f1b2d6eac851032c0c2256fa75e955327ebd # Parent 457eb974310bfbaea14aea128d55d4913015346d Add sin to JIT * src/ov-builtin.cc (octave_builtin::to_jit, octave_builtin::stash_jit): New function. * src/ov-builtin.h (octave_builtin::to_jit, octave_builtin::stash_jit): New declaration. (octave_builtin::octave_builtin): Initialize jtype. * src/pt-jit.cc (jit_typeinfo::jit_typeinfo): Initialize sin type. (jit_typeinfo::do_type_of): Convert builtin functions to their jit type. * src/pt-jit.h (jit_typeinfo): Add sin_type diff --git a/src/ov-builtin.cc b/src/ov-builtin.cc --- a/src/ov-builtin.cc +++ b/src/ov-builtin.cc @@ -152,5 +152,16 @@ return retval; } +jit_type * +octave_builtin::to_jit (void) const +{ + return jtype; +} + +void +octave_builtin::stash_jit (jit_type &type) +{ + jtype = &type; +} const std::list *octave_builtin::curr_lvalue_list = 0; diff --git a/src/ov-builtin.h b/src/ov-builtin.h --- a/src/ov-builtin.h +++ b/src/ov-builtin.h @@ -30,6 +30,7 @@ class octave_value; class octave_value_list; +class jit_type; // Builtin functions. @@ -39,13 +40,13 @@ { public: - octave_builtin (void) : octave_function (), f (0) { } + octave_builtin (void) : octave_function (), f (0), jtype (0) { } typedef octave_value_list (*fcn) (const octave_value_list&, int); octave_builtin (fcn ff, const std::string& nm = std::string (), const std::string& ds = std::string ()) - : octave_function (nm, ds), f (ff) { } + : octave_function (nm, ds), f (ff), jtype (0) { } ~octave_builtin (void) { } @@ -75,6 +76,10 @@ do_multi_index_op (int nargout, const octave_value_list& args, const std::list* lvalue_list); + jit_type *to_jit (void) const; + + void stash_jit (jit_type& type); + static const std::list *curr_lvalue_list; protected: @@ -82,6 +87,9 @@ // A pointer to the actual function. fcn f; + // A pointer to the jit type that represents the function. + jit_type *jtype; + private: // No copying! diff --git a/src/pt-jit.cc b/src/pt-jit.cc --- a/src/pt-jit.cc +++ b/src/pt-jit.cc @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #include "octave.h" #include "ov-fcn-handle.h" #include "ov-usr-fcn.h" +#include "ov-builtin.h" #include "ov-scalar.h" #include "pt-all.h" @@ -406,6 +408,8 @@ boolean = new_type ("bool", any, bool_t); index = new_type ("index", any, index_t); + sin_type = new_type ("sin", any, any_t); + casts.resize (next_id + 1); identities.resize (next_id + 1, 0); @@ -474,6 +478,7 @@ // release any fn = create_function ("octave_jit_release_any", void_t, any_t); + llvm::Function *release_any = fn; engine->addGlobalMapping (fn, reinterpret_cast(&octave_jit_release_any)); release_fn.add_overload (fn, false, 0, any); @@ -892,6 +897,37 @@ // cast scalar <- scalar fn = create_identity (scalar); casts[scalar->type_id ()].add_overload (fn, false, scalar, scalar); + + + // -------------------- builtin functions -------------------- + + // FIXME: Handling this here is messy, but it's the easiest way for now + // FIXME: Come up with a nicer way of defining functions + octave_value ov_sin = symbol_table::builtin_find ("sin"); + octave_builtin *bsin + = dynamic_cast (ov_sin.internal_rep ()); + if (bsin) + { + bsin->stash_jit (*sin_type); + + llvm::Function *isin + = llvm::Intrinsic::getDeclaration (module, llvm::Intrinsic::sin, + llvm::makeArrayRef (scalar_t)); + fn = create_function ("octave_jit_sin", scalar, any, scalar); + body = llvm::BasicBlock::Create (context, "body", fn); + builder.SetInsertPoint (body); + { + llvm::Value *ret = builder.CreateCall (isin, ++fn->arg_begin ()); + builder.CreateRet (ret); + } + llvm::verifyFunction (*fn); + paren_subsref_fn.add_overload (fn, false, scalar, sin_type, scalar); + release_fn.add_overload (release_any, false, 0, sin_type); + + fn = create_identity (any); + casts[any->type_id ()].add_overload (fn, false, any, sin_type); + casts[sin_type->type_id ()].add_overload (fn, false, sin_type, any); + } } void @@ -1019,7 +1055,13 @@ jit_typeinfo::do_type_of (const octave_value &ov) const { if (ov.is_function ()) - return 0; // functions are not supported + { + // FIXME: This is ugly, we need to finalize how we want to to this, then + // have octave_value fully support the needed functionality + octave_builtin *builtin + = dynamic_cast (ov.internal_rep ()); + return builtin ? builtin->to_jit () : 0; + } if (ov.is_range ()) return get_range (); diff --git a/src/pt-jit.h b/src/pt-jit.h --- a/src/pt-jit.h +++ b/src/pt-jit.h @@ -53,9 +53,11 @@ // The jit_functions contain information about overloads for different types. // For, example, if we know a and b are scalars, then c must also be a scalar. // +// Support for function calls is in progress. Currently, calls to sin with a +// scalar argument will compile. // // TODO: -// 1. Function calls +// 1. Function calls (In progress) // 2. Cleanup/documentation // 3. ... // --------------------------------------------------------- @@ -681,6 +683,7 @@ jit_type *string; jit_type *boolean; jit_type *index; + jit_type *sin_type; std::vector binary_ops; jit_function grab_fn;