This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gccgo] Use builtin sqrt
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 18 Nov 2009 23:02:22 -0800
- Subject: [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);
}