[llvm-commits] [dragonegg] r169372 - in /dragonegg/trunk: include/dragonegg/Internals.h src/Convert.cpp

Duncan Sands baldrick at free.fr
Wed Dec 5 02:48:45 PST 2012


Author: baldrick
Date: Wed Dec  5 04:48:45 2012
New Revision: 169372

URL: http://llvm.org/viewvc/llvm-project?rev=169372&view=rev
Log:
Be more systematic about handling implicit GCC casts by introducing utilities
for this, replacing ad-hoc code, and using the utilities in a few places where
no trouble was ever seen but which look like the kind of places where GCC might
make use of implicit casts.

Modified:
    dragonegg/trunk/include/dragonegg/Internals.h
    dragonegg/trunk/src/Convert.cpp

Modified: dragonegg/trunk/include/dragonegg/Internals.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Internals.h?rev=169372&r1=169371&r2=169372&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Internals.h (original)
+++ dragonegg/trunk/include/dragonegg/Internals.h Wed Dec  5 04:48:45 2012
@@ -326,7 +326,10 @@
 
   /// CastToAnyType - Cast the specified value to the specified type regardless
   /// of the types involved. This is an inferred cast.
-  Value *CastToAnyType (Value *V, bool VSigned, Type *Ty, bool TySigned);
+  Value *CastToAnyType (Value *Src, bool SrcIsSigned,
+                        Type *DstTy, bool DstIsSigned);
+  Constant *CastToAnyType (Constant *Src, bool SrcIsSigned,
+                           Type *DstTy, bool DstIsSigned);
 
   /// CastFromSameSizeInteger - Cast an integer (or vector of integer) value to
   /// the given scalar (resp. vector of scalar) type of the same bitwidth.
@@ -507,6 +510,10 @@
   /// register type to an LLVM value.  Only creates code in the entry block.
   Value *EmitRegister(tree_node *reg);
 
+  /// EmitRegisterWithCast - Utility method that calls EmitRegister, then casts
+  /// the returned value to the given register type.
+  Value *EmitRegisterWithCast(tree_node *reg, tree_node *type);
+
   /// EmitReg_SSA_NAME - Return the defining value of the given SSA_NAME.
   /// Only creates code in the entry block.
   Value *EmitReg_SSA_NAME(tree_node *reg);
@@ -693,6 +700,10 @@
   /// to an LLVM constant.  Creates no code, only constants.
   Constant *EmitRegisterConstant(tree_node *reg);
 
+  /// EmitRegisterConstantWithCast - Utility that casts the value returned by
+  /// EmitRegisterConstant to the given register type.
+  Constant *EmitRegisterConstantWithCast(tree_node *reg, tree_node *type);
+
   /// EmitComplexRegisterConstant - Turn the given COMPLEX_CST into an LLVM
   /// constant of the corresponding register type.
   Constant *EmitComplexRegisterConstant(tree_node *reg);

Modified: dragonegg/trunk/src/Convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=169372&r1=169371&r2=169372&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Wed Dec  5 04:48:45 2012
@@ -1781,13 +1781,48 @@
 
 /// CastToAnyType - Cast the specified value to the specified type making no
 /// assumptions about the types of the arguments. This creates an inferred cast.
