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

Duncan Sands baldrick at free.fr
Fri Apr 15 07:20:28 PDT 2011


Author: baldrick
Date: Fri Apr 15 09:20:27 2011
New Revision: 129566

URL: http://llvm.org/viewvc/llvm-project?rev=129566&view=rev
Log:
Baby steps towards the ultimate goal of completely divorcing the type used to
hold values in registers from the type used to hold values in memory.  This is
needed to support -m96bit-long-double for example, and in general seems like
The Right Thing To Do.  While there, add some initial support for vectors of
pointers (which the gcc vectorizer produces sometimes).

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

Modified: dragonegg/trunk/include/dragonegg/Constants.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Constants.h?rev=129566&r1=129565&r2=129566&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Constants.h (original)
+++ dragonegg/trunk/include/dragonegg/Constants.h Fri Apr 15 09:20:27 2011
@@ -49,12 +49,13 @@
 /// for the GCC type (see ConvertType); it is never smaller than the alloc size.
 extern llvm::Constant *ConvertInitializer(tree_node *exp);
 
-/// InterpretAsType - Interpret the bits of the given constant (starting from
-/// StartingBit) as representing a constant of type 'Ty'.  This results in the
-/// same constant as you would get by storing the bits of 'C' to memory (with
-/// the first bit stored being 'StartingBit') and then loading out a (constant)
-/// value of type 'Ty' from the stored to memory location.
-extern llvm::Constant *InterpretAsType(llvm::Constant *C, const llvm::Type* Ty,
-                                       int StartingBit);
+/// ExtractRegisterFromConstant - Extract a value of the given scalar GCC type
+/// from a constant.  The returned value is of in-register type, as returned by
+/// getRegType, and is what you would get by storing the constant to memory and
+/// using LoadRegisterFromMemory to load a register value back out starting from
+/// byte StartingByte.
+extern llvm::Constant *ExtractRegisterFromConstant(llvm::Constant *C,
+                                                   tree_node *type,
+                                                   int StartingByte = 0);
 
 #endif /* DRAGONEGG_CONSTANTS_H */

Modified: dragonegg/trunk/include/dragonegg/Internals.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Internals.h?rev=129566&r1=129565&r2=129566&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Internals.h (original)
+++ dragonegg/trunk/include/dragonegg/Internals.h Fri Apr 15 09:20:27 2011
@@ -236,6 +236,11 @@
 
 extern TypeConverter *TheTypeConverter;
 
