[cfe-commits] r41433 - in /cfe/trunk/CodeGen: CGExpr.cpp CGExprComplex.cpp CGExprScalar.cpp CodeGenFunction.h

Chris Lattner sabre at nondot.org
Sat Aug 25 23:48:56 PDT 2007


Author: lattner
Date: Sun Aug 26 01:48:56 2007
New Revision: 41433

URL: http://llvm.org/viewvc/llvm-project?rev=41433&view=rev
Log:
refactor scalar conversions out into CGExprScalar.cpp


Modified:
    cfe/trunk/CodeGen/CGExpr.cpp
    cfe/trunk/CodeGen/CGExprComplex.cpp
    cfe/trunk/CodeGen/CGExprScalar.cpp
    cfe/trunk/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=41433&r1=41432&r2=41433&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Sun Aug 26 01:48:56 2007
@@ -57,65 +57,9 @@
     if (DestBT->getKind() == BuiltinType::Bool)
       return RValue::get(ConvertScalarValueToBool(Val, ValTy));
   
-  // Handle pointer conversions next: pointers can only be converted to/from
-  // other pointers and integers.
-  if (isa<PointerType>(DstTy)) {
-    const llvm::Type *DestTy = ConvertType(DstTy);
-    
-    if (Val.getVal()->getType() == DestTy)
-      return Val;
-    
-    // The source value may be an integer, or a pointer.
-    assert(Val.isScalar() && "Can only convert from integer or pointer");
-    if (isa<llvm::PointerType>(Val.getVal()->getType()))
-      return RValue::get(Builder.CreateBitCast(Val.getVal(), DestTy, "conv"));
-    assert(ValTy->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
-    return RValue::get(Builder.CreateIntToPtr(Val.getVal(), DestTy, "conv"));
-  }
-  
-  if (isa<PointerType>(ValTy)) {
-    // Must be an ptr to int cast.
-    const llvm::Type *DestTy = ConvertType(DstTy);
-    assert(isa<llvm::IntegerType>(DestTy) && "not ptr->int?");
-    return RValue::get(Builder.CreateIntToPtr(Val.getVal(), DestTy, "conv"));
-  }
-  
-  // Finally, we have the arithmetic types: real int/float and complex
-  // int/float.  Handle real->real conversions first, they are the most
-  // common.
-  if (Val.isScalar() && DstTy->isRealType()) {
-    // We know that these are representable as scalars in LLVM, convert to LLVM
-    // types since they are easier to reason about.
-    llvm::Value *SrcVal = Val.getVal();
-    const llvm::Type *DestTy = ConvertType(DstTy);
-    if (SrcVal->getType() == DestTy) return Val;
-    
-    llvm::Value *Result;
-    if (isa<llvm::IntegerType>(SrcVal->getType())) {
-      bool InputSigned = ValTy->isSignedIntegerType();
-      if (isa<llvm::IntegerType>(DestTy))
-        Result = Builder.CreateIntCast(SrcVal, DestTy, InputSigned, "conv");
-      else if (InputSigned)
-        Result = Builder.CreateSIToFP(SrcVal, DestTy, "conv");
-      else
-        Result = Builder.CreateUIToFP(SrcVal, DestTy, "conv");
-    } else {
-      assert(SrcVal->getType()->isFloatingPoint() && "Unknown real conversion");
-      if (isa<llvm::IntegerType>(DestTy)) {
-        if (DstTy->isSignedIntegerType())
-          Result = Builder.CreateFPToSI(SrcVal, DestTy, "conv");
-        else
-          Result = Builder.CreateFPToUI(SrcVal, DestTy, "conv");
-      } else {
-        assert(DestTy->isFloatingPoint() && "Unknown real conversion");
-        if (DestTy->getTypeID() < SrcVal->getType()->getTypeID())
-          Result = Builder.CreateFPTrunc(SrcVal, DestTy, "conv");
-        else
-          Result = Builder.CreateFPExt(SrcVal, DestTy, "conv");
-      }
-    }
-    return RValue::get(Result);
-  }
+  if (Val.isScalar() && !hasAggregateLLVMType(DstTy))
+    return RValue::get(EmitScalarConversion(Val.getVal(), ValTy, DstTy));
+  
   
   assert(0 && "FIXME: We don't support complex conversions yet!");
 }

Modified: cfe/trunk/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprComplex.cpp?rev=41433&r1=41432&r2=41433&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/CodeGen/CGExprComplex.cpp Sun Aug 26 01:48:56 2007
@@ -203,10 +203,8 @@
     // rules for the corresponding real types.
     ComplexPairTy Res = Visit(Op);
     QualType SrcEltTy = CT->getElementType();
-    Res.first = CGF.EmitConversion(RValue::get(Res.first), SrcEltTy,
-                                   DestTy).getVal();
-    Res.second = CGF.EmitConversion(RValue::get(Res.second), SrcEltTy,
-                                    DestTy).getVal();
+    Res.first = CGF.EmitScalarConversion(Res.first, SrcEltTy, DestTy);
+    Res.second = CGF.EmitScalarConversion(Res.second, SrcEltTy, DestTy);
     return Res;
   }
   // C99 6.3.1.7: When a value of real type is converted to a complex type, the
@@ -216,7 +214,7 @@
   llvm::Value *Elt = CGF.EmitScalarExpr(Op);
 
   // Convert the input element to the element type of the complex.
-  Elt = CGF.EmitConversion(RValue::get(Elt), Op->getType(), DestTy).getVal();
+  Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
   
   // Return (realval, 0).
   return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));

Modified: cfe/trunk/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprScalar.cpp?rev=41433&r1=41432&r2=41433&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/CodeGen/CGExprScalar.cpp Sun Aug 26 01:48:56 2007
@@ -62,6 +62,12 @@
     return EmitLoadOfLValue(EmitLValue(E), E->getType());
   }
     
