Mercurial > hg > octave-nkf
changeset 18632:5a5a67799338 draft
jit compiler: Use seperate function for division operation
* libinterp/corefcn/jit-typeinfo.cc (jit_typeinfo::divide_float): New
function.
* libinterp/corefcn/jit-typeinfo.h (jit_typeinfo::divide_float): Declare
new function
author | Stefan Mahr <dac922@gmx.de> |
---|---|
date | Sun, 24 Nov 2013 23:28:50 +0100 |
parents | d464edd2552b |
children | 3f2a95a4b98d |
files | libinterp/corefcn/jit-typeinfo.cc libinterp/corefcn/jit-typeinfo.h |
diffstat | 2 files changed, 39 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/jit-typeinfo.cc +++ b/libinterp/corefcn/jit-typeinfo.cc @@ -1943,32 +1943,7 @@ add_binary_fcmp (scalar, octave_value::op_gt, llvm::CmpInst::FCMP_UGT); add_binary_fcmp (scalar, octave_value::op_ne, llvm::CmpInst::FCMP_UNE); - jit_function gripe_div0 = create_external (JIT_FN (gripe_divide_by_zero), 0); - gripe_div0.mark_can_error (); - - // divide is annoying because it might error - fn = create_internal ("octave_jit_div_scalar_scalar", scalar, scalar, scalar); - fn.mark_can_error (); - - llvm::BasicBlock *body = fn.new_block (); - builder.SetInsertPoint (body); - { - llvm::BasicBlock *warn_block = fn.new_block ("warn"); - llvm::BasicBlock *normal_block = fn.new_block ("normal"); - - llvm::Value *zero = llvm::ConstantFP::get (scalar_t, 0); - llvm::Value *check = builder.CreateFCmpUEQ (zero, fn.argument (builder, 1)); - builder.CreateCondBr (check, warn_block, normal_block); - - builder.SetInsertPoint (warn_block); - gripe_div0.call (builder); - builder.CreateBr (normal_block); - - builder.SetInsertPoint (normal_block); - llvm::Value *ret = builder.CreateFDiv (fn.argument (builder, 0), - fn.argument (builder, 1)); - fn.do_return (builder, ret); - } + fn = divide_float (scalar); binary_ops[octave_value::op_div].add_overload (fn); binary_ops[octave_value::op_el_div].add_overload (fn); @@ -1988,7 +1963,7 @@ // now for unary scalar operations // FIXME: Impelment not fn = create_internal ("octave_jit_++", scalar, scalar); - body = fn.new_block (); + llvm::BasicBlock *body = fn.new_block (); builder.SetInsertPoint (body); { llvm::Value *one = llvm::ConstantFP::get (scalar_t, 1); @@ -2097,29 +2072,7 @@ add_binary_fcmp (single, octave_value::op_gt, llvm::CmpInst::FCMP_UGT); add_binary_fcmp (single, octave_value::op_ne, llvm::CmpInst::FCMP_UNE); - // divide is annoying because it might error - fn = create_internal ("octave_jit_div_single_single", single, single, single); - fn.mark_can_error (); - - body = fn.new_block (); - builder.SetInsertPoint (body); - { - llvm::BasicBlock *warn_block = fn.new_block ("warn"); - llvm::BasicBlock *normal_block = fn.new_block ("normal"); - - llvm::Value *zero = llvm::ConstantFP::get (single_t, 0); - llvm::Value *check = builder.CreateFCmpUEQ (zero, fn.argument (builder, 1)); - builder.CreateCondBr (check, warn_block, normal_block); - - builder.SetInsertPoint (warn_block); - gripe_div0.call (builder); - builder.CreateBr (normal_block); - - builder.SetInsertPoint (normal_block); - llvm::Value *ret = builder.CreateFDiv (fn.argument (builder, 0), - fn.argument (builder, 1)); - fn.do_return (builder, ret); - } + fn = divide_float (single); binary_ops[octave_value::op_div].add_overload (fn); binary_ops[octave_value::op_el_div].add_overload (fn); @@ -3526,6 +3479,40 @@ return ret; } +jit_function +jit_typeinfo::divide_float (jit_type* ty) +{ + jit_function gripe_div0 = create_external (engine, &gripe_divide_by_zero, "gripe_divide_by_zero", 0); + gripe_div0.mark_can_error (); + + // divide is annoying because it might error + std::stringstream fname; + fname << "octave_jit_divide_" << ty->name (); + jit_function fn = create_internal (fname.str (), ty, ty, ty); + fn.mark_can_error (); + + llvm::BasicBlock *body = fn.new_block (); + builder.SetInsertPoint (body); + { + llvm::BasicBlock *warn_block = fn.new_block ("warn"); + llvm::BasicBlock *normal_block = fn.new_block ("normal"); + + llvm::Value *zero = llvm::ConstantFP::get (ty->to_llvm(), 0); + llvm::Value *check = builder.CreateFCmpUEQ (zero, fn.argument (builder, 1)); + builder.CreateCondBr (check, warn_block, normal_block); + + builder.SetInsertPoint (warn_block); + gripe_div0.call (builder); + builder.CreateBr (normal_block); + + builder.SetInsertPoint (normal_block); + llvm::Value *ret = builder.CreateFDiv (fn.argument (builder, 0), + fn.argument (builder, 1)); + fn.do_return (builder, ret); + } + return fn; +} + llvm::Value * jit_typeinfo::pack_complex (llvm::IRBuilderD& bld, llvm::Value *cplx) {
--- a/libinterp/corefcn/jit-typeinfo.h +++ b/libinterp/corefcn/jit-typeinfo.h @@ -774,6 +774,8 @@ jit_function mirror_binary (const jit_function& fn); + jit_function divide_float (jit_type* ty); + llvm::Function *wrap_complex (llvm::Function *wrap); static llvm::Value *pack_complex (llvm::IRBuilderD& bld,