+/// getRegType - Returns the LLVM type to use for registers that hold a value
+/// of the scalar GCC type 'type'.  All of the EmitReg* routines use this to
+/// determine the LLVM type to return.
+const Type *getRegType(tree_node *type);
+
 /// ConvertType - Returns the LLVM type to use for memory that holds a value
 /// of the given GCC type (getRegType should be used for values in registers).
 inline const Type *ConvertType(tree_node *type) {
@@ -649,11 +654,6 @@
 
   //===---------- EmitReg* - Convert register expression to LLVM ----------===//
 
-  /// getRegType - Returns the LLVM type to use for registers that hold a value
-  /// of the scalar GCC type 'type'.  All of the EmitReg* routines use this to
-  /// determine the LLVM type to return.
-  const Type *getRegType(tree_node *type);
-
   /// UselesslyTypeConvert - The useless_type_conversion_p predicate implicitly
   /// defines the GCC middle-end type system.  For scalar GCC types inner_type
   /// and outer_type, if 'useless_type_conversion_p(outer_type, inner_type)' is
@@ -783,9 +783,8 @@
   bool EmitBuiltinInitTrampoline(gimple_statement_d *stmt, Value *&Result);
 
   // Complex Math Expressions.
-  Value *CreateComplex(Value *Real, Value *Imag, tree_node *elt_type);
-  void SplitComplex(Value *Complex, Value *&Real, Value *&Imag,
-                    tree_node *elt_type);
+  Value *CreateComplex(Value *Real, Value *Imag);
+  void SplitComplex(Value *Complex, Value *&Real, Value *&Imag);
 
   // L-Value Expressions.
   LValue EmitLV_ARRAY_REF(tree_node *exp);
@@ -846,7 +845,6 @@
   /// this is mainly used for marshalling function parameters and return values,
   /// but that should be completely independent of the reg vs mem value logic.
   Value *Mem2Reg(Value *V, tree_node *type, LLVMBuilder &Builder);
-  Constant *Mem2Reg(Constant *C, tree_node *type, TargetFolder &Folder);
 
   /// Reg2Mem - Convert a value of in-register type (that given by getRegType)
   /// to in-memory type (that given by ConvertType).  TODO: Eliminate this

Modified: dragonegg/trunk/src/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Constants.cpp?rev=129566&r1=129565&r2=129566&view=diff
==============================================================================
--- dragonegg/trunk/src/Constants.cpp (original)
+++ dragonegg/trunk/src/Constants.cpp Fri Apr 15 09:20:27 2011
@@ -479,9 +479,88 @@
 
 
 //===----------------------------------------------------------------------===//
+//                    ... ExtractRegisterFromConstant ...
+//===----------------------------------------------------------------------===//
+
+/// ExtractRegisterFromConstant - Extract a value of the given scalar GCC type
+/// from a constant.  The returned value is of in-register type, as returned by
+/// getRegType, and is what you would get by storing the constant to memory and
+/// using LoadRegisterFromMemory to load a register value back out starting from
+/// byte StartingByte.
+Constant *ExtractRegisterFromConstant(Constant *C, tree type, int StartingByte) {
+  // NOTE: Needs to be kept in sync with getRegType.
+  int StartingBit = StartingByte * BITS_PER_UNIT;
+  switch (TREE_CODE(type)) {
+
+  default:
+    DieAbjectly("Unknown register type!", type);
+
+  case BOOLEAN_TYPE:
+  case ENUMERAL_TYPE:
+  case INTEGER_TYPE: {
+    // For integral types, extract an integer with size equal to the type size,
+    // then truncate down to the precision.  For example, when extracting a bool
+    // this probably first loads out an i8 or i32 which is then truncated to i1.
+    // This roundabout approach means we get the right result on both little and
+    // big endian machines.
+    uint64_t Size = getInt64(TYPE_SIZE(type), true);
+    const Type *MemTy = IntegerType::get(Context, Size);
+    C = InterpretAsType(C, MemTy, StartingBit);
+    return TheFolder->CreateTruncOrBitCast(C, getRegType(type));
+  }
+
+  case COMPLEX_TYPE: {
+    tree elt_type = TREE_TYPE (type);
+    unsigned Stride = GET_MODE_BITSIZE (TYPE_MODE (elt_type));
+    Constant *Vals[2] = {
+      ExtractRegisterFromConstant(C, elt_type, StartingBit),
+      ExtractRegisterFromConstant(C, elt_type, StartingBit + Stride)
+    };
+    return ConstantStruct::get(Context, Vals, 2, false);
+  }
+
+  case OFFSET_TYPE:
+  case POINTER_TYPE:
+  case REFERENCE_TYPE:
+    return InterpretAsType(C, getRegType(type), StartingBit);
+
+  case REAL_TYPE:
+    // NOTE: This might be wrong for floats with precision less than their alloc
+    // size on big-endian machines.
+    return InterpretAsType(C, getRegType(type), StartingBit);
+
+  case VECTOR_TYPE: {
+    tree elt_type = TREE_TYPE (type);
+    unsigned NumElts = TYPE_VECTOR_SUBPARTS(type);
+    unsigned Stride = GET_MODE_BITSIZE (TYPE_MODE (elt_type));
+    SmallVector<Constant*, 16> Vals(NumElts);
+    for (unsigned i = 0; i != NumElts; ++i) {
+      Vals[i] = ExtractRegisterFromConstant(C, elt_type, StartingBit+i*Stride);
+      // LLVM does not support vectors of pointers, so turn any pointers into
+      // integers.
+      if (isa<PointerType>(Vals[i]->getType())) {
+        const IntegerType *IntTy = getTargetData().getIntPtrType(Context);
+        Vals[i] = TheFolder->CreatePtrToInt(Vals[i], IntTy);
+      }
+    }
+    return ConstantVector::get(Vals);
+  }
+
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
 //                       ... ConvertInitializer ...
 //===----------------------------------------------------------------------===//
 
+/// getAsRegister - Turn the given GCC scalar constant into an LLVM constant of
+/// register type.
+static Constant *getAsRegister(tree exp) {
+  Constant *C = ConvertInitializer(exp);
+  return ExtractRegisterFromConstant(C, TREE_TYPE(exp));
+}
+
 /// ConvertInitializerWithCast - Convert the initial value for a global variable
 /// to an equivalent LLVM constant then cast to the given type if both the type
 /// and the initializer are scalar.  This is convenient for making explicit the
@@ -1161,16 +1240,6 @@
 //                            ... AddressOf ...
 //===----------------------------------------------------------------------===//
 
-/// getAsInteger - Given a constant of integer type, return its value as an LLVM
-/// integer constant.
-static Constant *getAsInteger(tree exp) {
-  tree type = TREE_TYPE(exp);
-  assert(INTEGRAL_TYPE_P(type) && "Constant does not have integer type!");
-  Constant *C = ConvertInitializer(exp);
-  const Type *IntTy = IntegerType::get(Context, TYPE_PRECISION(type));
-  return InterpretAsType(C, IntTy, 0);
-}
-
 /// AddressOfCST - Return the address of a simple constant, eg a of number.
 static Constant *AddressOfCST(tree exp) {
   Constant *Init = ConvertInitializer(exp);
@@ -1206,13 +1275,13 @@
          "Global with variable size?");
 
   // Get the index into the array as an LLVM integer constant.
-  Constant *IndexVal = getAsInteger(index);
+  Constant *IndexVal = getAsRegister(index);
 
   // Subtract off the lower bound, if any.
   tree lower_bound = array_ref_low_bound(exp);
   if (!integer_zerop(lower_bound)) {
     // Get the lower bound as an LLVM integer constant.
-    Constant *LowerBoundVal = getAsInteger(lower_bound);
+    Constant *LowerBoundVal = getAsRegister(lower_bound);
     IndexVal = TheFolder->CreateSub(IndexVal, LowerBoundVal, hasNUW(index_type),
                                     hasNSW(index_type));
   }
@@ -1235,7 +1304,7 @@
   // Compute the field offset in units from the start of the record.
   Constant *Offset;
   if (TREE_OPERAND(exp, 2)) {
-    Offset = getAsInteger(TREE_OPERAND(exp, 2));
+    Offset = getAsRegister(TREE_OPERAND(exp, 2));
     // At this point the offset is measured in units divided by (exactly)
     // (DECL_OFFSET_ALIGN / BITS_PER_UNIT).  Convert to units.
     unsigned factor = DECL_OFFSET_ALIGN(field_decl) / BITS_PER_UNIT;
@@ -1245,7 +1314,7 @@
                                                      factor));
   } else {
     assert(DECL_FIELD_OFFSET(field_decl) && "Field offset not available!");
-    Offset = getAsInteger(DECL_FIELD_OFFSET(field_decl));
+    Offset = getAsRegister(DECL_FIELD_OFFSET(field_decl));
   }
 
   // Here BitStart gives the offset of the field in bits from Offset.

Modified: dragonegg/trunk/src/Convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=129566&r1=129565&r2=129566&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Fri Apr 15 09:20:27 2011
@@ -5316,10 +5316,8 @@
 //                      ... Complex Math Expressions ...
 //===----------------------------------------------------------------------===//
 
-Value *TreeToLLVM::CreateComplex(Value *Real, Value *Imag, tree elt_type) {
+Value *TreeToLLVM::CreateComplex(Value *Real, Value *Imag) {
   assert(Real->getType() == Imag->getType() && "Component type mismatch!");
-  Real = Reg2Mem(Real, elt_type, Builder);
-  Imag = Reg2Mem(Imag, elt_type, Builder);
   const Type *EltTy = Real->getType();
   Value *Result = UndefValue::get(StructType::get(Context, EltTy, EltTy, NULL));
   Result = Builder.CreateInsertValue(Result, Real, 0);
@@ -5327,10 +5325,9 @@
   return Result;
 }
 
-void TreeToLLVM::SplitComplex(Value *Complex, Value *&Real, Value *&Imag,
-                              tree elt_type) {
-  Real = Mem2Reg(Builder.CreateExtractValue(Complex, 0), elt_type, Builder);
-  Imag = Mem2Reg(Builder.CreateExtractValue(Complex, 1), elt_type, Builder);
+void TreeToLLVM::SplitComplex(Value *Complex, Value *&Real, Value *&Imag) {
+  Real = Builder.CreateExtractValue(Complex, 0);
+  Imag = Builder.CreateExtractValue(Complex, 1);
 }
 
 
@@ -6034,18 +6031,8 @@
 Constant *TreeToLLVM::EmitConstantVectorConstructor(tree reg) {
   // Get the constructor as an LLVM constant.
   Constant *C = ConvertInitializer(reg);
-  // The constant may have pretty much any type, for example it could be a bunch
-  // of bytes.  Extract the vector elements from the constant.
-  tree elt_type = TREE_TYPE (TREE_TYPE (reg));
-  const Type *EltTy = getRegType(elt_type);
-  unsigned NumElts = TYPE_VECTOR_SUBPARTS(TREE_TYPE(reg));
-  // Get the spacing between consecutive vector elements.  Obtain this from the
-  // GCC type in case the LLVM type is something funky like i1.
-  unsigned Stride = GET_MODE_BITSIZE (TYPE_MODE (elt_type));
-  SmallVector<Constant*, 16> Vals(NumElts);
-  for (unsigned i = 0; i != NumElts; ++i)
-    Vals[i] = InterpretAsType(C, EltTy, i*Stride);
-  return ConstantVector::get(Vals);
+  // Load the vector register out of it.
+  return ExtractRegisterFromConstant(C, TREE_TYPE(reg));
 }
 
 /// EmitVectorRegisterConstant - Turn the given VECTOR_CST into an LLVM constant
@@ -6081,21 +6068,36 @@
   if (MemTy == RegTy)
     return V;
 
-  assert(RegTy->isIntegerTy() && MemTy->isIntegerTy() &&
-         "Unexpected type mismatch!");
-  return Builder.CreateIntCast(V, RegTy, /*isSigned*/!TYPE_UNSIGNED(type));
-}
-Constant *TreeToLLVM::Mem2Reg(Constant *C, tree type, TargetFolder &Folder) {
-  const Type *MemTy = C->getType();
-  const Type *RegTy = getRegType(type);
-  assert(MemTy == ConvertType(type) && "Not of memory type!");
-
-  if (MemTy == RegTy)
-    return C;
+  if (RegTy->isIntegerTy()) {
+    assert(MemTy->isIntegerTy() && "Type mismatch!");
+    return Builder.CreateIntCast(V, RegTy, /*isSigned*/!TYPE_UNSIGNED(type));
+  }
+
+  if (RegTy->isStructTy()) {
+    assert(TREE_CODE(type) == COMPLEX_TYPE && "Expected a complex type!");
+    assert(MemTy->isStructTy() && "Type mismatch!");
+    Value *RealPart = Builder.CreateExtractValue(V, 0);
+    RealPart = Mem2Reg(RealPart, TREE_TYPE(type), Builder);
+    Value *ImagPart = Builder.CreateExtractValue(V, 1);
+    ImagPart = Mem2Reg(ImagPart, TREE_TYPE(type), Builder);
+    return CreateComplex(RealPart, ImagPart);
+  }
+
+  if (RegTy->isVectorTy()) {
+    assert(TREE_CODE(type) == VECTOR_TYPE && "Expected a vector type!");
+    assert(MemTy->isVectorTy() && "Type mismatch!");
+    Value *V = UndefValue::get(RegTy);
+    unsigned NumElts = TYPE_VECTOR_SUBPARTS(type);
+    for (unsigned i = 0; i != NumElts; ++i) {
+      Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), i);
+      Value *Val = Builder.CreateExtractElement(V, Idx);
+      Val = Mem2Reg(Val, TREE_TYPE(type), Builder);
+      V = Builder.CreateInsertElement(V, Val, Idx);
+    }
+    return V;
+  }
 
-  assert(RegTy->isIntegerTy() && MemTy->isIntegerTy() &&
-         "Unexpected type mismatch!");
-  return Folder.CreateIntCast(C, RegTy, /*isSigned*/!TYPE_UNSIGNED(type));
+  DieAbjectly("Don't know how to turn this into a register!", type);
 }
 
 /// Reg2Mem - Convert a value of in-register type (that given by getRegType)
