This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gccgo] Use builtin sqrt


I committed this patch to the gccgo branch to use gcc's builtin sqrt
capability for Math.sqrt.  (This also fixes a bug in the last commit.)

Ian


Index: gcc/go/gogo.cc
===================================================================
--- gcc/go/gogo.cc	(revision 154273)
+++ gcc/go/gogo.cc	(working copy)
@@ -58,8 +58,9 @@ Gogo::Gogo()
 
   this->add_named_type(Type::make_float_type("float32", 32,
 					     RUNTIME_TYPE_CODE_FLOAT32));
-  this->add_named_type(Type::make_float_type("float64", 64,
-					     RUNTIME_TYPE_CODE_FLOAT64));
+  Named_type* float64_type = Type::make_float_type("float64", 64,
+						   RUNTIME_TYPE_CODE_FLOAT64);
+  this->add_named_type(float64_type);
 
   const int int_type_size = std::max(INT_TYPE_SIZE, 32);
   this->add_named_type(Type::make_integer_type("uint", true,
@@ -173,6 +174,17 @@ Gogo::Gogo()
 
   this->define_builtin_function_trees();
 
+  // For the math library.
+  Typed_identifier_list* sqrt_arg = new Typed_identifier_list();
+  sqrt_arg->push_back(Typed_identifier("x", float64_type, loc));
+  Typed_identifier_list* sqrt_result = new Typed_identifier_list();
+  sqrt_result->push_back(Typed_identifier("", float64_type, loc));
+  Function_type* sqrt_type = Type::make_function_type(NULL, sqrt_arg,
+						      sqrt_result, loc);
+  sqrt_type->set_is_builtin();
+  this->globals_->add_function_declaration("__builtin_sqrt", NULL, sqrt_type,
+					   loc);
+
   // Declare "init", to ensure that it is not defined with parameters
   // or return values.
   this->declare_function("init",
Index: gcc/go/go-lang.c
===================================================================
--- gcc/go/go-lang.c	(revision 154273)
+++ gcc/go/go-lang.c	(working copy)
@@ -114,6 +114,9 @@ go_langhook_init_options (unsigned int a
      requirements.  */
   flag_strict_aliasing = 1;
 
+  /* The builtin math functions should not set errno.  */
+  flag_errno_math = 0;
+
   /* We default to always showing a column number.  */
   flag_show_column = 1;
 
Index: gcc/go/gogo-tree.cc
===================================================================
--- gcc/go/gogo-tree.cc	(revision 154273)
+++ gcc/go/gogo-tree.cc	(working copy)
@@ -79,6 +79,12 @@ Gogo::define_builtin_function_trees()
 					  long_integer_type_node,
 					  NULL_TREE),
 		 true);
+
+  // We provide __builtin_sqrt for the math library.
+  define_builtin(BUILT_IN_SQRT, "__builtin_sqrt",
+		 build_function_type_list(double_type_node, double_type_node,
+					  NULL_TREE),
+		 true);
 }
 
 // Get the name to use for the import control function.  If there is a
Index: gcc/go/expressions.cc
===================================================================
--- gcc/go/expressions.cc	(revision 154318)
+++ gcc/go/expressions.cc	(working copy)
@@ -2828,7 +2828,7 @@ class Unary_expression : public Expressi
  public:
   Unary_expression(Operator op, Expression* expr, source_location location)
     : Expression(EXPRESSION_UNARY, location),
-      op_(op), expr_(expr), escapes_(true)
+      op_(op), escapes_(true), expr_(expr)
   { }
 
   // Return the operator.
@@ -4999,7 +4999,10 @@ class Builtin_call_expression : public C
       // Builtin functions from the unsafe package.
       BUILTIN_ALIGNOF,
       BUILTIN_OFFSETOF,
-      BUILTIN_SIZEOF
+      BUILTIN_SIZEOF,
+
+      // gccgo specific builtin functions.
+      BUILTIN_SQRT
     };
 
   Expression*
