[llvm-commits] [llvm-gcc-4.2] r71555 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h

Duncan Sands baldrick at free.fr
Tue May 12 07:54:10 PDT 2009


Author: baldrick
Date: Tue May 12 09:54:03 2009
New Revision: 71555

URL: http://llvm.org/viewvc/llvm-project?rev=71555&view=rev
Log:
Reapply r71425, tweaked to be more laid back about
how void* is converted to an LLVM type.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=71555&r1=71554&r2=71555&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue May 12 09:54:03 2009
@@ -930,6 +930,12 @@
 
   assert(((DestLoc && Result == 0) || DestLoc == 0) &&
          "Expected a scalar or aggregate but got the wrong thing!"); 
+  // Check that the type of the result matches that of the tree node.  If the
+  // result is not used then GCC sometimes sets the tree type to VOID_TYPE, so
+  // don't take VOID_TYPE too seriously here.
+  assert((Result == 0 || VOID_TYPE_P(TREE_TYPE(exp)) ||
+          Result->getType() == ConvertType(TREE_TYPE(exp))) &&
+          "Value has wrong type!");
   return Result;
 }
 
@@ -937,6 +943,8 @@
 /// the address of the result.
 LValue TreeToLLVM::EmitLV(tree exp) {
   // Needs to be in sync with EmitVIEW_CONVERT_EXPR.
+  LValue LV(0, 0);
+
   switch (TREE_CODE(exp)) {
   default:
     std::cerr << "Unhandled lvalue expression!\n";
@@ -947,44 +955,79 @@
   case VAR_DECL:
   case FUNCTION_DECL:
   case CONST_DECL:
-  case RESULT_DECL:   return EmitLV_DECL(exp);
+  case RESULT_DECL:
+    LV = EmitLV_DECL(exp);
+    break;
   case ARRAY_RANGE_REF:
-  case ARRAY_REF:     return EmitLV_ARRAY_REF(exp);
-  case COMPONENT_REF: return EmitLV_COMPONENT_REF(exp);
-  case BIT_FIELD_REF: return EmitLV_BIT_FIELD_REF(exp);
-  case REALPART_EXPR: return EmitLV_XXXXPART_EXPR(exp, 0);
-  case IMAGPART_EXPR: return EmitLV_XXXXPART_EXPR(exp, 1);
+  case ARRAY_REF:
+    LV = EmitLV_ARRAY_REF(exp);
+    break;
+  case COMPONENT_REF:
+    LV = EmitLV_COMPONENT_REF(exp);
+    break;
+  case BIT_FIELD_REF:
+    LV = EmitLV_BIT_FIELD_REF(exp);
+    break;
+  case REALPART_EXPR:
+    LV = EmitLV_XXXXPART_EXPR(exp, 0);
+    break;
+  case IMAGPART_EXPR:
+    LV = EmitLV_XXXXPART_EXPR(exp, 1);
+    break;
 
   // Constants.
   case LABEL_DECL: {
     Value *Ptr = TreeConstantToLLVM::EmitLV_LABEL_DECL(exp);
-    return LValue(Ptr, DECL_ALIGN(exp) / 8);
+    LV = LValue(Ptr, DECL_ALIGN(exp) / 8);
+    break;
   }
   case COMPLEX_CST: {
     Value *Ptr = TreeConstantToLLVM::EmitLV_COMPLEX_CST(exp);
-    return LValue(Ptr, TYPE_ALIGN(TREE_TYPE(exp)) / 8);
+    LV = LValue(Ptr, TYPE_ALIGN(TREE_TYPE(exp)) / 8);
+    break;
   }
   case STRING_CST: {
     Value *Ptr = TreeConstantToLLVM::EmitLV_STRING_CST(exp);
-    return LValue(Ptr, TYPE_ALIGN(TREE_TYPE(exp)) / 8);
+    LV = LValue(Ptr, TYPE_ALIGN(TREE_TYPE(exp)) / 8);
+    break;
   }
 
   // Type Conversion.
-  case VIEW_CONVERT_EXPR: return EmitLV_VIEW_CONVERT_EXPR(exp);
+  case VIEW_CONVERT_EXPR:
+    LV = EmitLV_VIEW_CONVERT_EXPR(exp);
+    break;
 
   // Exception Handling.
-  case EXC_PTR_EXPR:  return EmitLV_EXC_PTR_EXPR(exp);
-  case FILTER_EXPR:   return EmitLV_FILTER_EXPR(exp);
+  case EXC_PTR_EXPR:
+    LV = EmitLV_EXC_PTR_EXPR(exp);
+    break;
+  case FILTER_EXPR:
+    LV = EmitLV_FILTER_EXPR(exp);
+    break;
 
   // Trivial Cases.
   case WITH_SIZE_EXPR:
     // The address is the address of the operand.
-    return EmitLV(TREE_OPERAND(exp, 0));
+    LV = EmitLV(TREE_OPERAND(exp, 0));
+    break;
   case INDIRECT_REF:
     // The lvalue is just the address.
-    return LValue(Emit(TREE_OPERAND(exp, 0), 0),
-                  expr_align(exp) / 8);
+    LV = LValue(Emit(TREE_OPERAND(exp, 0), 0), expr_align(exp) / 8);
+    // Correct for implicit type conversion: INDIRECT_REF can be applied to a
+    // void*, resulting in a non-void type.
+    LV.Ptr = BitCastToType(LV.Ptr, ConvertType(TREE_TYPE(exp))->getPointerTo());
+    break;
   }
+
+  // Check that the type of the lvalue is indeed that of a pointer to the tree
+  // node.  This may not hold for bitfields because the type of a bitfield need
+  // not match the type of the value being loaded out of it.  Since LLVM has no
+  // void* type, don't insist that void* be converted to a specific LLVM type.
+  assert((LV.isBitfield() || VOID_TYPE_P(TREE_TYPE(exp)) ||
+          LV.Ptr->getType() == ConvertType(TREE_TYPE(exp))->getPointerTo()) &&
+         "LValue has wrong type!");
+
+  return LV;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1297,8 +1340,8 @@
              Emit(TYPE_SIZE_UNIT(type), 0), DestLoc.Alignment);
 }
 