@@ -6108,9 +6110,39 @@
   if (RegTy == MemTy)
     return V;
 
-  assert(RegTy->isIntegerTy() && MemTy->isIntegerTy() &&
-         "Unexpected type mismatch!");
-  return Builder.CreateIntCast(V, MemTy, /*isSigned*/!TYPE_UNSIGNED(type));
+  if (MemTy->isIntegerTy()) {
+    assert(RegTy->isIntegerTy() && "Type mismatch!");
+    return Builder.CreateIntCast(V, MemTy, /*isSigned*/!TYPE_UNSIGNED(type));
+  }
+
+  if (MemTy->isStructTy()) {
+    assert(TREE_CODE(type) == COMPLEX_TYPE && "Expected a complex type!");
+    assert(RegTy->isStructTy() && "Type mismatch!");
+    Value *RealPart, *ImagPart;
+    SplitComplex(V, RealPart, ImagPart);
+    RealPart = Reg2Mem(RealPart, TREE_TYPE(type), Builder);
+    ImagPart = Reg2Mem(ImagPart, TREE_TYPE(type), Builder);
+    Value *Z = UndefValue::get(MemTy);
+    Z = Builder.CreateInsertValue(Z, RealPart, 0);
+    Z = Builder.CreateInsertValue(Z, ImagPart, 1);
+    return Z;
+  }
+
+  if (MemTy->isVectorTy()) {
+    assert(TREE_CODE(type) == VECTOR_TYPE && "Expected a vector type!");
+    assert(RegTy->isVectorTy() && "Type mismatch!");
+    Value *V = UndefValue::get(MemTy);
+    unsigned NumElts = TYPE_VECTOR_SUBPARTS(type);
+    for (unsigned i = 0; i != NumElts; ++i) {
+      Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), i);
+      Value *Val = Builder.CreateExtractElement(V, Idx);
+      Val = Reg2Mem(Val, TREE_TYPE(type), Builder);
+      V = Builder.CreateInsertElement(V, Val, Idx);
+    }
+    return V;
+  }
+
+  DieAbjectly("Don't know how to turn this into memory!", type);
 }
 
 /// LoadRegisterFromMemory - Loads a value of the given scalar GCC type from
