[cfe-commits] r63248 - in /cfe/trunk: lib/AST/ExprConstant.cpp lib/CodeGen/CGExprConstant.cpp test/CodeGen/const-init.c

Daniel Dunbar daniel at zuster.org
Wed Jan 28 14:24:07 PST 2009


Author: ddunbar
Date: Wed Jan 28 16:24:07 2009
New Revision: 63248

URL: http://llvm.org/viewvc/llvm-project?rev=63248&view=rev
Log:
Implement basic _Complex integer constant folding.
 - Merged into single ComplexEvaluator, these share too much logic to
   be worth splitting for float/int (IMHO). Will split on request.

Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/test/CodeGen/const-init.c

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=63248&r1=63247&r2=63248&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Jan 28 16:24:07 2009
@@ -55,8 +55,7 @@
 static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
 static bool EvaluateInteger(const Expr *E, APSInt  &Result, EvalInfo &Info);
 static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
-static bool EvaluateComplexFloat(const Expr *E, APValue &Result, 
-                                 EvalInfo &Info);
+static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info);
 
 //===----------------------------------------------------------------------===//
 // Misc utilities
@@ -1228,16 +1227,16 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Complex Float Evaluation
+// Complex Evaluation (for float and integer)
 //===----------------------------------------------------------------------===//
 
 namespace {
-class VISIBILITY_HIDDEN ComplexFloatExprEvaluator
-  : public StmtVisitor<ComplexFloatExprEvaluator, APValue> {
+class VISIBILITY_HIDDEN ComplexExprEvaluator
+  : public StmtVisitor<ComplexExprEvaluator, APValue> {
   EvalInfo &Info;
   
 public:
-  ComplexFloatExprEvaluator(EvalInfo &info) : Info(info) {}
+  ComplexExprEvaluator(EvalInfo &info) : Info(info) {}
   
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
@@ -1250,12 +1249,28 @@
   APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
 
   APValue VisitImaginaryLiteral(ImaginaryLiteral *E) {
-    APFloat Result(0.0);
-    if (!EvaluateFloat(E->getSubExpr(), Result, Info))
-      return APValue();
+    Expr* SubExpr = E->getSubExpr();
+
+    if (SubExpr->getType()->isRealFloatingType()) {
+      APFloat Result(0.0);
+
+      if (!EvaluateFloat(SubExpr, Result, Info))
+        return APValue();
     
-    return APValue(APFloat(Result.getSemantics(), APFloat::fcZero), 
-                   Result);
+      return APValue(APFloat(Result.getSemantics(), APFloat::fcZero), 
+                     Result);
+    } else {
+      assert(SubExpr->getType()->isIntegerType() && 
+             "Unexpected imaginary literal.");
+
+      llvm::APSInt Result;
+      if (!EvaluateInteger(SubExpr, Result, Info))
+        return APValue();
+      
+      llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
+      Zero = 0;
+      return APValue(Zero, Result);
+    }
   }
 
   APValue VisitCastExpr(CastExpr *E) {
@@ -1269,6 +1284,15 @@
       
       return APValue(Result, 
                      APFloat(Result.getSemantics(), APFloat::fcZero));
+    } else if (SubExpr->getType()->isIntegerType()) {
+      APSInt Result;
+                     
+      if (!EvaluateInteger(SubExpr, Result, Info))
+        return APValue();
+      
+      llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
+      Zero = 0;
+      return APValue(Result, Zero);
     }
 
     // FIXME: Handle more casts.
@@ -1280,38 +1304,48 @@
 };
 } // end anonymous namespace
 
-static bool EvaluateComplexFloat(const Expr *E, APValue &Result, EvalInfo &Info)
+static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info)
 {
-  Result = ComplexFloatExprEvaluator(Info).Visit(const_cast<Expr*>(E));
-  if (Result.isComplexFloat())
-    assert(&Result.getComplexFloatReal().getSemantics() == 
-           &Result.getComplexFloatImag().getSemantics() && 
-           "Invalid complex evaluation.");
-  return Result.isComplexFloat();
+  Result = ComplexExprEvaluator(Info).Visit(const_cast<Expr*>(E));
+  assert((!Result.isComplexFloat() ||
+          (&Result.getComplexFloatReal().getSemantics() == 
+           &Result.getComplexFloatImag().getSemantics())) && 
+         "Invalid complex evaluation.");
+  return Result.isComplexFloat() || Result.isComplexInt();
 }
 