-void TreeToLLVM::EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size, 
-                            unsigned Align) {
+Value *TreeToLLVM::EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size,
+                              unsigned Align) {
   const Type *SBP = PointerType::getUnqual(Type::Int8Ty);
   const Type *IntPtr = TD.getIntPtrType();
   Value *Ops[4] = {
@@ -1310,10 +1353,11 @@
 
   Builder.CreateCall(Intrinsic::getDeclaration(TheModule, Intrinsic::memcpy,
                                                &IntPtr, 1), Ops, Ops+4);
+  return Ops[0];
 }
 
-void TreeToLLVM::EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, 
-                             unsigned Align) {
+Value *TreeToLLVM::EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size,
+                               unsigned Align) {
   const Type *SBP = PointerType::getUnqual(Type::Int8Ty);
   const Type *IntPtr = TD.getIntPtrType();
   Value *Ops[4] = {
@@ -1325,10 +1369,11 @@
 
   Builder.CreateCall(Intrinsic::getDeclaration(TheModule, Intrinsic::memmove,
                                                &IntPtr, 1), Ops, Ops+4);
+  return Ops[0];
 }
 
-void TreeToLLVM::EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, 
-                            unsigned Align) {
+Value *TreeToLLVM::EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size,
+                              unsigned Align) {
   const Type *SBP = PointerType::getUnqual(Type::Int8Ty);
   const Type *IntPtr = TD.getIntPtrType();
   Value *Ops[4] = {
@@ -1340,6 +1385,7 @@
   
   Builder.CreateCall(Intrinsic::getDeclaration(TheModule, Intrinsic::memset,
                                                &IntPtr, 1), Ops, Ops+4);
+  return Ops[0];
 }
 
 
@@ -3125,22 +3171,18 @@
 
 Value *TreeToLLVM::EmitBIT_NOT_EXPR(tree exp) {
   Value *Op = Emit(TREE_OPERAND(exp, 0), 0);
-  if (isa<PointerType>(Op->getType())) {
+  const Type *Ty = Op->getType();
+  if (isa<PointerType>(Ty)) {
     assert (TREE_CODE(TREE_TYPE(exp)) == INTEGER_TYPE &&
             "Expected integer type here");
-    Op = CastToType(Instruction::PtrToInt, Op, TREE_TYPE(exp));
-  }
-
-  const Type *Ty = Op->getType();
-  if (Ty->isFloatingPoint() ||
-      (isa<VectorType>(Ty) && 
-       cast<VectorType>(Ty)->getElementType()->isFloatingPoint())) {
-    Ty = getSuitableBitCastIntType(Ty);
-    if (!Ty)
-      abort();
-    Op = BitCastToType(Op, Ty);
+    Ty = ConvertType(TREE_TYPE(exp));
+    Op = CastToType(Instruction::PtrToInt, Op, Ty);
+  } else if (Ty->isFloatingPoint() ||
+             (isa<VectorType>(Ty) &&
+              cast<VectorType>(Ty)->getElementType()->isFloatingPoint())) {
+    Op = BitCastToType(Op, getSuitableBitCastIntType(Ty));
   }
-  return Builder.CreateNot(Op, (Op->getName()+"not").c_str());
+  return BitCastToType(Builder.CreateNot(Op, (Op->getName()+"not").c_str()),Ty);
 }
 
 Value *TreeToLLVM::EmitTRUTH_NOT_EXPR(tree exp) {
@@ -3237,13 +3279,11 @@
        (isa<VectorType>(Ty) && 
         cast<VectorType>(Ty)->getElementType()->isFloatingPoint()))) {
     Ty = getSuitableBitCastIntType(Ty);
-    if (!Ty)
-      abort();
     LHS = BitCastToType(LHS, Ty);
     RHS = BitCastToType(RHS, Ty);
   }
 
-  Value * V = Builder.CreateBinOp((Instruction::BinaryOps)Opc, LHS, RHS);
+  Value *V = Builder.CreateBinOp((Instruction::BinaryOps)Opc, LHS, RHS);
   if (ResTy != Ty)
     V = BitCastToType(V, ResTy);
   return V;
@@ -4375,7 +4415,8 @@
                                                  Ty, 2),
     C, C + 3);
   if (isBool)
