public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [dax@gurulabs.com: PATCH: `__norestrict' type qualifier (fwd)]
@ 1999-09-12  0:51 Richard Stallman
  1999-09-12 12:29 ` Jamie Lokier
  1999-09-30 18:02 ` Richard Stallman
  0 siblings, 2 replies; 10+ messages in thread
From: Richard Stallman @ 1999-09-12  0:51 UTC (permalink / raw)
  To: gcc

The proposal below looks like a good idea to me, at least in
principle.  This would give people a straightforward and reliable
solution to use when they get the new warning that we are discussing.

Since this really is a new feature, we have to judge it as one; it
needs to be clear to document, and reliable to use.  I don't know
whether this feature can be described and implemented reliably, but I
think that should be possible.  "Apply the same rules that apply to
char *" seems like a clear basis for the specification; and as long as
GCC reliably implements the ISO C aliasing rules for char *, it should
be able to implement this with equal reliability.

The other change I've proposed, to keep many cases of old code working
for now, remains a good idea even if this new feature is added.
They complement each other.


------- Start of forwarded message -------
Date: Sat, 11 Sep 1999 01:15:58 -0600 (MDT)
From: Dax Kelson <dax@gurulabs.com>
X-Sender: dkelson@ultra1.inconnect.com
To: jbuck@synopsys.COM
cc: rms@gnu.org
Subject: PATCH: `__norestrict' type qualifier (fwd)
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Length: 10202


Isn't this post from July relevent to the current alias dicussion?

Dax Kelson

- ---------- Forwarded message ----------
Date: 17 Jul 1999 15:26:14 -0400
From: Patrick J. LoPresti <patl@cag.lcs.mit.edu>
To: egcs@egcs.cygnus.com
Cc: torvalds@transmeta.com
Subject: PATCH: `__norestrict' type qualifier

Just in time for 2.95!

OK, maybe not.

The following patch adds support for a "__norestrict" type qualifier.
It is used to mark a pointer type as potentially aliasing all of
memory.  For example:

  *(unsigned int *__norestrict)p ^= ~0;

...flips the 32 (or 64) bits pointed at by p, no matter what type p
has.

The rationale for this is straightforward; it is a logical extension
of the "char *" exception for type aliasing.  Obviously (?) the ISO
folks realized that people use char * to access raw memory, so they
allowed char * to alias anything.  The problem is that nobody who
cares about performance uses char * for this purpose on modern
machines; they use a pointer to something with the "natural" word size
of the architecture.

Lots of code (especially in the Linux kernel) is written this way, and
it is not easy to rewrite using unions or macros (according to the
maintainers).  The `__norestrict' keyword makes it easy to convert
such code so that it can work in the presence of type-based alias
analysis.

Two notes:

  1) This is not well-tested, although it seems to work.  Many thanks
     to the author (Mark Mitchell?) of the current alias analysis
     support.  That well-commented and well-structured code made this
     extension fairly trivial, even for a GCC neophyte like me.

  2) I have not even glanced at the other front ends (e.g., C++), so
     there may be some additional work needed there to get this
     finished.  I am willing to do that work, but I didn't want to
     spend any more time on something which the GCC maintainers might
     reject out-of-hand...

 - Pat

======================================================================

diff -u -r gcc-orig/c-aux-info.c gcc/c-aux-info.c
- --- gcc-orig/c-aux-info.c	Sat Apr 17 13:14:45 1999
+++ gcc/c-aux-info.c	Sat Jul 17 14:17:25 1999
@@ -524,6 +524,8 @@
     ret_val = concat ("volatile ", ret_val, NULL_PTR);
   if (TYPE_RESTRICT (t))
     ret_val = concat ("restrict ", ret_val, NULL_PTR);
+  if (TYPE_NORESTRICT (t))
+    ret_val = concat ("__norestrict ", ret_val, NULL_PTR);
   return ret_val;
 }
 
diff -u -r gcc-orig/c-common.c gcc/c-common.c
- --- gcc-orig/c-common.c	Tue Apr 13 17:04:06 1999
+++ gcc/c-common.c	Sat Jul 17 14:17:23 1999
@@ -2980,12 +2980,12 @@
      values, so even though it should be illegal to use `restrict'
      with such an entity we don't flag that here.  Thus, special case
      code for that case is required in the C++ front-end.  */
- -  if ((type_quals & TYPE_QUAL_RESTRICT)
+  if ((type_quals & (TYPE_QUAL_RESTRICT | TYPE_QUAL_NORESTRICT))
       && (!POINTER_TYPE_P (type)
 	  || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
     {
- -      error ("invalid use of `restrict'");
- -      type_quals &= ~TYPE_QUAL_RESTRICT;
+      error ("invalid use of `restrict' or `__norestrict'");
+      type_quals &= ~(TYPE_QUAL_RESTRICT | TYPE_QUAL_NORESTRICT);
     }
 
   if (TREE_CODE (type) == ARRAY_TYPE)
