]> gcc.gnu.org Git - gcc.git/commitdiff
alias.c (find_base_term): Improve handling of addresses constructed from binary opera...
authorJeffrey A Law <law@cygnus.com>
Sun, 30 May 1999 23:51:39 +0000 (23:51 +0000)
committerJeff Law <law@gcc.gnu.org>
Sun, 30 May 1999 23:51:39 +0000 (17:51 -0600)
        * alias.c (find_base_term): Improve handling of addresses
        constructed from binary operations.

From-SVN: r27263

gcc/ChangeLog
gcc/alias.c

index d6af4427b50130e24834cac1670c831852260505..20ad9b64d37d0b79ba73bac62e127ee600da0860 100644 (file)
@@ -1,3 +1,8 @@
+Mon May 31 00:46:17 1999  Jeffrey A Law  (law@cygnus.com)
+
+       * alias.c (find_base_term): Improve handling of addresses
+       constructed from binary operations.
+
 Sun May 30 14:29:17 1999  Eric Raskin (ehr@listworks.com)
 
        * dgux.h (STARTFILE_SPEC): Fix incorrectly matched curly-braces.
index 3bfb44004861b12052792dca4ea41b622515ca07..9d8aac7832a481d6becc13c7509f788e2c98c0c4 100644 (file)
@@ -746,10 +746,55 @@ find_base_term (x)
     case PLUS:
     case MINUS:
       {
-       rtx tmp = find_base_term (XEXP (x, 0));
-       if (tmp)
-         return tmp;
-       return find_base_term (XEXP (x, 1));
+       rtx tmp1 = XEXP (x, 0);
+       rtx tmp2 = XEXP (x, 1);
+
+       /* This is a litle bit tricky since we have to determine which of
+          the two operands represents the real base address.  Otherwise this
+          routine may return the index register instead of the base register.
+
+          That may cause us to believe no aliasing was possible, when in
+          fact aliasing is possible.
+
+          We use a few simple tests to guess the base register.  Additional
+          tests can certainly be added.  For example, if one of the operands
+          is a shift or multiply, then it must be the index register and the
+          other operand is the base register.  */
+       
+       /* If either operand is known to be a pointer, then use it
+          to determine the base term.  */
+       if (REG_P (tmp1) && REGNO_POINTER_FLAG (REGNO (tmp1)))
+         return find_base_term (tmp1);
+
+       if (REG_P (tmp2) && REGNO_POINTER_FLAG (REGNO (tmp2)))
+         return find_base_term (tmp2);
+
+       /* Neither operand was known to be a pointer.  Go ahead and find the
+          base term for both operands.  */
+       tmp1 = find_base_term (tmp1);
+       tmp2 = find_base_term (tmp2);
+
+       /* If either base term is named object or a special address
+          (like an argument or stack reference), then use it for the
+          base term.  */
+       if (tmp1
+           && (GET_CODE (tmp1) == SYMBOL_REF
+               || GET_CODE (tmp1) == LABEL_REF
+               || (GET_CODE (tmp1) == ADDRESS
+                   && GET_MODE (tmp1) != VOIDmode)))
+         return tmp1;
+
+       if (tmp2
+           && (GET_CODE (tmp2) == SYMBOL_REF
+               || GET_CODE (tmp2) == LABEL_REF
+               || (GET_CODE (tmp2) == ADDRESS
+                   && GET_MODE (tmp2) != VOIDmode)))
+         return tmp2;
+
+       /* We could not determine which of the two operands was the
+          base register and which was the index.  So we can determine
+          nothing from the base alias check.  */
+       return 0;
       }
 
     case AND:
This page took 0.067671 seconds and 5 git commands to generate.