-    Result = Builder.CreateICmpEQ(Result, C[1]);
+    Result = CastToUIntType(Builder.CreateICmpEQ(Result, C[1]),
+                            ConvertType(boolean_type_node));
   else
     Result = Builder.CreateIntToPtr(Result, ResultTy);
   return Result;
@@ -4633,6 +4674,7 @@
     Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0);
     EmitBuiltinUnaryOp(Amt, Result, Intrinsic::cttz); 
     Result = Builder.CreateAdd(Result, ConstantInt::get(Result->getType(), 1));
+    Result = CastToUIntType(Result, ConvertType(TREE_TYPE(exp)));
     Value *Cond =
       Builder.CreateICmpEQ(Amt, Constant::getNullValue(Amt->getType()));
     Result = Builder.CreateSelect(Cond,
@@ -5063,7 +5105,7 @@
 }
 
 bool TreeToLLVM::EmitBuiltinUnaryOp(Value *InVal, Value *&Result,
-                                       Intrinsic::ID Id) {
+                                    Intrinsic::ID Id) {
   // The intrinsic might be overloaded in which case the argument is of
   // varying type. Make sure that we specify the actual type for "iAny" 
   // by passing it as the 3rd and 4th parameters. This isn't needed for
@@ -5191,11 +5233,9 @@
       return false;
   }
 
-  if (isMemMove)
-    EmitMemMove(DstV, SrcV, Len, std::min(SrcAlign, DstAlign));
-  else
+  Result = isMemMove ?
+    EmitMemMove(DstV, SrcV, Len, std::min(SrcAlign, DstAlign)) :
     EmitMemCpy(DstV, SrcV, Len, std::min(SrcAlign, DstAlign));
-  Result = DstV;
   return true;
 }
 
@@ -5223,8 +5263,7 @@
     if (!OptimizeIntoPlainBuiltIn(exp, Len, Size))
       return false;
   }
-  EmitMemSet(DstV, Val, Len, DstAlign);
-  Result = DstV;
+  Result = EmitMemSet(DstV, Val, Len, DstAlign);
   return true;
 }
 
@@ -6240,7 +6279,7 @@
     const Type *EltTy = ConvertType(TREE_TYPE(exp));
     FieldPtr = BitCastToType(FieldPtr, PointerType::getUnqual(EltTy));
   }
-  
+
   assert(BitStart == 0 &&
          "It's a bitfield reference or we didn't get to the field!");
   return LValue(FieldPtr, LVAlign);
