changeset 18564: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	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)
 {
--- 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,