[llvm-commits] [dragonegg] r128000 - /dragonegg/trunk/Constants.cpp

Duncan Sands baldrick at free.fr
Mon Mar 21 08:56:04 PDT 2011


Author: baldrick
Date: Mon Mar 21 10:56:04 2011
New Revision: 128000

URL: http://llvm.org/viewvc/llvm-project?rev=128000&view=rev
Log:
GCC now has a convenient method for turning INTEGER_CST, REAL_CST and
friends into the bunch of bytes they represent in memory on the target
machine.  Use this to simplify and unify the handling of such constants.

Modified:
    dragonegg/trunk/Constants.cpp

Modified: dragonegg/trunk/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=128000&r1=127999&r2=128000&view=diff
==============================================================================
--- dragonegg/trunk/Constants.cpp (original)
+++ dragonegg/trunk/Constants.cpp Mon Mar 21 10:56:04 2011
@@ -407,106 +407,18 @@
 //                       ... ConvertInitializer ...
 //===----------------------------------------------------------------------===//
 
-/// 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
-/// by querying the buffer's size.
-/// The following kinds of expressions are currently supported: INTEGER_CST,
-/// REAL_CST, COMPLEX_CST, VECTOR_CST, STRING_CST.
-static unsigned EncodeExpr(tree exp, SmallVectorImpl<unsigned char> &Buffer) {
+/// ConvertCST - Return the given simple constant as an array of bytes.  For the
+/// moment only INTEGER_CST, REAL_CST, COMPLEX_CST and VECTOR_CST are supported.
+static Constant *ConvertCST(tree exp) {
   const tree type = TREE_TYPE(exp);
   unsigned SizeInBytes = (TREE_INT_CST_LOW(TYPE_SIZE(type)) + 7) / 8;
-  Buffer.resize(SizeInBytes);
+  // Encode the constant in Buffer in target format.
+  std::vector<unsigned char> Buffer(SizeInBytes);
   unsigned BytesWritten = native_encode_expr(exp, &Buffer[0], SizeInBytes);
   assert(BytesWritten == SizeInBytes && "Failed to fully encode expression!");
-  return BytesWritten;
-}
-
-static Constant *ConvertINTEGER_CST(tree exp) {
-  const Type *Ty = ConvertType(TREE_TYPE(exp));
-
-  // Handle i128 specially.
-  if (const IntegerType *IT = dyn_cast<IntegerType>(Ty)) {
-    if (IT->getBitWidth() == 128) {
-      // GCC only supports i128 on 64-bit systems.
-      assert(HOST_BITS_PER_WIDE_INT == 64 &&
-             "i128 only supported on 64-bit system");
-      uint64_t Bits[] = { TREE_INT_CST_LOW(exp), TREE_INT_CST_HIGH(exp) };
-      return ConstantInt::get(Context, APInt(128, 2, Bits));
-    }
-  }
-
-  // Build the value as a ulong constant, then constant fold it to the right
-  // type.  This handles overflow and other things appropriately.
-  uint64_t IntValue = getINTEGER_CSTVal(exp);
-  ConstantInt *C = ConstantInt::get(Type::getInt64Ty(Context), IntValue);
-  // The destination type can be a pointer, integer or floating point
-  // so we need a generalized cast here
-  Instruction::CastOps opcode = CastInst::getCastOpcode(C, false, Ty,
-      !TYPE_UNSIGNED(TREE_TYPE(exp)));
-  return TheFolder->CreateCast(opcode, C, Ty);
-}
-
-static Constant *ConvertREAL_CST(tree exp) {
-  // TODO: Test new implementation on a big-endian machine.
-
-  // Encode the constant in Buffer in target format.
-  SmallVector<unsigned char, 16> Buffer;
-  EncodeExpr(exp, Buffer);
-
-  // Discard any alignment padding, which we assume comes at the end.
-  unsigned Precision = TYPE_PRECISION(TREE_TYPE(exp));
-  assert((Precision & 7) == 0 && "Unsupported real number precision!");
-  Buffer.resize(Precision / 8);
-
-  // We are going to view the buffer as an array of APInt words.  Ensure that
-  // the buffer contains a whole number of words by extending it if necessary.
-  unsigned Words = (Precision + integerPartWidth - 1) / integerPartWidth;
-  // On a little-endian machine extend the buffer by adding bytes to the end.
-  Buffer.resize(Words * (integerPartWidth / 8));
-  // On a big-endian machine extend the buffer by adding bytes to the beginning.
-  if (BYTES_BIG_ENDIAN)
-    std::copy_backward(Buffer.begin(), Buffer.begin() + Precision / 8,
-                       Buffer.end());
-
-  // Ensure that the least significant word comes first: we are going to make an
-  // APInt, and the APInt constructor wants the least significant word first.
-  integerPart *Parts = (integerPart *)&Buffer[0];
-  if (BYTES_BIG_ENDIAN)
-    std::reverse(Parts, Parts + Words);
-
-  bool isPPC_FP128 = ConvertType(TREE_TYPE(exp))->isPPC_FP128Ty();
-  if (isPPC_FP128) {
-    // This type is actually a pair of doubles in disguise.  They turn up the
-    // wrong way round here, so flip them.
-    assert(FLOAT_WORDS_BIG_ENDIAN && "PPC not big endian!");
-    assert(Words == 2 && Precision == 128 && "Strange size for PPC_FP128!");
-    std::swap(Parts[0], Parts[1]);
-  }
-
-  // Form an APInt from the buffer, an APFloat from the APInt, and the desired
-  // floating point constant from the APFloat, phew!
-  const APInt &I = APInt(Precision, Words, Parts);
-  return ConstantFP::get(Context, APFloat(I, !isPPC_FP128));
-}
-
-static Constant *ConvertVECTOR_CST(tree exp) {
-  if (!TREE_VECTOR_CST_ELTS(exp))
-    return Constant::getNullValue(ConvertType(TREE_TYPE(exp)));
-
-  std::vector<Constant*> Elts;
-  for (tree elt = TREE_VECTOR_CST_ELTS(exp); elt; elt = TREE_CHAIN(elt))
-    Elts.push_back(ConvertInitializer(TREE_VALUE(elt)));
-
-  // The vector should be zero filled if insufficient elements are provided.
-  if (Elts.size() < TYPE_VECTOR_SUBPARTS(TREE_TYPE(exp))) {
-    tree EltType = TREE_TYPE(TREE_TYPE(exp));
-    Constant *Zero = Constant::getNullValue(ConvertType(EltType));
-    while (Elts.size() < TYPE_VECTOR_SUBPARTS(TREE_TYPE(exp)))
-      Elts.push_back(Zero);
-  }
-
-  return ConstantVector::get(Elts);
+  // Turn it into an LLVM byte array.
+  return ConstantArray::get(Context, StringRef((char *)&Buffer[0], SizeInBytes),
+                            /*AddNull*/false);
 }
 
 static Constant *ConvertSTRING_CST(tree exp) {
@@ -580,14 +492,6 @@
   return ConstantArray::get(StrTy, Elts);
 }
 
-static Constant *ConvertCOMPLEX_CST(tree exp) {
-  Constant *Elts[2] = {
-    ConvertInitializer(TREE_REALPART(exp)),
-    ConvertInitializer(TREE_IMAGPART(exp))
-  };
-  return ConstantStruct::get(Context, Elts, 2, false);
-}
-
 static Constant *ConvertADDR_EXPR(tree exp) {
   return AddressOf(TREE_OPERAND(exp, 0));
 }
@@ -1308,21 +1212,15 @@
     debug_tree(exp);
     assert(0 && "Unknown constant to convert!");
     abort();
+  case COMPLEX_CST:
   case INTEGER_CST:
-    Init = ConvertINTEGER_CST(exp);
-    break;
   case REAL_CST:
-    Init = ConvertREAL_CST(exp);
-    break;
   case VECTOR_CST:
-    Init = ConvertVECTOR_CST(exp);
+    Init = InterpretAsType(ConvertCST(exp), ConvertType(TREE_TYPE(exp)), 0);
     break;
   case STRING_CST:
     Init = ConvertSTRING_CST(exp);
     break;
-  case COMPLEX_CST:
-    Init = ConvertCOMPLEX_CST(exp);
-    break;
   case NOP_EXPR:
     Init = ConvertNOP_EXPR(exp);
     break;





More information about the llvm-commits mailing list