Mercurial > octave-nkf
diff src/jit-typeinfo.cc @ 15067:df4538e3b50b
ND scalar indexing in JIT.
* src/jit-ir.cc (jit_magic_end::jit_magic_end): Use jit_magic_end::context.
* src/jit-ir.h (jit_call::jit_call): New overload.
(jit_magic_end::context): New class.
(jit_magic_end::jit_magic_end): moved to src/jit-ir.cc.
* src/jit-typeinfo.cc (octave_jit_paren_scalar): New function.
(jit_typeinfo::jit_typeinfo): Generate ND scalar indexing.
(jit_typeinfo::gen_subsref): New function.
* src/jit-typeinfo.h (jit_typeinfo::gen_subsref): New declaration.
* src/pt-jit.cc (jit_convert::visit_index_expression, jit_convert::do_assign):
Update resolve call.
(jit_convert::resolve): Resolve ND indices.
* src/pt-jit.h (jit_convert::resolve): Change function signature.
author | Max Brister <max@2bass.com> |
---|---|
date | Tue, 31 Jul 2012 11:51:01 -0500 |
parents | bc32288f4a42 |
children | f57d7578c1a6 |
line wrap: on
line diff
--- a/src/jit-typeinfo.cc Tue Jul 31 14:14:03 2012 -0400 +++ b/src/jit-typeinfo.cc Tue Jul 31 11:51:01 2012 -0500 @@ -243,6 +243,27 @@ *ret = *mat; } +extern "C" double +octave_jit_paren_scalar (jit_matrix *mat, double *indicies, + octave_idx_type idx_count) +{ + // FIXME: Replace this with a more optimal version + try + { + Array<idx_vector> idx (dim_vector (1, idx_count)); + for (octave_idx_type i = 0; i < idx_count; ++i) + idx(i) = idx_vector (indicies[i]); + + Array<double> ret = mat->array->index (idx); + return ret.xelem (0); + } + catch (const octave_execution_exception&) + { + gripe_library_execution_error (); + return 0; + } +} + extern "C" void octave_jit_paren_subsasgn_matrix_range (jit_matrix *result, jit_matrix *mat, jit_range *index, double value) @@ -789,6 +810,9 @@ boolean = new_type ("bool", any, bool_t); index = new_type ("index", any, index_t); + // a fake type for interfacing with C++ + jit_type *scalar_ptr = new_type ("scalar_ptr", 0, scalar_t->getPointerTo ()); + create_int (8); create_int (16); create_int (32); @@ -1310,6 +1334,18 @@ } paren_subsref_fn.add_overload (fn); + // generate () subsref for ND indexing of matricies with scalars + jit_function paren_scalar = create_function (jit_convention::external, + "octave_jit_paren_scalar", + scalar, matrix, scalar_ptr, + index); + paren_scalar.add_mapping (engine, &octave_jit_paren_scalar); + paren_scalar.mark_can_error (); + + // FIXME: Generate this on the fly + for (size_t i = 2; i < 10; ++i) + gen_subsref (paren_scalar, i); + // paren subsasgn paren_subsasgn_fn.stash_name ("()subsasgn"); @@ -1831,4 +1867,37 @@ return ret; } +void +jit_typeinfo::gen_subsref (const jit_function& paren_scalar, size_t n) +{ + std::stringstream name; + name << "jit_paren_subsref_matrix_scalar" << n; + std::vector<jit_type *> args (n + 1, scalar); + args[0] = matrix; + jit_function fn = create_function (jit_convention::internal, name.str (), + scalar, args); + fn.mark_can_error (); + llvm::BasicBlock *body = fn.new_block (); + builder.SetInsertPoint (body); + + llvm::Type *scalar_t = scalar->to_llvm (); + llvm::ArrayType *array_t = llvm::ArrayType::get (scalar_t, n); + llvm::Value *array = llvm::UndefValue::get (array_t); + for (size_t i = 0; i < n; ++i) + { + llvm::Value *idx = fn.argument (builder, i + 1); + array = builder.CreateInsertValue (array, idx, i); + } + + llvm::Value *array_mem = builder.CreateAlloca (array_t); + builder.CreateStore (array, array_mem); + array = builder.CreateBitCast (array_mem, scalar_t->getPointerTo ()); + + llvm::Value *nelem = llvm::ConstantInt::get (index->to_llvm (), n); + llvm::Value *mat = fn.argument (builder, 0); + llvm::Value *ret = paren_scalar.call (builder, mat, array, nelem); + fn.do_return (builder, ret); + paren_subsref_fn.add_overload (fn); +} + #endif