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]

Re: [PATCH] Optimize SELECT CASE for character length 1


Jakub Jelinek wrote:
> For character length 1, we can easily avoid calling the
> library function, instead a normal SWITCH_EXPR can be emitted.


+	      if (d->low->expr_type != EXPR_CONSTANT
+		  || d->low->ts.type != BT_CHARACTER)
+		break;

I wonder whether one shouldn't have a gcc_assert here.
Ditto for high. Reasoning as follows.

F2008 has for the case selectors:

R840 case-stmt  is  CASE case-selector [case-construct-name]
R843 case-selector  is  ( case-value-range-list )
                    or  DEFAULT
R844 case-value-range   is  case-value
                        or  case-value :
                        or  : case-value
                        or  case-value : case-value
R845 case-value  is  scalar-constant-expr

Thus, d->low/d->high shall be a constant expression (or NULL).


Regarding the type:

"C832 (R838) For a given case-construct, each case-value shall
 be of the same type as case-expr. For character type, the kind
 type parameters shall be the same; character length differences
 are allowed."

Also that the kind is the same is already checked at resolution
stage.


Regarding:

+	  if (d->low)
+	    {
[...]
+	      if (d->low->value.character.length > 1)
+		{
+		  for (i = 1; i < d->low->value.character.length; i++)
+		    if (d->low->value.character.string[i] != ' ')
+		      break;
+		  if (i != d->low->value.character.length)
+		    break;
+		}


Shouldn't this be
+                 if (i > 1)
+                   break;
rather than
+                 if (i != d->low->value.character.length)
+                   break;


If one wants, one could handle  case ("abc") and case ("aa":"az") special.
That is:

if (low && high
    && low->value.character.string[0] == high->value.character.string[0]
    && ((low->value.character.string[1] < ' '
         && high->value.character.string[1] < ' ')
        || (low->value.character.string[1] > ' '
            && high->value.character.string[1] > ' ')))
  continue;

In both loops as the value can never be matched by a single character.


--- gcc/testsuite/gfortran.dg/select_char_2.f90.jj	2010-07-14 22:01:24.000000000 +0200
+++ gcc/testsuite/gfortran.dg/select_char_2.f90	2010-07-14 22:00:23.000000000 +0200

Shouldn't this be a run test and have a tree-dump check that select case
is not done via a library call? Or at least the latter?

Otherwise, the patch looks okay.

Tobias


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