@@ -7228,6 +7267,8 @@
 //===----------------------------------------------------------------------===//
 
 Constant *TreeConstantToLLVM::EmitLV(tree exp) {
+  Constant *LV;
+
   switch (TREE_CODE(exp)) {
   default: 
     debug_tree(exp); 
@@ -7235,16 +7276,29 @@
     abort();
   case FUNCTION_DECL:
   case CONST_DECL:
-  case VAR_DECL:      return EmitLV_Decl(exp);
-  case LABEL_DECL:    return EmitLV_LABEL_DECL(exp);
-  case COMPLEX_CST:   return EmitLV_COMPLEX_CST(exp);
-  case STRING_CST:    return EmitLV_STRING_CST(exp);
-  case COMPONENT_REF: return EmitLV_COMPONENT_REF(exp);
+  case VAR_DECL:
+    LV = EmitLV_Decl(exp);
+    break;
+  case LABEL_DECL:
+    LV = EmitLV_LABEL_DECL(exp);
+    break;
+  case COMPLEX_CST:
+    LV = EmitLV_COMPLEX_CST(exp);
+    break;
+  case STRING_CST:
+    LV = EmitLV_STRING_CST(exp);
+    break;
+  case COMPONENT_REF:
+    LV = EmitLV_COMPONENT_REF(exp);
+    break;
   case ARRAY_RANGE_REF:
-  case ARRAY_REF:     return EmitLV_ARRAY_REF(exp);
+  case ARRAY_REF:
+    LV = EmitLV_ARRAY_REF(exp);
+    break;
   case INDIRECT_REF:
     // The lvalue is just the address.
-    return Convert(TREE_OPERAND(exp, 0));
+    LV = Convert(TREE_OPERAND(exp, 0));
+    break;
   case COMPOUND_LITERAL_EXPR: // FIXME: not gimple - defined by C front-end
     /* This used to read 
        return EmitLV(COMPOUND_LITERAL_EXPR_DECL(exp));
@@ -7252,8 +7306,18 @@
        with casts or the like.  The following is equivalent with no checking
        (since we know TREE_CODE(exp) is COMPOUND_LITERAL_EXPR the checking 
        doesn't accomplish anything anyway). */
-    return EmitLV(DECL_EXPR_DECL (TREE_OPERAND (exp, 0)));
+    LV = EmitLV(DECL_EXPR_DECL (TREE_OPERAND (exp, 0)));
+    break;
   }
+
+  // Check that the type of the lvalue is indeed that of a pointer to the tree
+  // node.  Since LLVM has no void* type, don't insist that void* be converted
+  // to a specific LLVM type.
+  assert((VOID_TYPE_P(TREE_TYPE(exp)) ||
+          LV->getType() == ConvertType(TREE_TYPE(exp))->getPointerTo()) &&
+         "LValue of constant has wrong type!");
+
+  return LV;
 }
 
 Constant *TreeConstantToLLVM::EmitLV_Decl(tree exp) {
@@ -7283,8 +7347,13 @@
     if (tree ID = DECL_ASSEMBLER_NAME(exp))
       mark_referenced(ID);
   }
-  
-  return Val;
+
+  // The type of the global value output for exp need not match that of exp.
+  // For example if the global's initializer has a different type to the global
+  // itself (allowed in GCC but not in LLVM) then the global is changed to have
+  // the type of the initializer.  Correct for this now.
+  return TheFolder->CreateBitCast(Val,
+                                  ConvertType(TREE_TYPE(exp))->getPointerTo());
 }
 
 /// EmitLV_LABEL_DECL - Someone took the address of a label.
@@ -7385,18 +7454,6 @@
     if (!integer_zerop(LowerBound))
       Index = fold(build2(MINUS_EXPR, IndexType, Index, LowerBound));
     ArrayAddr = EmitLV(Array);
-    
-    // The GCC array expression value may not compile to an LLVM array type if
-    // (for example) the array value is an array of unions.  In this case, the
-    // array literal will turn into an LLVM constant struct, which has struct
-    // type.  Do a cast to the correct type just to be certain everything is
-    // kosher.
-    const PointerType *ResPTy = cast<PointerType>(ArrayAddr->getType());
-    if (!isa<llvm::ArrayType>(ResPTy->getElementType())) {
-      const Type *RealArrayTy = ConvertType(ArrayType);
-      ResPTy = PointerType::getUnqual(RealArrayTy);
-      ArrayAddr = TheFolder->CreateBitCast(ArrayAddr, ResPTy);
-    }    
   } else {
     ArrayAddr = Convert(Array);
   }

Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=71555&r1=71554&r2=71555&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Tue May 12 09:54:03 2009
@@ -430,10 +430,11 @@
   void EmitAggregateZero(MemRef DestLoc, tree_node *GCCType);
                          
   /// EmitMemCpy/EmitMemMove/EmitMemSet - Emit an llvm.memcpy/llvm.memmove or
-  /// llvm.memset call with the specified operands.
-  void EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
-  void EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
-  void EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);
+  /// llvm.memset call with the specified operands.  Returns DestPtr bitcast
+  /// to i8*.
+  Value *EmitMemCpy(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
+  Value *EmitMemMove(Value *DestPtr, Value *SrcPtr, Value *Size, unsigned Align);
+  Value *EmitMemSet(Value *DestPtr, Value *SrcVal, Value *Size, unsigned Align);
 
   /// EmitLandingPads - Emit EH landing pads.
   void EmitLandingPads();





More information about the llvm-commits mailing list