-Value *TreeToLLVM::CastToAnyType(Value *V, bool VisSigned,
+Value *TreeToLLVM::CastToAnyType(Value *Src, bool SrcIsSigned,
                                  Type* DestTy, bool DestIsSigned) {
-  Type *SrcTy = V->getType();
+  Type *SrcTy = Src->getType();
 
   // Eliminate useless casts of a type to itself.
   if (SrcTy == DestTy)
-    return V;
+    return Src;
+
+  // Check whether the cast needs to be done in two steps, for example a pointer
+  // to float cast requires converting the pointer to an integer before casting
+  // to the float.
+  if (!CastInst::isCastable(SrcTy, DestTy)) {
+    unsigned SrcBits = SrcTy->getScalarSizeInBits();
+    unsigned DestBits = DestTy->getScalarSizeInBits();
+    if (SrcBits && !isa<IntegerType>(SrcTy)) {
+      Type *IntTy = IntegerType::get(Context, SrcBits);
+      Src = Builder.CreateBitCast(Src, IntTy);
+      return CastToAnyType(Src, SrcIsSigned, DestTy, DestIsSigned);
+    }
+    if (DestBits && !isa<IntegerType>(DestTy)) {
+      Type *IntTy = IntegerType::get(Context, DestBits);
+      Src = CastToAnyType(Src, SrcIsSigned, IntTy, DestIsSigned);
+      return Builder.CreateBitCast(Src, DestTy);
+    }
+    llvm_unreachable("Unable to cast between these types!");
+  }
+
+  // The types are different so we must cast. Use getCastOpcode to create an
+  // inferred cast opcode.
+  Instruction::CastOps opc =
+    CastInst::getCastOpcode(Src, SrcIsSigned, DestTy, DestIsSigned);
+
+  // Generate the cast and return it.
+  return Builder.CreateCast(opc, Src, DestTy);
+}
+Constant *TreeToLLVM::CastToAnyType(Constant *Src, bool SrcIsSigned,
+                                    Type* DestTy, bool DestIsSigned) {
+  Type *SrcTy = Src->getType();
+
+  // Eliminate useless casts of a type to itself.
+  if (SrcTy == DestTy)
+    return Src;
 
   // Check whether the cast needs to be done in two steps, for example a pointer
   // to float cast requires converting the pointer to an integer before casting
@@ -1797,13 +1832,13 @@
     unsigned DestBits = DestTy->getScalarSizeInBits();
     if (SrcBits && !isa<IntegerType>(SrcTy)) {
       Type *IntTy = IntegerType::get(Context, SrcBits);
-      V = Builder.CreateBitCast(V, IntTy);
-      return CastToAnyType(V, VisSigned, DestTy, DestIsSigned);
+      Src = TheFolder->CreateBitCast(Src, IntTy);
+      return CastToAnyType(Src, SrcIsSigned, DestTy, DestIsSigned);
     }
     if (DestBits && !isa<IntegerType>(DestTy)) {
       Type *IntTy = IntegerType::get(Context, DestBits);
-      V = CastToAnyType(V, VisSigned, IntTy, DestIsSigned);
-      return Builder.CreateBitCast(V, DestTy);
+      Src = CastToAnyType(Src, SrcIsSigned, IntTy, DestIsSigned);
+      return TheFolder->CreateBitCast(Src, DestTy);
     }
     llvm_unreachable("Unable to cast between these types!");
   }
@@ -1811,10 +1846,10 @@
   // The types are different so we must cast. Use getCastOpcode to create an
   // inferred cast opcode.
   Instruction::CastOps opc =
-    CastInst::getCastOpcode(V, VisSigned, DestTy, DestIsSigned);
+    CastInst::getCastOpcode(Src, SrcIsSigned, DestTy, DestIsSigned);
 
   // Generate the cast and return it.
-  return Builder.CreateCast(opc, V, DestTy);
+  return TheFolder->CreateCast(opc, Src, DestTy);
 }
 
 /// CastFromSameSizeInteger - Cast an integer (or vector of integer) value to
@@ -6493,6 +6528,18 @@
   }
 }
 
+/// EmitRegisterConstantWithCast - Utility that casts the value returned by
+/// EmitRegisterConstant to the given register type.
+Constant *TreeToLLVM::EmitRegisterConstantWithCast(tree reg, tree type) {
+  Constant *C = EmitRegisterConstant(reg);
+  if (TREE_TYPE(reg) == type)
+    return C;
+  // For vector types, TYPE_UNSIGNED returns the unsignedness of the element.
+  bool SrcIsSigned = !TYPE_UNSIGNED(TREE_TYPE(reg));
+  bool DstIsSigned = !TYPE_UNSIGNED(type);
+  return CastToAnyType(C, SrcIsSigned, getRegType(type), DstIsSigned);
+}
+
 /// EncodeExpr - Write the given expression into Buffer as it would appear in
 /// memory on the target (the buffer is resized to contain exactly the bytes
 /// written).  Return the number of bytes written; this can also be obtained
@@ -6511,9 +6558,10 @@
 /// EmitComplexRegisterConstant - Turn the given COMPLEX_CST into an LLVM
 /// constant of the corresponding register type.
 Constant *TreeToLLVM::EmitComplexRegisterConstant(tree reg) {
+  tree elt_type = TREE_TYPE(TREE_TYPE(reg));
   Constant *Elts[2] = {
-    EmitRegisterConstant(TREE_REALPART(reg)),
-    EmitRegisterConstant(TREE_IMAGPART(reg))
+    EmitRegisterConstantWithCast(TREE_REALPART(reg), elt_type),
+    EmitRegisterConstantWithCast(TREE_IMAGPART(reg), elt_type)
   };
   return ConstantStruct::getAnon(Elts);
 }
@@ -6597,26 +6645,15 @@
     return getDefaultValue(getRegType(TREE_TYPE(reg)));
 
   // Convert the elements.
-  VectorType *ResTy = cast<VectorType>(getRegType(TREE_TYPE(reg)));
-  Type *ResEltTy = ResTy->getElementType();
   SmallVector<Constant*, 16> Elts;
-  bool DstIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_TYPE(reg)));
-  for (tree elt = TREE_VECTOR_CST_ELTS(reg); elt; elt = TREE_CHAIN(elt)) {
-    Constant *Elt = EmitRegisterConstant(TREE_VALUE(elt));
-    // Make any implicit type conversions explicit.
-    if (Elt->getType() != ResEltTy) {
-      bool SrcIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_VALUE(elt)));
-      Instruction::CastOps opcode =
-        CastInst::getCastOpcode(Elt, SrcIsSigned, ResEltTy, DstIsSigned);
-      Elt = TheFolder->CreateCast(opcode, Elt, ResEltTy);
-    }
-    Elts.push_back(Elt);
-  }
+  tree elt_type = TREE_TYPE(TREE_TYPE(reg));
+  for (tree elt = TREE_VECTOR_CST_ELTS(reg); elt; elt = TREE_CHAIN(elt))
+    Elts.push_back(EmitRegisterConstantWithCast(TREE_VALUE(elt), elt_type));
 
   // If there weren't enough elements then set the rest of the vector to the
   // default value.
   if (Elts.size() < TYPE_VECTOR_SUBPARTS(TREE_TYPE(reg))) {
-    Constant *Default = getDefaultValue(ResEltTy);
+    Constant *Default = getDefaultValue(getRegType(elt_type));
     Elts.append(TYPE_VECTOR_SUBPARTS(TREE_TYPE(reg)) - Elts.size(), Default);
   }
 
