# HG changeset patch # User Stefan Mahr # Date 1385332130 -3600 # Node ID 5a5a67799338411261bba327bdb03d20f4ba09aa # Parent d464edd2552bc16e3749448a28062209d0c7824a 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 diff -r d464edd2552b -r 5a5a67799338 libinterp/corefcn/jit-typeinfo.cc --- a/libinterp/corefcn/jit-typeinfo.cc Fri Sep 27 06:50:59 2013 +0800 +++ b/libinterp/corefcn/jit-typeinfo.cc Sun Nov 24 23:28:50 2013 +0100 @@ -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) { diff -r d464edd2552b -r 5a5a67799338 libinterp/corefcn/jit-typeinfo.h --- a/libinterp/corefcn/jit-typeinfo.h Fri Sep 27 06:50:59 2013 +0800 +++ b/libinterp/corefcn/jit-typeinfo.h Sun Nov 24 23:28:50 2013 +0100 @@ -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,