@@ -3038,6 +3038,18 @@
 				    DECL_POINTER_ALIAS_SET (decl));
 	    }
 	}
+    }
+  if (type_quals & TYPE_QUAL_NORESTRICT)
+    {
+      if (!TREE_TYPE (decl)
+	  || !POINTER_TYPE_P (TREE_TYPE (decl))
+	  || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (TREE_TYPE (decl))))
+	error ("invalid use of `__norestrict'");
+      else if (flag_strict_aliasing)
+        {
+          /* Unrestricted pointers can alias anything. */
+          DECL_POINTER_ALIAS_SET (decl) = 0;
+        }
     }
 }
 
diff -u -r gcc-orig/c-decl.c gcc/c-decl.c
- --- gcc-orig/c-decl.c	Mon Apr 12 10:05:29 1999
+++ gcc/c-decl.c	Sat Jul 17 14:17:25 1999
@@ -4383,6 +4383,7 @@
   int longlong = 0;
   int constp;
   int restrictp;
+  int norestrictp;
   int volatilep;
   int type_quals = TYPE_UNQUALIFIED;
   int inlinep;
@@ -4700,19 +4701,26 @@
      declaration contains the `const'.  */
   constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
   restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
+  norestrictp = (!! (specbits & 1 << (int) RID_NORESTRICT)
+                 + TYPE_NORESTRICT (type));
   volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
   inlinep = !! (specbits & (1 << (int) RID_INLINE));
   if (constp > 1)
     pedwarn ("duplicate `const'");
   if (restrictp > 1)
     pedwarn ("duplicate `restrict'");
+  if (norestrictp > 1)
+    pedwarn ("duplicate `__norestrict'");
   if (volatilep > 1)
     pedwarn ("duplicate `volatile'");
+  if (restrictp && norestrictp)
+    error ("Both `restrict' and `__norestrict' applied to same type");
   if (! flag_gen_aux_info && (TYPE_QUALS (type)))
     type = TYPE_MAIN_VARIANT (type);
   type_quals = ((constp ? TYPE_QUAL_CONST : 0)
 		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
- -		| (volatilep ? TYPE_QUAL_VOLATILE : 0));
+		| (volatilep ? TYPE_QUAL_VOLATILE : 0)
+                | (norestrictp ? TYPE_QUAL_NORESTRICT : 0));
 
   /* Warn if two storage classes are given. Default to `auto'.  */
 
@@ -5075,6 +5083,8 @@
 		    volatilep++;
 		  else if (qualifier == ridpointers[(int) RID_RESTRICT])
 		    restrictp++;
+                  else if (qualifier == ridpointers[(int) RID_NORESTRICT])
+                    norestrictp++;
 		  else if (!erred)
 		    {
 		      erred = 1;
@@ -5087,10 +5097,15 @@
 		pedwarn ("duplicate `volatile'");
 	      if (restrictp > 1)
 		pedwarn ("duplicate `restrict'");
+	      if (norestrictp > 1)
+		pedwarn ("duplicate `__norestrict'");
+              if (restrictp && norestrictp)
+                error ("`restrict' and `__norestrict' applied to same type");
 
 	      type_quals = ((constp ? TYPE_QUAL_CONST : 0)
 			    | (restrictp ? TYPE_QUAL_RESTRICT : 0)
- -			    | (volatilep ? TYPE_QUAL_VOLATILE : 0));
+			    | (volatilep ? TYPE_QUAL_VOLATILE : 0)
+                            | (norestrictp ? TYPE_QUAL_NORESTRICT : 0));
 	    }
 
 	  declarator = TREE_OPERAND (declarator, 0);

diff -u -r gcc-orig/c-lex.c gcc/c-lex.c
- --- gcc-orig/c-lex.c	Sat Mar 20 14:21:23 1999
+++ gcc/c-lex.c	Sat Jul 17 14:17:24 1999
@@ -257,6 +257,7 @@
   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
   ridpointers[(int) RID_CONST] = get_identifier ("const");
   ridpointers[(int) RID_RESTRICT] = get_identifier ("restrict");
+  ridpointers[(int) RID_NORESTRICT] = get_identifier ("norestrict");
   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
   ridpointers[(int) RID_STATIC] = get_identifier ("static");

diff -u -r gcc-orig/c-lex.h gcc/c-lex.h
- --- gcc-orig/c-lex.h	Thu Feb 18 15:38:39 1999
+++ gcc/c-lex.h	Sat Jul 17 14:17:24 1999
@@ -41,6 +41,7 @@
   RID_SIGNED,
   RID_CONST,
   RID_RESTRICT,
+  RID_NORESTRICT,
   RID_VOLATILE,
   RID_INLINE,
   RID_NOALIAS,