@@ -6119,6 +6151,7 @@
 /// is of in-register type, as returned by getRegType).
 Value *TreeToLLVM::LoadRegisterFromMemory(MemRef Loc, tree type,
                                           LLVMBuilder &Builder) {
+  // NOTE: Needs to be kept in sync with getRegType.
   const Type *MemTy = ConvertType(type);
   Value *Ptr = Builder.CreateBitCast(Loc.Ptr, MemTy->getPointerTo());
   LoadInst *LI = Builder.CreateLoad(Ptr, Loc.Volatile);
@@ -6131,6 +6164,7 @@
 /// (which is the in-register type given by getRegType) and the in-memory type.
 void TreeToLLVM::StoreRegisterToMemory(Value *V, MemRef Loc, tree type,
                                        LLVMBuilder &Builder) {
+  // NOTE: Needs to be kept in sync with getRegType.
   const Type *MemTy = ConvertType(type);
   Value *Ptr = Builder.CreateBitCast(Loc.Ptr, MemTy->getPointerTo());
   StoreInst *SI = Builder.CreateStore(Reg2Mem(V, type, Builder), Ptr,
@@ -6248,12 +6282,12 @@
 Value *TreeToLLVM::EmitReg_CONJ_EXPR(tree op) {
   tree elt_type = TREE_TYPE(TREE_TYPE(op));
   Value *R, *I;
-  SplitComplex(EmitRegister(op), R, I, elt_type);
+  SplitComplex(EmitRegister(op), R, I);
 
   // ~(a+ib) = a + i*-b
   I = CreateAnyNeg(I, elt_type);
 
-  return CreateComplex(R, I, elt_type);
+  return CreateComplex(R, I);
 }
 
 Value *TreeToLLVM::EmitReg_CONVERT_EXPR(tree type, tree op) {
@@ -6267,13 +6301,13 @@
 
   if (TREE_CODE(type) == COMPLEX_TYPE) {
     tree elt_type = TREE_TYPE(type);
-    Value *R, *I; SplitComplex(V, R, I, elt_type);
+    Value *R, *I; SplitComplex(V, R, I);
 
     // -(a+ib) = -a + i*-b
     R = CreateAnyNeg(R, elt_type);
     I = CreateAnyNeg(I, elt_type);
 
-    return CreateComplex(R, I, elt_type);
+    return CreateComplex(R, I);
   }
 
   return CreateAnyNeg(V, type);
@@ -6349,9 +6383,9 @@
 
   if (TREE_CODE(TREE_TYPE(lhs)) == COMPLEX_TYPE) {
     Value *LHSr, *LHSi;
-    SplitComplex(LHS, LHSr, LHSi, TREE_TYPE(TREE_TYPE(lhs)));
+    SplitComplex(LHS, LHSr, LHSi);
     Value *RHSr, *RHSi;
-    SplitComplex(RHS, RHSr, RHSi, TREE_TYPE(TREE_TYPE(lhs)));
+    SplitComplex(RHS, RHSr, RHSi);
 
     Value *DSTr, *DSTi;
     if (LHSr->getType()->isFloatingPointTy()) {
@@ -6539,7 +6573,7 @@
 }
 
 Value *TreeToLLVM::EmitReg_COMPLEX_EXPR(tree op0, tree op1) {
-    return CreateComplex(EmitRegister(op0), EmitRegister(op1), TREE_TYPE(op1));
+  return CreateComplex(EmitRegister(op0), EmitRegister(op1));
 }
 
 Value *TreeToLLVM::EmitReg_FLOOR_DIV_EXPR(tree type, tree op0, tree op1) {
@@ -6631,14 +6665,14 @@
 
   if (TREE_CODE(type) == COMPLEX_TYPE) {
     tree elt_type = TREE_TYPE(type);
-    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi, elt_type);
-    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi, elt_type);
+    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi);
+    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi);
 
     // (a+ib) - (c+id) = (a-c) + i(b-d)
     LHSr = CreateAnySub(LHSr, RHSr, elt_type);
     LHSi = CreateAnySub(LHSi, RHSi, elt_type);
 
-    return CreateComplex(LHSr, LHSi, elt_type);
+    return CreateComplex(LHSr, LHSi);
   }
 
   return CreateAnySub(LHS, RHS, type);
@@ -6651,8 +6685,8 @@
 
   if (TREE_CODE(type) == COMPLEX_TYPE) {
     tree elt_type = TREE_TYPE(type);
-    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi, elt_type);
-    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi, elt_type);
+    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi);
+    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi);
     Value *DSTr, *DSTi;
 
     // (a+ib) * (c+id) = (ac-bd) + i(ad+cb)