@@ -6669,6 +6706,18 @@
   return isa<SSA_NAME>(reg) ? EmitReg_SSA_NAME(reg) : EmitMinInvariant(reg);
 }
 
+/// EmitRegisterWithCast - Utility method that calls EmitRegister, then casts
+/// the returned value to the given register type.
+Value *TreeToLLVM::EmitRegisterWithCast(tree reg, tree type) {
+  Value *V = EmitRegister(reg);
+  if (TREE_TYPE(reg) == type)
+    return V;
+  // For vector types, TYPE_UNSIGNED returns the unsignedness of the element.
+  bool SrcIsSigned = !TYPE_UNSIGNED(TREE_TYPE(reg));
+  bool DstIsSigned = !TYPE_UNSIGNED(type);
+  return CastToAnyType(V, SrcIsSigned, getRegType(type), DstIsSigned);
+}
+
 /// EmitReg_SSA_NAME - Return the defining value of the given SSA_NAME.
 /// Only creates code in the entry block.
 Value *TreeToLLVM::EmitReg_SSA_NAME(tree reg) {
@@ -6811,8 +6860,7 @@
 }
 
 Value *TreeToLLVM::EmitReg_CONVERT_EXPR(tree type, tree op) {
-  return CastToAnyType(EmitRegister(op), !TYPE_UNSIGNED(TREE_TYPE(op)),
-                       getRegType(type), !TYPE_UNSIGNED(type));
+  return EmitRegisterWithCast(op, type);
 }
 
 Value *TreeToLLVM::EmitReg_NEGATE_EXPR(tree op) {
@@ -7819,13 +7867,8 @@
 }
 
 Value *TreeToLLVM::EmitReg_WIDEN_MULT_EXPR(tree type, tree op0, tree op1) {
-  Value *LHS = EmitRegister(op0);
-  Value *RHS = EmitRegister(op1);
-  Type *DestTy = getRegType(type);
-  LHS = CastToAnyType(LHS, !TYPE_UNSIGNED(TREE_TYPE(op0)), DestTy,
-                      !TYPE_UNSIGNED(type));
-  RHS = CastToAnyType(RHS, !TYPE_UNSIGNED(TREE_TYPE(op0)), DestTy,
-                      !TYPE_UNSIGNED(type));
+  Value *LHS = EmitRegisterWithCast(op0, type);
+  Value *RHS = EmitRegisterWithCast(op1, type);
   return Builder.CreateMul(LHS, RHS);
 }
 
@@ -8625,7 +8668,7 @@
 void TreeToLLVM::RenderGIMPLE_SWITCH(gimple stmt) {
   // Emit the condition.
   Value *Index = EmitRegister(gimple_switch_index(stmt));
-  bool IndexIsSigned = !TYPE_UNSIGNED(TREE_TYPE(gimple_switch_index(stmt)));
+  tree index_type = TREE_TYPE(gimple_switch_index(stmt));
 
   // Create the switch instruction.
   tree default_label = CASE_LABEL(gimple_switch_label(stmt, 0));
@@ -8639,9 +8682,7 @@
     BasicBlock *Dest = getLabelDeclBlock(CASE_LABEL(label));
 
     // Convert the integer to the right type.
-    Value *Val = EmitRegister(CASE_LOW(label));
-    Val = CastToAnyType(Val, !TYPE_UNSIGNED(TREE_TYPE(CASE_LOW(label))),
-                        Index->getType(), IndexIsSigned);
+    Value *Val = EmitRegisterWithCast(CASE_LOW(label), index_type);
     ConstantInt *LowC = cast<ConstantInt>(Val);
 
     if (!CASE_HIGH(label)) {
@@ -8650,10 +8691,8 @@
     }
 
     // Otherwise, we have a range, like 'case 1 ... 17'.
-    Val = EmitRegister(CASE_HIGH(label));
     // Make sure the case value is the same type as the switch expression
-    Val = CastToAnyType(Val, !TYPE_UNSIGNED(TREE_TYPE(CASE_HIGH(label))),
-                        Index->getType(), IndexIsSigned);
+    Val = EmitRegisterWithCast(CASE_HIGH(label), index_type);
     ConstantInt *HighC = cast<ConstantInt>(Val);
 
     APInt Range = HighC->getValue() - LowC->getValue();





More information about the llvm-commits mailing list