+  /// EmitScalarConversion - Emit a conversion from the specified type to the
+  /// specified destination type, both of which are LLVM scalar types.
+  llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
+                                    QualType DstTy);
+    
+    
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
   //===--------------------------------------------------------------------===//
@@ -237,6 +243,68 @@
 //                                Utilities
 //===----------------------------------------------------------------------===//
 
+/// EmitScalarConversion - Emit a conversion from the specified type to the
+/// specified destination type, both of which are LLVM scalar types.
+llvm::Value *ScalarExprEmitter::EmitScalarConversion(llvm::Value *Src, 
+                                                     QualType SrcType,
+                                                     QualType DstType) {
+  SrcType = SrcType.getCanonicalType();
+  DstType = DstType.getCanonicalType();
+  if (SrcType == DstType) return Src;
+
+  // Handle conversions to bool first, they are special: comparisons against 0.
+  if (const BuiltinType *DestBT = dyn_cast<BuiltinType>(DstType))
+    if (DestBT->getKind() == BuiltinType::Bool)
+      return CGF.ConvertScalarValueToBool(RValue::get(Src), SrcType);
+  
+  const llvm::Type *DstTy = ConvertType(DstType);
+
+  // Ignore conversions like int -> uint.
+  if (Src->getType() == DstTy)
+    return Src;
+
+  // Handle pointer conversions next: pointers can only be converted to/from
+  // other pointers and integers.
+  if (isa<PointerType>(DstType)) {
+    // The source value may be an integer, or a pointer.
+    if (isa<llvm::PointerType>(Src->getType()))
+      return Builder.CreateBitCast(Src, DstTy, "conv");
+    assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
+    return Builder.CreateIntToPtr(Src, DstTy, "conv");
+  }
+  
+  if (isa<PointerType>(SrcType)) {
+    // Must be an ptr to int cast.
+    assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
+    return Builder.CreateIntToPtr(Src, DstTy, "conv");
+  }
+  
+  // Finally, we have the arithmetic types: real int/float.
+  if (isa<llvm::IntegerType>(Src->getType())) {
+    bool InputSigned = SrcType->isSignedIntegerType();
+    if (isa<llvm::IntegerType>(DstTy))
+      return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
+    else if (InputSigned)
+      return Builder.CreateSIToFP(Src, DstTy, "conv");
+    else
+      return Builder.CreateUIToFP(Src, DstTy, "conv");
+  }
+  
+  assert(Src->getType()->isFloatingPoint() && "Unknown real conversion");
+  if (isa<llvm::IntegerType>(DstTy)) {
+    if (DstType->isSignedIntegerType())
+      return Builder.CreateFPToSI(Src, DstTy, "conv");
+    else
+      return Builder.CreateFPToUI(Src, DstTy, "conv");
+  }
+
+  assert(DstTy->isFloatingPoint() && "Unknown real conversion");
+  if (DstTy->getTypeID() < Src->getType()->getTypeID())
+    return Builder.CreateFPTrunc(Src, DstTy, "conv");
+  else
+    return Builder.CreateFPExt(Src, DstTy, "conv");
+}
+
 //===----------------------------------------------------------------------===//
 //                            Visitor Methods
 //===----------------------------------------------------------------------===//
@@ -295,11 +363,21 @@
 // have to handle a more broad range of conversions than explicit casts, as they
 // handle things like function to ptr-to-function decay etc.
 Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy) {
+  // Handle cases where the source is an LLVM Scalar type.
+  if (!CGF.hasAggregateLLVMType(E->getType())) {
+    Value *Src = Visit(const_cast<Expr*>(E));
+
+    // If the destination is void, just evaluate the source.
+    if (DestTy->isVoidType()) return 0;
+
+    // Use EmitScalarConversion to perform the conversion.
+    return EmitScalarConversion(Src, E->getType(), DestTy);
+  }
+  
   RValue Src = CGF.EmitAnyExpr(E);
   
   // If the destination is void, just evaluate the source.
-  if (DestTy->isVoidType())
-    return 0;
+  if (DestTy->isVoidType()) return 0;
   
   // FIXME: Refactor EmitConversion to not return an RValue.  Sink it into this
   // method.
@@ -742,3 +820,13 @@
   
   return ScalarExprEmitter(*this).Visit(const_cast<Expr*>(E));
 }
+
+/// EmitScalarConversion - Emit a conversion from the specified type to the
+/// specified destination type, both of which are LLVM scalar types.
+llvm::Value *CodeGenFunction::EmitScalarConversion(llvm::Value *Src, 
+                                                   QualType SrcTy,
+                                                   QualType DstTy) {
+  assert(!hasAggregateLLVMType(SrcTy) && !hasAggregateLLVMType(DstTy) &&
+         "Invalid scalar expression to emit");
+  return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy);
+}

Modified: cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenFunction.h?rev=41433&r1=41432&r2=41433&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/CodeGen/CodeGenFunction.h Sun Aug 26 01:48:56 2007
@@ -361,6 +361,12 @@
   /// LLVM scalar type, returning the result.
   llvm::Value *EmitScalarExpr(const Expr *E);
   
+  /// EmitScalarConversion - Emit a conversion from the specified type to the
+  /// specified destination type, both of which are LLVM scalar types.
+  llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
+                                    QualType DstTy);
+  
+  
   /// EmitAggExpr - Emit the computation of the specified expression of
   /// aggregate type.  The result is computed into DestPtr.  Note that if
   /// DestPtr is null, the value of the aggregate expression is not needed.





More information about the cfe-commits mailing list