@@ -6678,7 +6712,7 @@
       DSTi = Builder.CreateAdd(Tmp3, Tmp4);        // ad+cb
     }
 
-    return CreateComplex(DSTr, DSTi, elt_type);
+    return CreateComplex(DSTr, DSTi);
   }
 
   return CreateAnyMul(LHS, RHS, type);
@@ -6691,14 +6725,14 @@
 
   if (TREE_CODE(type) == COMPLEX_TYPE) {
     tree elt_type = TREE_TYPE(type);
-    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi, elt_type);
-    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi, elt_type);
+    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi);
+    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi);
 
     // (a+ib) + (c+id) = (a+c) + i(b+d)
     LHSr = CreateAnyAdd(LHSr, RHSr, elt_type);
     LHSi = CreateAnyAdd(LHSi, RHSi, elt_type);
 
-    return CreateComplex(LHSr, LHSi, elt_type);
+    return CreateComplex(LHSr, LHSi);
   }
 
   return CreateAnyAdd(LHS, RHS, type);
@@ -6724,8 +6758,8 @@
 
   if (TREE_CODE(type) == COMPLEX_TYPE) {
     tree elt_type = TREE_TYPE(type);
-    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi, elt_type);
-    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi, elt_type);
+    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi);
+    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi);
     Value *DSTr, *DSTi;
 
     // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
