[Gmp-commit] /var/hg/gmp: Allocate less for overlapping operands.

mercurial at gmplib.org mercurial at gmplib.org
Tue May 22 22:54:34 CEST 2012


details:   /var/hg/gmp/rev/42c56b9cc061
changeset: 14997:42c56b9cc061
user:      Torbjorn Granlund <tege at gmplib.org>
date:      Tue May 22 22:54:31 2012 +0200
description:
Allocate less for overlapping operands.

diffstat:

 ChangeLog     |   2 +-
 mpz/sqrt.c    |  29 +++++++++++++++--------------
 mpz/sqrtrem.c |  35 +++++++++++++++++++----------------
 3 files changed, 35 insertions(+), 31 deletions(-)

diffs (146 lines):

diff -r 95565da39490 -r 42c56b9cc061 ChangeLog
--- a/ChangeLog	Tue May 22 20:32:36 2012 +0200
+++ b/ChangeLog	Tue May 22 22:54:31 2012 +0200
@@ -1,6 +1,6 @@
 2012-05-22  Torbjorn Granlund  <tege at gmplib.org>
 
-	* mpz/sqrt.c: Simplify.
+	* mpz/sqrt.c: Allocate less for overlapping operands, simplify.
 	* mpz/sqrtrem.c: Likewise.
 
 2012-05-21 Marco Bodrato <bodrato at mail.dm.unipi.it>
diff -r 95565da39490 -r 42c56b9cc061 mpz/sqrt.c
--- a/mpz/sqrt.c	Tue May 22 20:32:36 2012 +0200
+++ b/mpz/sqrt.c	Tue May 22 22:54:31 2012 +0200
@@ -27,9 +27,7 @@
 {
   mp_size_t op_size, root_size;
   mp_ptr root_ptr, op_ptr;
-  TMP_DECL;
 
-  TMP_MARK;
   op_size = SIZ (op);
   if (op_size <= 0)
     {
@@ -41,6 +39,7 @@
 
   /* The size of the root is accurate after this simple calculation.  */
   root_size = (op_size + 1) / 2;
+  SIZ (root) = root_size;
 
   root_ptr = PTR (root);
   op_ptr = PTR (op);
@@ -50,27 +49,29 @@
       /* From size relations, we can tell ROOT != OP.  */
       ASSERT (root_ptr != op_ptr);
 
-      __GMP_FREE_FUNC_LIMBS (root_ptr, ALLOC (root));
-
+      root_ptr = __GMP_REALLOCATE_FUNC_LIMBS (root_ptr, ALLOC (root), root_size);
       ALLOC (root) = root_size;
-      root_ptr = __GMP_ALLOCATE_FUNC_LIMBS (root_size);
       PTR (root) = root_ptr;
     }
   else
     {
-      /* Make OP not overlap with ROOT.  */
       if (root_ptr == op_ptr)
 	{
-	  /* ROOT and OP are identical.  Allocate temporary space for OP.  */
-	  op_ptr = TMP_ALLOC_LIMBS (op_size);
-	  /* Copy to the temporary space.  Hack: Avoid temporary variable
-	     by using ROOT_PTR.  */
-	  MPN_COPY (op_ptr, root_ptr, op_size);
+	  /* Allocate temp space for the root, which we then copy to the
+	     shared OP/ROOT variable.  */
+	  mp_ptr p;
+	  TMP_DECL;
+	  TMP_MARK;
+
+	  p = TMP_ALLOC_LIMBS (root_size);
+	  mpn_sqrtrem (p, NULL, root_ptr, op_size);
+
+	  MPN_COPY (root_ptr, p, root_size);
+
+	  TMP_FREE;
+	  return;
 	}
     }
 
   mpn_sqrtrem (root_ptr, NULL, op_ptr, op_size);
-
-  SIZ (root) = root_size;
-  TMP_FREE;
 }
diff -r 95565da39490 -r 42c56b9cc061 mpz/sqrtrem.c
--- a/mpz/sqrtrem.c	Tue May 22 20:32:36 2012 +0200
+++ b/mpz/sqrtrem.c	Tue May 22 22:54:31 2012 +0200
@@ -28,9 +28,7 @@
 {
   mp_size_t op_size, root_size, rem_size;
   mp_ptr root_ptr, op_ptr;
-  TMP_DECL;
 
-  TMP_MARK;
   op_size = SIZ (op);
   if (op_size <= 0)
     {
@@ -45,6 +43,7 @@
 
   /* The size of the root is accurate after this simple calculation.  */
   root_size = (op_size + 1) / 2;
+  SIZ (root) = root_size;
 
   root_ptr = PTR (root);
   op_ptr = PTR (op);
@@ -54,32 +53,36 @@
       /* From size relations, we can tell ROOT != OP.  */
       ASSERT (root_ptr != op_ptr);
 
-      __GMP_FREE_FUNC_LIMBS (root_ptr, ALLOC (root));
-
+      root_ptr = __GMP_REALLOCATE_FUNC_LIMBS (root_ptr, ALLOC (root), root_size);
       ALLOC (root) = root_size;
-      root_ptr = __GMP_ALLOCATE_FUNC_LIMBS (root_size);
       PTR (root) = root_ptr;
     }
   else
     {
-      /* Make OP not overlap with ROOT.  */
       if (root_ptr == op_ptr)
 	{
-	  /* ROOT and OP are identical.  Allocate temporary space for OP.  */
-	  op_ptr = TMP_ALLOC_LIMBS (op_size);
-	  /* Copy to the temporary space.  Hack: Avoid temporary variable
-	     by using ROOT_PTR.  */
-	  MPN_COPY (op_ptr, root_ptr, op_size);
+	  /* Allocate temp space for the root, which we then copy to the
+	     shared OP/ROOT variable.  */
+	  mp_ptr p;
+	  TMP_DECL;
+	  TMP_MARK;
+
+	  p = TMP_ALLOC_LIMBS (root_size);
+	  rem_size = mpn_sqrtrem (p, PTR (rem), root_ptr, op_size);
+
+	  if (rem != root)	/* Don't overwrite remainder */
+	    MPN_COPY (root_ptr, p, root_size);
+
+	  TMP_FREE;
+	  goto done;
 	}
     }
 
   rem_size = mpn_sqrtrem (root_ptr, PTR (rem), op_ptr, op_size);
 
-  SIZ (root) = root_size;
+ done:
 
-  /* Write remainder size last, to enable us to define this function to
-     give only the square root remainder, if the user calls if with
-     ROOT == REM.  */
+  /* Write remainder size last, to make this function give only the square root
+     remainder, when passed ROOT == REM.  */
   SIZ (rem) = rem_size;
-  TMP_FREE;
 }


More information about the gmp-commit mailing list