-APValue ComplexFloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
+APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
 {
   APValue Result, RHS;
   
-  if (!EvaluateComplexFloat(E->getLHS(), Result, Info))
+  if (!EvaluateComplex(E->getLHS(), Result, Info))
     return APValue();
   
-  if (!EvaluateComplexFloat(E->getRHS(), RHS, Info))
+  if (!EvaluateComplex(E->getRHS(), RHS, Info))
     return APValue();
-  
+
   switch (E->getOpcode()) {
   default: return APValue();
   case BinaryOperator::Add:
-    Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
-                                     APFloat::rmNearestTiesToEven);
-    Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
-                                     APFloat::rmNearestTiesToEven);
+    if (Result.isComplexFloat()) {
+      Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
+                                       APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
+                                       APFloat::rmNearestTiesToEven);
+    } else {
+      Result.getComplexIntReal() += RHS.getComplexIntReal();
+      Result.getComplexIntImag() += RHS.getComplexIntImag();
+    }
   case BinaryOperator::Sub:
-    Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
-                                          APFloat::rmNearestTiesToEven);
-    Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
-                                          APFloat::rmNearestTiesToEven);
+    if (Result.isComplexFloat()) {
+      Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
+                                            APFloat::rmNearestTiesToEven);
+      Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
+                                            APFloat::rmNearestTiesToEven);
+    } else {
+      Result.getComplexIntReal() -= RHS.getComplexIntReal();
+      Result.getComplexIntImag() -= RHS.getComplexIntImag();
+    }
   }
 
   return Result;
@@ -1346,10 +1380,10 @@
       return false;
     
     Result.Val = APValue(f);
-  } else if (getType()->isComplexType()) {
-    if (!EvaluateComplexFloat(this, Result.Val, Info))
+  } else if (getType()->isAnyComplexType()) {
+    if (!EvaluateComplex(this, Result.Val, Info))
       return false;
-  }  else
+  } else
     return false;
 
   return true;

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=63248&r1=63247&r2=63248&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Wed Jan 28 16:24:07 2009
@@ -597,7 +597,9 @@
     assert(!Result.HasSideEffects && 
            "Constant expr should not have any side effects!");
     switch (Result.Val.getKind()) {
-    default: assert(0 && "unhandled value kind!");
+    case APValue::Uninitialized:
+      assert(0 && "Constant expressions should be uninitialized.");
+      return llvm::UndefValue::get(getTypes().ConvertType(type));
     case APValue::LValue: {
       llvm::Constant *Offset = 
         llvm::ConstantInt::get(llvm::Type::Int64Ty, 
@@ -631,6 +633,14 @@
       }
       return C;
     }
+    case APValue::ComplexInt: {
+      llvm::Constant *Complex[2];
+      
+      Complex[0] = llvm::ConstantInt::get(Result.Val.getComplexIntReal());
+      Complex[1] = llvm::ConstantInt::get(Result.Val.getComplexIntImag());
+      
+      return llvm::ConstantStruct::get(Complex, 2);
+    }
     case APValue::Float:
       return llvm::ConstantFP::get(Result.Val.getFloat());
     case APValue::ComplexFloat: {

Modified: cfe/trunk/test/CodeGen/const-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/const-init.c?rev=63248&r1=63247&r2=63248&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/const-init.c (original)
+++ cfe/trunk/test/CodeGen/const-init.c Wed Jan 28 16:24:07 2009
@@ -21,3 +21,6 @@
 };
 
 int g0 = (int)(&(((union s2 *) 0)->f0.f0) - 0);
+
+_Complex int g1 = 1 + 10i;
+_Complex double g2 = 1.0 + 10.0i;





More information about the cfe-commits mailing list