@@ -6744,7 +6778,7 @@
     Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8); // bc-ad
     DSTi = Builder.CreateFDiv(Tmp9, Tmp6);
 
-    return CreateComplex(DSTr, DSTi, elt_type);
+    return CreateComplex(DSTr, DSTi);
   }
 
   assert(FLOAT_TYPE_P(type) && "RDIV_EXPR not floating point!");
@@ -6843,8 +6877,8 @@
 
   if (TREE_CODE(type) == COMPLEX_TYPE) {
     tree elt_type = TREE_TYPE(type);
-    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi, elt_type);
-    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi, elt_type);
+    Value *LHSr, *LHSi; SplitComplex(LHS, LHSr, LHSi);
+    Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi);
     Value *DSTr, *DSTi;
 
     // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
@@ -6869,7 +6903,7 @@
     DSTi = TYPE_UNSIGNED(elt_type) ?
       Builder.CreateUDiv(Tmp9, Tmp6) : Builder.CreateSDiv(Tmp9, Tmp6);
 
-    return CreateComplex(DSTr, DSTi, elt_type);
+    return CreateComplex(DSTr, DSTi);
   }
 
   assert(LHS->getType()->isIntOrIntVectorTy() && "TRUNC_DIV_EXPR not integer!");

Modified: dragonegg/trunk/src/Types.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Types.cpp?rev=129566&r1=129565&r2=129566&view=diff
==============================================================================
--- dragonegg/trunk/src/Types.cpp (original)
+++ dragonegg/trunk/src/Types.cpp Fri Apr 15 09:20:27 2011
@@ -651,17 +651,64 @@
 /// getRegType - Returns the LLVM type to use for registers that hold a value
 /// of the scalar GCC type 'type'.  All of the EmitReg* routines use this to
 /// determine the LLVM type to return.