@@ -5051,6 +5054,8 @@ Builtin_call_expression::Builtin_call_ex
     this->code_ = BUILTIN_OFFSETOF;
   else if (name == "Sizeof")
     this->code_ = BUILTIN_SIZEOF;
+  else if (name == "__builtin_sqrt")
+    this->code_ = BUILTIN_SQRT;
   else
     gcc_unreachable();
 }
@@ -5323,6 +5328,9 @@ Builtin_call_expression::do_type()
 
     case BUILTIN_CLOSED:
       return Type::lookup_bool_type();
+
+    case BUILTIN_SQRT:
+      return Type::lookup_float_type("float64");
     }
 }
 
@@ -5334,6 +5342,8 @@ Builtin_call_expression::do_determine_ty
   this->fn()->determine_type_no_context();
 
   Type_context subcontext(NULL, true);
+  if (this->code_ == BUILTIN_SQRT)
+    subcontext.type = Type::lookup_float_type("float64");
   const Expression_list* args = this->args();
   if (args != NULL)
     {
@@ -5478,6 +5488,17 @@ Builtin_call_expression::do_check_types(
 	}
       break;
 
+    case BUILTIN_SQRT:
+      if (this->check_one_arg())
+	{
+	  Expression* arg = this->one_arg();
+	  if (arg->type()->float_type() == NULL
+	      || arg->type()->float_type()->is_abstract()
+	      || arg->type()->float_type()->bits() != 64)
+	    this->report_error(_("argument 1 has incompatible type"));
+	}
+      break;
+
     default:
       gcc_unreachable();
     }
@@ -5801,6 +5822,22 @@ Builtin_call_expression::do_get_tree(Tra
 	return ret;
       }
 
+    case BUILTIN_SQRT:
+      {
+	const Expression_list* args = this->args();
+	gcc_assert(args != NULL && args->size() == 1);
+	Expression* arg = args->front();
+	tree arg_tree = arg->get_tree(context);
+	if (arg_tree == error_mark_node)
+	  return error_mark_node;
+	tree type = Type::lookup_float_type("float64")->get_tree(gogo);
+	arg_tree = fold_convert_loc(this->location(), type, arg_tree);
+	tree fn = built_in_decls[BUILT_IN_SQRT];
+	tree call = build1(ADDR_EXPR, build_pointer_type(TREE_TYPE(fn)), fn);
+	call = build_call_nary(TREE_TYPE(TREE_TYPE(fn)), call, 1, arg_tree);
+	return fold_convert_loc(this->location(), type, call);
+      }
+
     default:
       gcc_unreachable();
     }
Index: libgo/go/math/sqrt.go
===================================================================
--- libgo/go/math/sqrt.go	(revision 154273)
+++ libgo/go/math/sqrt.go	(working copy)
@@ -30,36 +30,5 @@ func Sqrt(x float64) float64 {
 		return 0;
 	}
 
-	y, exp := Frexp(x);
-	for y < 0.5 {
-		y = y * 2;
-		exp = exp - 1;
-	}
-
-	if exp&1 != 0 {
-		y = y * 2;
-		exp = exp - 1;
-	}
-	temp := 0.5 * (1 + y);
-
-	for exp > 60 {
-		temp = temp * float64(1<<30);
-		exp = exp - 60;
-	}
-	for exp < -60 {
-		temp = temp / float64(1<<30);
-		exp = exp + 60;
-	}
-	if exp >= 0 {
-		exp = 1 << uint(exp/2);
-		temp = temp * float64(exp);
-	} else {
-		exp = 1 << uint(-exp/2);
-		temp = temp / float64(exp);
-	}
-
-	for i := 0; i <= 4; i++ {
-		temp = 0.5 * (temp + x/temp)
-	}
-	return temp;
+	return __builtin_sqrt(x);
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]