Просмотр исходного кода

Merge pull request #9170 from richardkchapman/max-zero

HPCC-16345 Optimize MAX(unsigned, 0) and IF(unsigned < 0, 0, unsigned)

Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
Gavin Halliday 8 лет назад
Родитель
Сommit
902447d8d2
3 измененных файлов с 67 добавлено и 1 удалено
  1. 1 0
      common/deftype/deftype.hpp
  2. 31 1
      ecl/hql/hqlfold.cpp
  3. 35 0
      ecl/regress/fold6.ecl

+ 1 - 0
common/deftype/deftype.hpp

@@ -206,6 +206,7 @@ public:
     virtual IHqlScope * castToScope() = 0;
 
     inline bool isBoolean() const { return getTypeCode() == type_boolean; }
+    inline bool isUnsignedNumeric() { return (isInteger() || getTypeCode()==type_decimal) && !isSigned(); }
 
 private:
     inline IValue * castFrom(__int64 value) { return NULL; }

+ 31 - 1
ecl/hql/hqlfold.cpp

@@ -442,7 +442,6 @@ static IHqlExpression * optimizeCompare(IHqlExpression * expr)
 
     if (op == no_order)
         return NULL;
-    //MORE: Optimize <unsigned> >=|< 0 and 0 >|<= <unsigned>
     
     bool swap = false;
     IHqlExpression * castChild = NULL;
@@ -450,6 +449,16 @@ static IHqlExpression * optimizeCompare(IHqlExpression * expr)
     if (leftValue)
     {
         ITypeInfo * rType = rightChild->queryType();
+        if (rType->isUnsignedNumeric() && isZero(leftChild))
+        {
+            switch (op)
+            {
+            case no_le:
+                return createConstant(true);
+            case no_gt:
+                return createConstant(false);
+            }
+        }
         if (rType->getTypeCode() == type_boolean)
         {
             bool val = leftValue->getBoolValue();
@@ -481,6 +490,16 @@ static IHqlExpression * optimizeCompare(IHqlExpression * expr)
     else if (rightValue)
     {
         ITypeInfo * lType = leftChild->queryType();
+        if (lType->isUnsignedNumeric() && isZero(rightChild))
+        {
+            switch (op)
+            {
+            case no_ge:
+                return createConstant(true);
+            case no_lt:
+                return createConstant(false);
+            }
+        }
         if (lType->getTypeCode() == type_boolean)
         {
             bool val = rightValue->getBoolValue();
@@ -3900,6 +3919,7 @@ IHqlExpression * foldConstantOperator(IHqlExpression * expr, unsigned foldOption
     case no_maxlist:
         {
             IHqlExpression * child = expr->queryChild(0);
+            bool isUnsigned = expr->queryType()->isUnsignedNumeric();
             switch (child->getOperator())
             {
             case no_null:
@@ -3916,6 +3936,16 @@ IHqlExpression * foldConstantOperator(IHqlExpression * expr, unsigned foldOption
                         IValue * value = cur->queryValue();
                         if (value)
                         {
+                            if (isUnsigned && isZero(cur))
+                            {
+                                if (op==no_minlist)
+                                    return LINK(cur);  // Nothing can be lower than zero in an unsigned minlist...
+                                else
+                                {
+                                    same = false;
+                                    continue;
+                                }
+                            }
                             if (best)
                             {
                                 int c = value->compare(best);

+ 35 - 0
ecl/regress/fold6.ecl

@@ -0,0 +1,35 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2016 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+// Test folding of comparisons of unsigned values against zero
+
+unsigned4 a := nofold(3); // : STORED('a');
+ASSERT(MAX(a, (unsigned4) 0) = a);
+ASSERT(a >= 0);
+ASSERT(0 <= a);
+
+BIG_ENDIAN unsigned4 ba := nofold(3); // : STORED('ba');
+
+ASSERT(MAX(ba, (BIG_ENDIAN unsigned4) 0) = ba);
+ASSERT(ba >= 0);
+ASSERT(0 <= ba);
+
+unsigned decimal4 da := nofold(3); // : STORED('da');
+
+ASSERT(MAX(da, (unsigned decimal4) 0) = da);
+ASSERT(da >= 0);
+ASSERT(0 <= da);