-const Type *TreeToLLVM::getRegType(tree type) {
+const Type *getRegType(tree type) {
+  // NOTE: Any changes made here need to be reflected in LoadRegisterFromMemory,
+  // StoreRegisterToMemory and ExtractRegisterFromConstant.
   assert(!AGGREGATE_TYPE_P(type) && "Registers must have a scalar type!");
   assert(TREE_CODE(type) != VOID_TYPE && "Registers cannot have void type!");
 
-  // For integral types, convert based on the type precision.
-  if (TREE_CODE(type) == BOOLEAN_TYPE || TREE_CODE(type) == ENUMERAL_TYPE ||
-      TREE_CODE(type) == INTEGER_TYPE)
+  switch (TREE_CODE(type)) {
+
+  default:
+    DieAbjectly("Unknown register type!", type);
+
+  case BOOLEAN_TYPE:
+  case ENUMERAL_TYPE:
+  case INTEGER_TYPE:
+    // For integral types, convert based on the type precision.  For example,
+    // this turns bool into i1 while ConvertType probably turns it into i8 or
+    // i32.
     return IntegerType::get(Context, TYPE_PRECISION(type));
 
-  // Otherwise, return the type used to represent memory.
-  return ConvertType(type);
+  case COMPLEX_TYPE: {
+    const Type *EltTy = getRegType(TREE_TYPE(type));
+    return StructType::get(Context, EltTy, EltTy, NULL);
+  }
+
+  case OFFSET_TYPE:
+    return getTargetData().getIntPtrType(Context);
+
+  case POINTER_TYPE:
+  case REFERENCE_TYPE:
+    // void* -> byte*
+    return VOID_TYPE_P(TREE_TYPE(type)) ?  GetUnitPointerType(Context) :
+      ConvertType(TREE_TYPE(type))->getPointerTo();
+
+  case REAL_TYPE:
+    if (TYPE_PRECISION(type) == 32)
+      return Type::getFloatTy(Context);
+    if (TYPE_PRECISION(type) == 64)
+      return Type::getDoubleTy(Context);
+    if (TYPE_PRECISION(type) == 80)
+      return Type::getX86_FP80Ty(Context);
+    if (TYPE_PRECISION(type) == 128)
+#ifdef TARGET_POWERPC
+      return Type::getPPC_FP128Ty(Context);
+#else
+      // IEEE quad precision.
+      return Type::getFP128Ty(Context);
+#endif
+      DieAbjectly("Unknown FP type!", type);
+
+  case VECTOR_TYPE: {
+    // LLVM does not support vectors of pointers, so turn any pointers into
+    // integers.
+    const Type *EltTy = POINTER_TYPE_P(TREE_TYPE(type)) ?
+      getTargetData().getIntPtrType(Context) : getRegType(TREE_TYPE(type));
+    return VectorType::get(EltTy, TYPE_VECTOR_SUBPARTS(type));
+  }
+
+  }
 }
 
 
@@ -736,7 +783,10 @@
 
   case VECTOR_TYPE: {
     if ((Ty = GET_TYPE_LLVM(type))) return Ty;
-    Ty = ConvertType(TREE_TYPE(type));
+    // LLVM does not support vectors of pointers, so turn any pointers into
+    // integers.
+    Ty = POINTER_TYPE_P(TREE_TYPE(type)) ?
+      getTargetData().getIntPtrType(Context) : ConvertType(TREE_TYPE(type));
     assert(!Ty->isAbstract() && "should use TypeDB.setType()");
     Ty = VectorType::get(Ty, TYPE_VECTOR_SUBPARTS(type));
     Ty = SET_TYPE_LLVM(type, Ty);
@@ -866,11 +916,8 @@
     // Handle OFFSET_TYPE specially.  This is used for pointers to members,
     // which are really just integer offsets.  As such, return the appropriate
     // integer directly.
-    switch (getTargetData().getPointerSize()) {
-    default: assert(0 && "Unknown pointer size!");
-    case 4: Ty = Type::getInt32Ty(Context); break;
-    case 8: Ty = Type::getInt64Ty(Context); break;
-    }
+    Ty = getTargetData().getIntPtrType(Context);
+    break;
   }
 
   // Try to give the type a helpful name.  There is no point in doing this for





More information about the llvm-commits mailing list