diff -u -r gcc-orig/c-parse.gperf gcc/c-parse.gperf
- --- gcc-orig/c-parse.gperf	Wed Mar 31 02:43:51 1999
+++ gcc/c-parse.gperf	Sat Jul 17 13:53:22 1999
@@ -33,6 +33,8 @@
 __iterator, SCSPEC, RID_ITERATOR
 __iterator__, SCSPEC, RID_ITERATOR
 __label__, LABEL, NORID
+__norestrict, TYPE_QUAL, RID_NORESTRICT
+__norestrict__, TYPE_QUAL, RID_NORESTRICT
 __real, REALPART, NORID
 __real__, REALPART, NORID
 __restrict, TYPE_QUAL, RID_RESTRICT

diff -u -r gcc-orig/c-parse.in gcc/c-parse.in
- --- gcc-orig/c-parse.in	Mon Apr 26 18:35:50 1999
+++ gcc/c-parse.in	Sat Jul 17 14:17:24 1999
@@ -116,7 +116,8 @@
    yylval contains an IDENTIFIER_NODE which indicates which one.  */
 %token TYPESPEC
 
- -/* Reserved words that qualify type: "const", "volatile", or "restrict".
+/* Reserved words that qualify type: "const", "volatile", "restrict",
+   or "__norestrict".
    yylval contains an IDENTIFIER_NODE which indicates which one.  */
 %token TYPE_QUAL
 
diff -u -r gcc-orig/tree.c gcc/tree.c
- --- gcc-orig/tree.c	Sat Apr 17 07:43:57 1999
+++ gcc/tree.c	Sat Jul 17 14:17:25 1999
@@ -3608,6 +3608,7 @@
   TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
   TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
   TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
+  TYPE_NORESTRICT (type) = (type_quals & TYPE_QUAL_NORESTRICT) != 0;
 }
 
 /* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for

diff -u -r gcc-orig/tree.h gcc/tree.h
- --- gcc-orig/tree.h	Sun May  2 13:43:32 1999
+++ gcc/tree.h	Sat Jul 17 14:17:26 1999
@@ -834,6 +834,9 @@
    the term.  */
 #define TYPE_RESTRICT(NODE) (TYPE_CHECK (NODE)->type.restrict_flag)
 
+/* Nonzero if type is `norestrict'-qualified. */
+#define TYPE_NORESTRICT(NODE) (TYPE_CHECK (NODE)->type.norestrict_flag)
+
 /* There is a TYPE_QUAL value for each type qualifier.  They can be
    combined by bitwise-or to form the complete set of qualifiers for a
    type.  */
@@ -842,12 +845,14 @@
 #define TYPE_QUAL_CONST    0x1
 #define TYPE_QUAL_VOLATILE 0x2
 #define TYPE_QUAL_RESTRICT 0x4
+#define TYPE_QUAL_NORESTRICT 0x8
 
 /* The set of type qualifiers for this type.  */
- -#define TYPE_QUALS(NODE)			\
- -  ((TYPE_READONLY(NODE) * TYPE_QUAL_CONST) |	\
- -   (TYPE_VOLATILE(NODE) * TYPE_QUAL_VOLATILE) |	\
- -   (TYPE_RESTRICT(NODE) * TYPE_QUAL_RESTRICT))
+#define TYPE_QUALS(NODE)			        \
+  ((TYPE_READONLY(NODE) * TYPE_QUAL_CONST) |	        \
+   (TYPE_VOLATILE(NODE) * TYPE_QUAL_VOLATILE) |	        \
+   (TYPE_RESTRICT(NODE) * TYPE_QUAL_RESTRICT) |         \
+   (TYPE_NORESTRICT(NODE) * TYPE_QUAL_NORESTRICT))
 
 /* These flags are available for each language front end to use internally.  */
 #define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type.lang_flag_0)
@@ -901,6 +906,7 @@
   unsigned transparent_union_flag : 1;
   unsigned packed_flag : 1;
   unsigned restrict_flag : 1;
+  unsigned norestrict_flag : 1;
 
   unsigned lang_flag_0 : 1;
   unsigned lang_flag_1 : 1;
@@ -909,7 +915,7 @@
   unsigned lang_flag_4 : 1;
   unsigned lang_flag_5 : 1;
   unsigned lang_flag_6 : 1;
- -  /* room for 3 more bits */
+  /* room for 2 more bits */
 
   unsigned int align;
   union tree_node *pointer_to;
------- End of forwarded message -------

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~1999-09-30 18:02 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-09-12  0:51 [dax@gurulabs.com: PATCH: `__norestrict' type qualifier (fwd)] Richard Stallman
1999-09-12 12:29 ` Jamie Lokier
1999-09-14  8:34   ` patl
1999-09-14  8:38     ` Jamie Lokier
1999-09-15  2:02       ` Jeffrey A Law
1999-09-30 18:02         ` Jeffrey A Law
1999-09-30 18:02       ` Jamie Lokier
1999-09-30 18:02     ` Patrick J. LoPresti
1999-09-30 18:02   ` Jamie Lokier
1999-09-30 18:02 ` Richard Stallman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).