# HG changeset patch # User Max Brister # Date 1344629129 18000 # Node ID 709e8928e68cb1f1c816557cd194beba3d80816a # Parent 142e377e7e28911cd2e2650b1a67fcd243981b49 Scalar unary operation support in JIT * jit-typeinfo.cc (jit_typeinfo::jit_typeinfo): Add scalar unary operations. * jit-typeinfo.h (jit_typeinfo::unary_op, jit_typeinfo::do_unary_op): New function. * pt-jit.cc (jit_convert::visit_postfix_expression, jit_convert::visit_prefix_expression): Impelment. (jit_convert::visit): Protect result. diff -r 142e377e7e28 -r 709e8928e68c src/interp-core/jit-typeinfo.cc --- a/src/interp-core/jit-typeinfo.cc Fri Aug 10 13:09:11 2012 -0700 +++ b/src/interp-core/jit-typeinfo.cc Fri Aug 10 15:05:29 2012 -0500 @@ -1106,6 +1106,14 @@ binary_ops[i].stash_name ("binary" + op_name); } + unary_ops.resize (octave_value::num_unary_ops); + for (size_t i = 0; i < octave_value::num_unary_ops; ++i) + { + octave_value::unary_op op = static_cast (i); + std::string op_name = octave_value::unary_op_as_string (op); + unary_ops[i].stash_name ("unary" + op_name); + } + for (int op = 0; op < octave_value::num_binary_ops; ++op) { llvm::Twine fn_name ("octave_jit_binary_any_any_"); @@ -1164,7 +1172,6 @@ release_fn.add_overload (fn); // now for binary scalar operations - // FIXME: Finish all operations add_binary_op (scalar, octave_value::op_add, llvm::Instruction::FAdd); add_binary_op (scalar, octave_value::op_sub, llvm::Instruction::FSub); add_binary_op (scalar, octave_value::op_mul, llvm::Instruction::FMul); @@ -1224,6 +1231,48 @@ binary_ops[octave_value::op_pow].add_overload (fn); binary_ops[octave_value::op_el_pow].add_overload (fn); + // now for unary scalar operations + // FIXME: Impelment not + fn = create_function (jit_convention::internal, "octave_jit_++", scalar, + scalar); + body = fn.new_block (); + builder.SetInsertPoint (body); + { + llvm::Value *one = llvm::ConstantFP::get (scalar_t, 1); + llvm::Value *val = fn.argument (builder, 0); + val = builder.CreateFAdd (val, one); + fn.do_return (builder, val); + } + unary_ops[octave_value::op_incr].add_overload (fn); + + fn = create_function (jit_convention::internal, "octave_jit_--", scalar, + scalar); + body = fn.new_block (); + builder.SetInsertPoint (body); + { + llvm::Value *one = llvm::ConstantFP::get (scalar_t, 1); + llvm::Value *val = fn.argument (builder, 0); + val = builder.CreateFSub (val, one); + fn.do_return (builder, val); + } + unary_ops[octave_value::op_decr].add_overload (fn); + + fn = create_function (jit_convention::internal, "octave_jit_uminus", scalar, + scalar); + body = fn.new_block (); + builder.SetInsertPoint (body); + { + llvm::Value *mone = llvm::ConstantFP::get (scalar_t, -1); + llvm::Value *val = fn.argument (builder, 0); + val = builder.CreateFMul (val, mone); + fn.do_return (builder, val); + } + + fn = create_identity (scalar); + unary_ops[octave_value::op_uplus].add_overload (fn); + unary_ops[octave_value::op_transpose].add_overload (fn); + unary_ops[octave_value::op_hermitian].add_overload (fn); + // now for binary complex operations add_binary_op (complex, octave_value::op_add, llvm::Instruction::FAdd); add_binary_op (complex, octave_value::op_sub, llvm::Instruction::FSub); diff -r 142e377e7e28 -r 709e8928e68c src/interp-core/jit-typeinfo.h --- a/src/interp-core/jit-typeinfo.h Fri Aug 10 13:09:11 2012 -0700 +++ b/src/interp-core/jit-typeinfo.h Fri Aug 10 15:05:29 2012 -0500 @@ -476,6 +476,11 @@ return instance->do_binary_op (op); } + static const jit_operation& unary_op (int op) + { + return instance->do_unary_op (op); + } + static const jit_operation& grab (void) { return instance->grab_fn; } static const jit_function& get_grab (jit_type *type) @@ -607,6 +612,12 @@ return binary_ops[op]; } + const jit_operation& do_unary_op (int op) const + { + assert (static_cast (op) < unary_ops.size ()); + return unary_ops[op]; + } + const jit_operation& do_cast (jit_type *to) { static jit_operation null_function; @@ -737,6 +748,7 @@ llvm::StructType *complex_ret; std::vector binary_ops; + std::vector unary_ops; jit_operation grab_fn; jit_operation release_fn; jit_operation print_fn; diff -r 142e377e7e28 -r 709e8928e68c src/interp-core/pt-jit.cc --- a/src/interp-core/pt-jit.cc Fri Aug 10 13:09:11 2012 -0700 +++ b/src/interp-core/pt-jit.cc Fri Aug 10 15:05:29 2012 -0500 @@ -581,15 +581,33 @@ } void -jit_convert::visit_postfix_expression (tree_postfix_expression&) +jit_convert::visit_postfix_expression (tree_postfix_expression& tpe) { - throw jit_fail_exception (); + octave_value::unary_op etype = tpe.op_type (); + tree_expression *operand = tpe.operand (); + jit_value *operandv = visit (operand); + + const jit_operation& fn = jit_typeinfo::unary_op (etype); + result = create_checked (fn, operandv); + + if (etype == octave_value::op_incr || etype == octave_value::op_decr) + { + // FIXME: Somehow copy operandv + // do_assign (operand, operandv); + throw jit_fail_exception ("Postfix ++ and -- not yet supported"); + } } void -jit_convert::visit_prefix_expression (tree_prefix_expression&) +jit_convert::visit_prefix_expression (tree_prefix_expression& tpe) { - throw jit_fail_exception (); + octave_value::unary_op etype = tpe.op_type (); + tree_expression *operand = tpe.operand (); + const jit_operation& fn = jit_typeinfo::unary_op (etype); + result = create_checked (fn, visit (operand)); + + if (etype == octave_value::op_incr || etype == octave_value::op_decr) + do_assign (operand, result); } void @@ -905,12 +923,11 @@ jit_value * jit_convert::visit (tree& tee) { - result = 0; - tee.accept (*this); + unwind_protect prot; + prot.protect_var (result); - jit_value *ret = result; - result = 0; - return ret; + tee.accept (*this); + return result; } void @@ -1963,4 +1980,12 @@ %! endwhile %! assert (i == 10); +%!test +%! i = 0; +%! while i < 10 +%! a = ++i; +%! endwhile +%! assert (i == 10); +%! assert (a == 10); + */