[llvm-commits] [dragonegg] r130479 - /dragonegg/trunk/src/Constants.cpp

Duncan Sands baldrick at free.fr
Thu Apr 28 23:31:39 PDT 2011


Author: baldrick
Date: Fri Apr 29 01:31:39 2011
New Revision: 130479

URL: http://llvm.org/viewvc/llvm-project?rev=130479&view=rev
Log:
Remove all uses of the global TheFolder constant folder from global
constant handling.

Modified:
    dragonegg/trunk/src/Constants.cpp

Modified: dragonegg/trunk/src/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Constants.cpp?rev=130479&r1=130478&r2=130479&view=diff
==============================================================================
--- dragonegg/trunk/src/Constants.cpp (original)
+++ dragonegg/trunk/src/Constants.cpp Fri Apr 29 01:31:39 2011
@@ -34,6 +34,7 @@
 #include "llvm/GlobalVariable.h"
 #include "llvm/LLVMContext.h"
 #include "llvm/Support/Host.h"
+#include "llvm/Support/TargetFolder.h"
 #include "llvm/Target/TargetData.h"
 
 // System headers
@@ -55,6 +56,10 @@
 
 static LLVMContext &Context = getGlobalContext();
 
+// Forward declarations.
+static Constant *ConvertInitializerImpl(tree, TargetFolder &);
+static Constant *AddressOfImpl(tree, TargetFolder &);
+
 //===----------------------------------------------------------------------===//
 //                           ... InterpretAsType ...
 //===----------------------------------------------------------------------===//
@@ -62,6 +67,8 @@
 typedef Range<int> SignedRange;
 
 /// BitSlice - A contiguous range of bits held in memory.
+namespace {
+
 class BitSlice {
   SignedRange R;
   Constant *Contents; // Null if and only if the range is empty.
@@ -74,11 +81,11 @@
   }
 
   /// ExtendRange - Extend the slice to a wider range.  All added bits are zero.
-  BitSlice ExtendRange(SignedRange r) const;
+  BitSlice ExtendRange(SignedRange r, TargetFolder &Folder) const;
 
   /// ReduceRange - Reduce the slice to a smaller range discarding any bits that
   /// do not belong to the new range.
-  BitSlice ReduceRange(SignedRange r) const;
+  BitSlice ReduceRange(SignedRange r, TargetFolder &Folder) const;
 
 public:
   /// BitSlice - Default constructor: empty bit range.
@@ -137,16 +144,18 @@
   /// returned value corresponds to the first bit of the range (aka "First"),
   /// while on big-endian machines it corresponds to the last bit of the range
   /// (aka "Last-1").
-  Constant *getBits(SignedRange r) const;
+  Constant *getBits(SignedRange r, TargetFolder &Folder) const;
 
   /// Merge - Join the slice with another (which must be disjoint), forming the
   /// convex hull of the ranges.  The bits in the range of one of the slices are
   /// those of that slice.  Any other bits have an undefined value.
-  void Merge(const BitSlice &other);
+  void Merge(const BitSlice &other, TargetFolder &Folder);
 };
 
+} // Unnamed namespace.
+
 /// ExtendRange - Extend the slice to a wider range.  All added bits are zero.
-BitSlice BitSlice::ExtendRange(SignedRange r) const {
+BitSlice BitSlice::ExtendRange(SignedRange r, TargetFolder &Folder) const {
   assert(r.contains(R) && "Not an extension!");
   // Quick exit if the range did not actually increase.
   if (R == r)
@@ -157,18 +166,18 @@
   if (empty())
     return BitSlice(r, Constant::getNullValue(ExtTy));
   // Extend the contents to the new type.
-  Constant *C = TheFolder->CreateZExtOrBitCast(Contents, ExtTy);
+  Constant *C = Folder.CreateZExtOrBitCast(Contents, ExtTy);
   // Position the old contents correctly inside the new contents.
   unsigned deltaFirst = R.getFirst() - r.getFirst();
   unsigned deltaLast = r.getLast() - R.getLast();
   if (BYTES_BIG_ENDIAN && deltaLast) {
     (void)deltaFirst; // Avoid unused variable warning.
     Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaLast);
-    C = TheFolder->CreateShl(C, ShiftAmt);
+    C = Folder.CreateShl(C, ShiftAmt);
   } else if (!BYTES_BIG_ENDIAN && deltaFirst) {
     (void)deltaLast; // Avoid unused variable warning.
     Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaFirst);
-    C = TheFolder->CreateShl(C, ShiftAmt);
+    C = Folder.CreateShl(C, ShiftAmt);
   }
   return BitSlice(r, C);
 }
@@ -180,7 +189,7 @@
 /// returned value corresponds to the first bit of the range (aka "First"),
 /// while on big-endian machines it corresponds to the last bit of the range
 /// (aka "Last-1").
-Constant *BitSlice::getBits(SignedRange r) const {
+Constant *BitSlice::getBits(SignedRange r, TargetFolder &Folder) const {
   assert(!r.empty() && "Bit range is empty!");
   // Quick exit if the desired range matches that of the slice.
   if (R == r)
@@ -190,9 +199,9 @@
   if (empty())
     return UndefValue::get(RetTy);
   // Extend to the convex hull of the two ranges.
-  BitSlice Slice = ExtendRange(R.Join(r));
+  BitSlice Slice = ExtendRange(R.Join(r), Folder);
   // Chop the slice down to the requested range.
-  Slice = Slice.ReduceRange(r);
+  Slice = Slice.ReduceRange(r, Folder);
   // Now we can just return the bits contained in the slice.
   return Slice.Contents;
 }
@@ -200,7 +209,7 @@
 /// Merge - Join the slice with another (which must be disjoint), forming the
 /// convex hull of the ranges.  The bits in the range of one of the slices are
 /// those of that slice.  Any other bits have an undefined value.
-void BitSlice::Merge(const BitSlice &other) {
+void BitSlice::Merge(const BitSlice &other, TargetFolder &Folder) {
   // If the other slice is empty, the result is this slice.
   if (other.empty())
     return;
@@ -213,18 +222,17 @@
 
   // Extend each slice to the convex hull of the ranges.
   SignedRange Hull = R.Join(other.getRange());
-  BitSlice ExtThis = ExtendRange(Hull);
-  BitSlice ExtOther = other.ExtendRange(Hull);
+  BitSlice ExtThis = ExtendRange(Hull, Folder);
+  BitSlice ExtOther = other.ExtendRange(Hull, Folder);
 
   // Since the slices are disjoint and all added bits are zero they can be
   // joined via a simple 'or'.
-  *this = BitSlice(Hull, TheFolder->CreateOr(ExtThis.Contents,
-                                             ExtOther.Contents));
+  *this = BitSlice(Hull, Folder.CreateOr(ExtThis.Contents, ExtOther.Contents));
 }
 
 /// ReduceRange - Reduce the slice to a smaller range discarding any bits that
 /// do not belong to the new range.
-BitSlice BitSlice::ReduceRange(SignedRange r) const {
+BitSlice BitSlice::ReduceRange(SignedRange r, TargetFolder &Folder) const {
   assert(R.contains(r) && "Not a reduction!");
   // Quick exit if the range did not actually decrease.
   if (R == r)
@@ -240,15 +248,15 @@
   if (BYTES_BIG_ENDIAN && deltaLast) {
     (void)deltaFirst; // Avoid unused variable warning.
     Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaLast);
-    C = TheFolder->CreateLShr(C, ShiftAmt);
+    C = Folder.CreateLShr(C, ShiftAmt);
   } else if (!BYTES_BIG_ENDIAN && deltaFirst) {
     (void)deltaLast; // Avoid unused variable warning.
     Constant *ShiftAmt = ConstantInt::get(C->getType(), deltaFirst);
-    C = TheFolder->CreateLShr(C, ShiftAmt);
+    C = Folder.CreateLShr(C, ShiftAmt);
   }
   // Truncate to the new type.
   const Type *RedTy = IntegerType::get(Context, r.getWidth());
-  C = TheFolder->CreateTruncOrBitCast(C, RedTy);
+  C = Folder.CreateTruncOrBitCast(C, RedTy);
   return BitSlice(r, C);
 }
 
@@ -256,7 +264,7 @@
 /// integer.  Only the bits in the given range are needed, so there is no need
 /// to supply bits outside this range though it is harmless to do so.  There is
 /// also no need to supply undefined bits inside the range.
-static BitSlice ViewAsBits(Constant *C, SignedRange R) {
+static BitSlice ViewAsBits(Constant *C, SignedRange R, TargetFolder &Folder) {
   if (R.empty())
     return BitSlice();
 
@@ -276,7 +284,7 @@
   case Type::PointerTyID: {
     // Cast to an integer with the same number of bits and return that.
     const IntegerType *IntTy = getTargetData().getIntPtrType(Context);
-    return BitSlice(0, StoreSize, TheFolder->CreatePtrToInt(C, IntTy));
+    return BitSlice(0, StoreSize, Folder.CreatePtrToInt(C, IntTy));
   }
   case Type::DoubleTyID:
   case Type::FloatTyID:
@@ -288,7 +296,7 @@
     // Bitcast to an integer with the same number of bits and return that.
     unsigned BitWidth = Ty->getPrimitiveSizeInBits();
     const IntegerType *IntTy = IntegerType::get(Context, BitWidth);
-    C = TheFolder->CreateBitCast(C, IntTy);
+    C = Folder.CreateBitCast(C, IntTy);
     // Be careful about where the bits are placed in case this is a funky type
     // like i1.  If the width is a multiple of the address unit then there is
     // nothing to worry about: the bits occupy the range [0, StoreSize).  But
@@ -314,11 +322,11 @@
     SignedRange StrideRange(0, Stride);
     for (unsigned i = FirstElt; i < LastElt; ++i) {
       // Extract the element.
-      Constant *Elt = TheFolder->CreateExtractValue(C, &i, 1);
+      Constant *Elt = Folder.CreateExtractValue(C, &i, 1);
       // View it as a bunch of bits.
-      BitSlice EltBits = ViewAsBits(Elt, StrideRange);
+      BitSlice EltBits = ViewAsBits(Elt, StrideRange, Folder);
       // Add to the already known bits.
-      Bits.Merge(EltBits.Displace(i * Stride));
+      Bits.Merge(EltBits.Displace(i * Stride), Folder);
     }
     return Bits;
   }
@@ -334,13 +342,14 @@
     BitSlice Bits;
     for (unsigned i = FirstIdx; i < LastIdx; ++i) {
       // Extract the field.
-      Constant *Field = TheFolder->CreateExtractValue(C, &i, 1);
+      Constant *Field = Folder.CreateExtractValue(C, &i, 1);
       // View it as a bunch of bits.
       const Type *FieldTy = Field->getType();
       unsigned FieldStoreSize = getTargetData().getTypeStoreSizeInBits(FieldTy);
-      BitSlice FieldBits = ViewAsBits(Field, SignedRange(0, FieldStoreSize));
+      BitSlice FieldBits = ViewAsBits(Field, SignedRange(0, FieldStoreSize),
+                                      Folder);
       // Add to the already known bits.
-      Bits.Merge(FieldBits.Displace(SL->getElementOffset(i)*8));
+      Bits.Merge(FieldBits.Displace(SL->getElementOffset(i)*8), Folder);
     }
     return Bits;
   }
@@ -362,11 +371,11 @@
     for (unsigned i = FirstElt; i < LastElt; ++i) {
       // Extract the element.
       ConstantInt *Idx = ConstantInt::get(Type::getInt32Ty(Context), i);
-      Constant *Elt = TheFolder->CreateExtractElement(C, Idx);
+      Constant *Elt = Folder.CreateExtractElement(C, Idx);
       // View it as a bunch of bits.
-      BitSlice EltBits = ViewAsBits(Elt, StrideRange);
+      BitSlice EltBits = ViewAsBits(Elt, StrideRange, Folder);
       // Add to the already known bits.
-      Bits.Merge(EltBits.Displace(i * Stride));
+      Bits.Merge(EltBits.Displace(i * Stride), Folder);
     }
     return Bits;
   }
@@ -378,7 +387,8 @@
 /// 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.
-Constant *InterpretAsType(Constant *C, const Type* Ty, int StartingBit = 0) {
+static Constant *InterpretAsType(Constant *C, const Type* Ty, int StartingBit,
+                                 TargetFolder &Folder) {
   if (C->getType() == Ty)
     return C;
 
@@ -392,23 +402,23 @@
     // out are needed, so rather than converting the entire constant this only
     // converts enough to get all of the required bits.
     BitSlice Bits = ViewAsBits(C, SignedRange(StartingBit,
-                                              StartingBit + StoreSize));
+                                              StartingBit + StoreSize), Folder);
     // Extract the bits used by the integer.  If the integer width is a multiple
     // of the address unit then the endianness of the target doesn't matter.  If
     // not then the padding bits come at the start on big-endian machines and at
     // the end on little-endian machines.
     Bits = Bits.Displace(-StartingBit);
     return BYTES_BIG_ENDIAN ?
-      Bits.getBits(SignedRange(StoreSize - BitWidth, StoreSize)) :
-      Bits.getBits(SignedRange(0, BitWidth));
+      Bits.getBits(SignedRange(StoreSize - BitWidth, StoreSize), Folder) :
+      Bits.getBits(SignedRange(0, BitWidth), Folder);
   }
 
   case Type::PointerTyID: {
     // Interpret as an integer with the same number of bits then cast back to
     // the original type.
     const IntegerType *IntTy = getTargetData().getIntPtrType(Context);
-    C = InterpretAsType(C, IntTy, StartingBit);
-    return TheFolder->CreateIntToPtr(C, Ty);
+    C = InterpretAsType(C, IntTy, StartingBit, Folder);
+    return Folder.CreateIntToPtr(C, Ty);
   }
   case Type::DoubleTyID:
   case Type::FloatTyID:
@@ -420,7 +430,8 @@
     // the original type.
     unsigned BitWidth = Ty->getPrimitiveSizeInBits();
     const IntegerType *IntTy = IntegerType::get(Context, BitWidth);
-    return TheFolder->CreateBitCast(InterpretAsType(C, IntTy, StartingBit), Ty);
+    return Folder.CreateBitCast(InterpretAsType(C, IntTy, StartingBit, Folder),
+                                Ty);
   }
 
   case Type::ArrayTyID: {
@@ -431,7 +442,7 @@
     const unsigned NumElts = ATy->getNumElements();
     std::vector<Constant*> Vals(NumElts);
     for (unsigned i = 0; i != NumElts; ++i)
-      Vals[i] = InterpretAsType(C, EltTy, StartingBit + i*Stride);
+      Vals[i] = InterpretAsType(C, EltTy, StartingBit + i*Stride, Folder);
     return ConstantArray::get(ATy, Vals); // TODO: Use ArrayRef constructor.
   }
 
@@ -443,7 +454,8 @@
     std::vector<Constant*> Vals(NumElts);
     for (unsigned i = 0; i != NumElts; ++i)
       Vals[i] = InterpretAsType(C, STy->getElementType(i),
-                                StartingBit + SL->getElementOffsetInBits(i));
+                                StartingBit + SL->getElementOffsetInBits(i),
+                                Folder);
     return ConstantStruct::get(STy, Vals); // TODO: Use ArrayRef constructor.
   }
 
@@ -455,7 +467,7 @@
     const unsigned NumElts = VTy->getNumElements();
     SmallVector<Constant*, 16> Vals(NumElts);
     for (unsigned i = 0; i != NumElts; ++i)
-      Vals[i] = InterpretAsType(C, EltTy, StartingBit + i*Stride);
+      Vals[i] = InterpretAsType(C, EltTy, StartingBit + i*Stride, Folder);
     return ConstantVector::get(Vals);
   }
   }
@@ -466,12 +478,11 @@
 //                    ... 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) {
+/// ExtractRegisterFromConstantImpl - Implementation of
+/// ExtractRegisterFromConstant.
+static Constant *ExtractRegisterFromConstantImpl(Constant *C, tree type,
+                                                 int StartingByte,
+                                                 TargetFolder &Folder) {
   // NOTE: Needs to be kept in sync with getRegType and RepresentAsMemory.
   int StartingBit = StartingByte * BITS_PER_UNIT;
   switch (TREE_CODE(type)) {
@@ -489,16 +500,16 @@
     // 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));
+    C = InterpretAsType(C, MemTy, StartingBit, Folder);
+    return Folder.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)
+      ExtractRegisterFromConstantImpl(C, elt_type, StartingBit, Folder),
+      ExtractRegisterFromConstantImpl(C, elt_type, StartingBit + Stride, Folder)
     };
     return ConstantStruct::get(Context, Vals, 2, false);
   }
@@ -506,12 +517,12 @@
   case OFFSET_TYPE:
   case POINTER_TYPE:
   case REFERENCE_TYPE:
-    return InterpretAsType(C, getRegType(type), StartingBit);
+    return InterpretAsType(C, getRegType(type), StartingBit, Folder);
 
   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);
+    return InterpretAsType(C, getRegType(type), StartingBit, Folder);
 
   case VECTOR_TYPE: {
     tree elt_type = TREE_TYPE(type);
@@ -519,12 +530,13 @@
     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);
+      Vals[i] = ExtractRegisterFromConstantImpl(C, elt_type,
+                                                StartingBit+i*Stride, Folder);
       // 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);
+        Vals[i] = Folder.CreatePtrToInt(Vals[i], IntTy);
       }
     }
     return ConstantVector::get(Vals);
@@ -533,6 +545,16 @@
   }
 }
 
+/// 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) {
+  TargetFolder Folder(&getTargetData());
+  return ExtractRegisterFromConstantImpl(C, type, StartingByte, Folder);
+}
+
 
 //===----------------------------------------------------------------------===//
 //                       ... ConvertInitializer ...
@@ -540,16 +562,17 @@
 
 /// 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));
+static Constant *getAsRegister(tree exp, TargetFolder &Folder) {
+  Constant *C = ConvertInitializerImpl(exp, Folder);
+  return ExtractRegisterFromConstantImpl(C, TREE_TYPE(exp), 0, Folder);
 }
 
 /// RepresentAsMemory - Turn a constant of in-register type (corresponding
 /// to the given GCC type) into an in-memory constant.  The result has the
 /// property that applying ExtractRegisterFromConstant to it gives you the
 /// original in-register constant back again.
-static Constant *RepresentAsMemory(Constant *C, tree type) {
+static Constant *RepresentAsMemory(Constant *C, tree type,
+                                   TargetFolder &Folder) {
   // NOTE: Needs to be kept in sync with ExtractRegisterFromConstant.
   assert(C->getType() == getRegType(type) && "Constant has wrong type!");
   Constant *Result;
@@ -570,18 +593,18 @@
     const Type *MemTy = IntegerType::get(Context, Size);
     // We can extend in any way, but get nicer IR by respecting signedness.
     bool isSigned = !TYPE_UNSIGNED(type);
-    Result = isSigned ? TheFolder->CreateSExtOrBitCast(C, MemTy) :
-      TheFolder->CreateZExtOrBitCast(C, MemTy);
+    Result = isSigned ? Folder.CreateSExtOrBitCast(C, MemTy) :
+      Folder.CreateZExtOrBitCast(C, MemTy);
     break;
   }
 
   case COMPLEX_TYPE: {
     tree elt_type = TREE_TYPE(type);
     unsigned Idx[2] = {0, 1};
-    Constant *Real = TheFolder->CreateExtractValue(C, Idx, 1);
-    Constant *Imag = TheFolder->CreateExtractValue(C, Idx + 1, 1);
-    Real = RepresentAsMemory(Real, elt_type);
-    Imag = RepresentAsMemory(Imag, elt_type);
+    Constant *Real = Folder.CreateExtractValue(C, Idx, 1);
+    Constant *Imag = Folder.CreateExtractValue(C, Idx + 1, 1);
+    Real = RepresentAsMemory(Real, elt_type, Folder);
+    Imag = RepresentAsMemory(Imag, elt_type, Folder);
     Constant *Vals[2] = { Real, Imag };
     Result = ConstantStruct::get(Context, Vals, 2, false);
     break;
@@ -607,8 +630,8 @@
     std::vector<Constant*> Vals(NumElts);
     for (unsigned i = 0; i != NumElts; ++i) {
       ConstantInt *Idx = ConstantInt::get(Type::getInt32Ty(Context), i);
-      Vals[i] = TheFolder->CreateExtractElement(C, Idx);
-      Vals[i] = RepresentAsMemory(Vals[i], elt_type);
+      Vals[i] = Folder.CreateExtractElement(C, Idx);
+      Vals[i] = RepresentAsMemory(Vals[i], elt_type, Folder);
     }
     // The elements may have funky types, so forming a vector may not always be
     // possible.
@@ -620,9 +643,9 @@
 
   // Ensure that the result satisfies the guarantees given by ConvertInitializer
   // by turning it into a type with the right size and an appropriate alignment.
-  Result = InterpretAsType(Result, ConvertType(type));
+  Result = InterpretAsType(Result, ConvertType(type), 0, Folder);
 
-  assert(C == ExtractRegisterFromConstant(Result, type) &&
+  assert(C == ExtractRegisterFromConstantImpl(Result, type, 0, Folder) &&
          "Register inserted wrong!");
 
   return Result;
@@ -633,9 +656,10 @@
 /// and the initializer are scalar.  This is convenient for making explicit the
 /// implicit scalar casts that GCC allows in "assignments" such as initializing
 /// a record field.
-static Constant *ConvertInitializerWithCast(tree exp, tree type) {
+static Constant *ConvertInitializerWithCast(tree exp, tree type,
+                                            TargetFolder &Folder) {
   // Convert the initializer.
-  Constant *C = ConvertInitializer(exp);
+  Constant *C = ConvertInitializerImpl(exp, Folder);
 
   // If no cast is needed, or it would not be a scalar cast, then just return
   // the initializer as is.
@@ -654,21 +678,21 @@
   // that would not perform a value extension (adding extra zeros or sign bits
   // when casting to a larger integer type for example): any extra bits would
   // wrongly get an undefined value instead.
-  C = ExtractRegisterFromConstant(C, TREE_TYPE(exp));
+  C = ExtractRegisterFromConstantImpl(C, TREE_TYPE(exp), 0, Folder);
 
   // Cast to the desired type.
   bool SrcIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp));
   bool DestIsSigned = !TYPE_UNSIGNED(type);
   Instruction::CastOps opcode = CastInst::getCastOpcode(C, SrcIsSigned, DestTy,
                                                         DestIsSigned);
-  C = TheFolder->CreateCast(opcode, C, DestTy);
+  C = Folder.CreateCast(opcode, C, DestTy);
 
-  return RepresentAsMemory(C, type);
+  return RepresentAsMemory(C, type, Folder);
 }
 
 /// 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) {
+static Constant *ConvertCST(tree exp, TargetFolder &) {
   const tree type = TREE_TYPE(exp);
   unsigned SizeInChars = (TREE_INT_CST_LOW(TYPE_SIZE(type)) + CHAR_BIT - 1) /
     CHAR_BIT;
@@ -681,7 +705,7 @@
                             /*AddNull*/false);
 }
 
-static Constant *ConvertSTRING_CST(tree exp) {
+static Constant *ConvertSTRING_CST(tree exp, TargetFolder &) {
   const ArrayType *StrTy = cast<ArrayType>(ConvertType(TREE_TYPE(exp)));
   const Type *ElTy = StrTy->getElementType();
 
@@ -752,12 +776,12 @@
   return ConstantArray::get(StrTy, Elts);
 }
 
-static Constant *ConvertADDR_EXPR(tree exp) {
-  return AddressOf(TREE_OPERAND(exp, 0));
+static Constant *ConvertADDR_EXPR(tree exp, TargetFolder &Folder) {
+  return AddressOfImpl(TREE_OPERAND(exp, 0), Folder);
 }
 
 /// ConvertArrayCONSTRUCTOR - Convert a CONSTRUCTOR with array or vector type.
-static Constant *ConvertArrayCONSTRUCTOR(tree exp) {
+static Constant *ConvertArrayCONSTRUCTOR(tree exp, TargetFolder &Folder) {
   const TargetData &TD = getTargetData();
 
   tree init_type = TREE_TYPE(exp);
@@ -794,7 +818,7 @@
   tree elt_index, elt_value;
   FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(exp), ix, elt_index, elt_value) {
     // Find and decode the constructor's value.
-    Constant *Val = ConvertInitializerWithCast(elt_value, elt_type);
+    Constant *Val = ConvertInitializerWithCast(elt_value, elt_type, Folder);
     uint64_t ValSize = TD.getTypeAllocSizeInBits(Val->getType());
     assert(ValSize <= EltSize && "Element initial value too big!");
 
@@ -903,13 +927,16 @@
 /// FieldContents - A constant restricted to a range of bits.  Any part of the
 /// constant outside of the range is discarded.  The range may be bigger than
 /// the constant in which case any extra bits have an undefined value.
+namespace {
+
 class FieldContents {
   SignedRange R; // The range of bits occupied by the constant.
   Constant *C;   // The constant.  May be null if the range is empty.
   int Starts;    // The first bit of the constant is positioned at this offset.
+  TargetFolder &Folder;
 
-  FieldContents(SignedRange r, Constant *c, int starts)
-    : R(r), C(c), Starts(starts) {
+  FieldContents(SignedRange r, Constant *c, int starts, TargetFolder &folder)
+    : R(r), C(c), Starts(starts), Folder(folder) {
     assert((R.empty() || C) && "Need constant when range not empty!");
   }
 
@@ -919,7 +946,7 @@
     if (R.empty())
       return 0;
     const Type *IntTy = IntegerType::get(Context, R.getWidth());
-    return InterpretAsType(C, IntTy, R.getFirst() - Starts);
+    return InterpretAsType(C, IntTy, R.getFirst() - Starts, Folder);
   }
 
   /// isSafeToReturnContentsDirectly - Return whether the current value for the
@@ -942,12 +969,16 @@
   }
 
 public:
-  /// FieldContents - Default constructor: empty bit range.
-  FieldContents() : R(), C(0), Starts(0) {}
-
   /// get - Fill the range [first, last) with the given constant.
-  static FieldContents get(int first, int last, Constant *c) {
-    return FieldContents(SignedRange(first, last), c, first);
+  static FieldContents get(int first, int last, Constant *c,
+                           TargetFolder &folder) {
+    return FieldContents(SignedRange(first, last), c, first, folder);
+  }
+
+  // Copy assignment operator.
+  FieldContents &operator=(const FieldContents &other) {
+    R = other.R; C = other.C; Starts = other.Starts; Folder = other.Folder;
+    return *this;
   }
 
   /// getRange - Return the range occupied by this field.
@@ -993,12 +1024,14 @@
     // The integer type used to hold the bits was too big (for example an i24
     // typically occupies 32 bits so is too big for a range of 24 bits).  Turn
     // it into an array of bytes instead.
-    C = InterpretAsType(C, GetUnitType(Context, Units));
+    C = InterpretAsType(C, GetUnitType(Context, Units), 0, Folder);
     assert(isSafeToReturnContentsDirectly(TD) && "Unit over aligned?");
     return C;
   }
 };
 
+} // Unnamed namespace.
+
 /// JoinWith - Form the union of this field with another field (which must be
 /// disjoint from this one).  After this the range will be the convex hull of
 /// the ranges of the two fields.
@@ -1007,13 +1040,13 @@
   // together.  This can result in a nasty integer constant expression, but as
   // we only get here for bitfields that's mostly harmless.
   BitSlice Bits(R, getAsBits());
-  Bits.Merge (BitSlice(S.R, S.getAsBits()));
+  Bits.Merge (BitSlice(S.R, S.getAsBits()), Folder);
   R = Bits.getRange();
-  C = Bits.getBits(R);
+  C = Bits.getBits(R, Folder);
   Starts = R.empty() ? 0 : R.getFirst();
 }
 
-static Constant *ConvertRecordCONSTRUCTOR(tree exp) {
+static Constant *ConvertRecordCONSTRUCTOR(tree exp, TargetFolder &Folder) {
   // FIXME: This new logic, especially the handling of bitfields, is untested
   // and probably wrong on big-endian machines.
   IntervalList<FieldContents, int, 8> Layout;
@@ -1062,7 +1095,7 @@
       // it is guaranteed to cover all parts of the GCC type that can be default
       // initialized.  This makes for nicer IR than just using a bunch of bytes.
       Constant *Zero = Constant::getNullValue(FieldTy);
-      Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Zero));
+      Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Zero, Folder));
     }
   }
 
@@ -1086,7 +1119,8 @@
     assert(TREE_CODE(field) == FIELD_DECL && "Initial value not for a field!");
     assert(OffsetIsLLVMCompatible(field) && "Field position not known!");
     // Turn the initial value for this field into an LLVM constant.
-    Constant *Init = ConvertInitializerWithCast(value, TREE_TYPE(field));
+    Constant *Init = ConvertInitializerWithCast(value, TREE_TYPE(field),
+                                                Folder);
     // Work out the range of bits occupied by the field.
     uint64_t FirstBit = getFieldOffsetInBits(field);
     assert(FirstBit <= TypeSize && "Field off end of type!");
@@ -1098,7 +1132,7 @@
     uint64_t LastBit = FirstBit + BitWidth;
 
     // Set the bits occupied by the field to the initial value.
-    Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Init));
+    Layout.AddInterval(FieldContents::get(FirstBit, LastBit, Init, Folder));
   }
 
   // Force all fields to begin and end on a byte boundary.  This automagically
@@ -1173,7 +1207,7 @@
   return ConstantStruct::get(Context, Elts, Pack);
 }
 
-static Constant *ConvertCONSTRUCTOR(tree exp) {
+static Constant *ConvertCONSTRUCTOR(tree exp, TargetFolder &Folder) {
   // If the constructor is empty then default initialize all of the components.
   // It is safe to use the LLVM type here as it covers every part of the GCC
   // type that can possibly be default initialized.
@@ -1184,56 +1218,48 @@
   default:
     DieAbjectly("Unknown constructor!", exp);
   case VECTOR_TYPE:
-  case ARRAY_TYPE:  return ConvertArrayCONSTRUCTOR(exp);
+  case ARRAY_TYPE:  return ConvertArrayCONSTRUCTOR(exp, Folder);
   case QUAL_UNION_TYPE:
   case RECORD_TYPE:
-  case UNION_TYPE: return ConvertRecordCONSTRUCTOR(exp);
+  case UNION_TYPE: return ConvertRecordCONSTRUCTOR(exp, Folder);
   }
 }
 
-static Constant *ConvertMINUS_EXPR(tree exp) {
-  Constant *LHS = getAsRegister(TREE_OPERAND(exp, 0));
-  Constant *RHS = getAsRegister(TREE_OPERAND(exp, 1));
-  return RepresentAsMemory(TheFolder->CreateSub(LHS, RHS), TREE_TYPE(exp));
+static Constant *ConvertMINUS_EXPR(tree exp, TargetFolder &Folder) {
+  Constant *LHS = getAsRegister(TREE_OPERAND(exp, 0), Folder);
+  Constant *RHS = getAsRegister(TREE_OPERAND(exp, 1), Folder);
+  return RepresentAsMemory(Folder.CreateSub(LHS, RHS), TREE_TYPE(exp), Folder);
 }
 
-static Constant *ConvertPLUS_EXPR(tree exp) {
-  Constant *LHS = getAsRegister(TREE_OPERAND(exp, 0));
-  Constant *RHS = getAsRegister(TREE_OPERAND(exp, 1));
-  return RepresentAsMemory(TheFolder->CreateAdd(LHS, RHS), TREE_TYPE(exp));
+static Constant *ConvertPLUS_EXPR(tree exp, TargetFolder &Folder) {
+  Constant *LHS = getAsRegister(TREE_OPERAND(exp, 0), Folder);
+  Constant *RHS = getAsRegister(TREE_OPERAND(exp, 1), Folder);
+  return RepresentAsMemory(Folder.CreateAdd(LHS, RHS), TREE_TYPE(exp), Folder);
 }
 
-static Constant *ConvertPOINTER_PLUS_EXPR(tree exp) {
-  Constant *Ptr = getAsRegister(TREE_OPERAND(exp, 0)); // The pointer.
-  Constant *Idx = getAsRegister(TREE_OPERAND(exp, 1)); // Offset in units.
+static Constant *ConvertPOINTER_PLUS_EXPR(tree exp, TargetFolder &Folder) {
+  Constant *Ptr = getAsRegister(TREE_OPERAND(exp, 0), Folder); // Pointer
+  Constant *Idx = getAsRegister(TREE_OPERAND(exp, 1), Folder); // Offset (units)
 
   // Convert the pointer into an i8* and add the offset to it.
-  Ptr = TheFolder->CreateBitCast(Ptr, GetUnitPointerType(Context));
+  Ptr = Folder.CreateBitCast(Ptr, GetUnitPointerType(Context));
   Constant *Result = POINTER_TYPE_OVERFLOW_UNDEFINED ?
-    TheFolder->CreateInBoundsGetElementPtr(Ptr, &Idx, 1) :
-    TheFolder->CreateGetElementPtr(Ptr, &Idx, 1);
+    Folder.CreateInBoundsGetElementPtr(Ptr, &Idx, 1) :
+    Folder.CreateGetElementPtr(Ptr, &Idx, 1);
 
   // The result may be of a different pointer type.
-  Result = TheFolder->CreateBitCast(Result, getRegType(TREE_TYPE(exp)));
+  Result = Folder.CreateBitCast(Result, getRegType(TREE_TYPE(exp)));
 
-  return RepresentAsMemory(Result, TREE_TYPE(exp));
+  return RepresentAsMemory(Result, TREE_TYPE(exp), Folder);
 }
 
-static Constant *ConvertVIEW_CONVERT_EXPR(tree exp) {
+static Constant *ConvertVIEW_CONVERT_EXPR(tree exp, TargetFolder &Folder) {
   // Does not change the bits, only the type they are considered to be.
-  return ConvertInitializer(TREE_OPERAND(exp, 0));
+  return ConvertInitializerImpl(TREE_OPERAND(exp, 0), Folder);
 }
 
-/// ConvertInitializer - Convert the initial value for a global variable to an
-/// equivalent LLVM constant.  Also handles constant constructors.  The type of
-/// the returned value may be pretty much anything.  All that is guaranteed is
-/// that its alloc size is equal to the size of the initial value and that its
-/// alignment is less than or equal to the initial value's GCC type alignment.
-/// Note that the GCC type may have variable size or no size, in which case the
-/// size is determined by the initial value.  When this happens the size of the
-/// initial value may exceed the alloc size of the LLVM memory type generated
-/// for the GCC type (see ConvertType); it is never smaller than the alloc size.
-Constant *ConvertInitializer(tree exp) {
+/// ConvertInitializerImpl - Implementation of ConvertInitializer.
+static Constant *ConvertInitializerImpl(tree exp, TargetFolder &Folder) {
   // If we already converted the initializer then return the cached copy.
   if (Constant *C = (Constant *)llvm_get_cached(exp))
     return C;
@@ -1246,39 +1272,40 @@
   case INTEGER_CST:
   case REAL_CST:
   case VECTOR_CST:
-    Init = ConvertCST(exp);
+    Init = ConvertCST(exp, Folder);
     break;
   case STRING_CST:
-    Init = ConvertSTRING_CST(exp);
+    Init = ConvertSTRING_CST(exp, Folder);
     break;
   case ADDR_EXPR:
-    Init = ConvertADDR_EXPR(exp);
+    Init = ConvertADDR_EXPR(exp, Folder);
     break;
   case CONSTRUCTOR:
-    Init = ConvertCONSTRUCTOR(exp);
+    Init = ConvertCONSTRUCTOR(exp, Folder);
     break;
   case CONVERT_EXPR:
   case NOP_EXPR:
-    Init = ConvertInitializerWithCast(TREE_OPERAND(exp, 0), TREE_TYPE(exp));
+    Init = ConvertInitializerWithCast(TREE_OPERAND(exp, 0), TREE_TYPE(exp),
+                                      Folder);
     break;
   case MINUS_EXPR:
-    Init = ConvertMINUS_EXPR(exp);
+    Init = ConvertMINUS_EXPR(exp, Folder);
     break;
   case PLUS_EXPR:
-    Init = ConvertPLUS_EXPR(exp);
+    Init = ConvertPLUS_EXPR(exp, Folder);
     break;
   case POINTER_PLUS_EXPR:
-    Init = ConvertPOINTER_PLUS_EXPR(exp);
+    Init = ConvertPOINTER_PLUS_EXPR(exp, Folder);
     break;
   case VIEW_CONVERT_EXPR:
-    Init = ConvertVIEW_CONVERT_EXPR(exp);
+    Init = ConvertVIEW_CONVERT_EXPR(exp, Folder);
     break;
   }
 
   // Make the IR easier to read by converting the bunch of bytes returned by
   // ConvertCST into a less surprising type when it is safe to do so.
   if (!AGGREGATE_TYPE_P(TREE_TYPE(exp)))
-    Init = InterpretAsType(Init, ConvertType(TREE_TYPE(exp)));
+    Init = InterpretAsType(Init, ConvertType(TREE_TYPE(exp)), 0, Folder);
 
 #ifndef NDEBUG
   // Check that the guarantees we make about the returned value actually hold.
@@ -1306,14 +1333,28 @@
   return Init;
 }
 
+/// ConvertInitializer - Convert the initial value for a global variable to an
+/// equivalent LLVM constant.  Also handles constant constructors.  The type of
+/// the returned value may be pretty much anything.  All that is guaranteed is
+/// that its alloc size is equal to the size of the initial value and that its
+/// alignment is less than or equal to the initial value's GCC type alignment.
+/// Note that the GCC type may have variable size or no size, in which case the
+/// size is determined by the initial value.  When this happens the size of the
+/// initial value may exceed the alloc size of the LLVM memory type generated
+/// for the GCC type (see ConvertType); it is never smaller than the alloc size.
+Constant *ConvertInitializer(tree exp) {
+  TargetFolder Folder(&getTargetData());
+  return ConvertInitializerImpl(exp, Folder);
+}
+
 
 //===----------------------------------------------------------------------===//
 //                            ... AddressOf ...
 //===----------------------------------------------------------------------===//
 
 /// AddressOfCST - Return the address of a simple constant, eg a of number.
-static Constant *AddressOfCST(tree exp) {
-  Constant *Init = ConvertInitializer(exp);
+static Constant *AddressOfCST(tree exp, TargetFolder &Folder) {
+  Constant *Init = ConvertInitializerImpl(exp, Folder);
 
   // Cache the constants to avoid making obvious duplicates that have to be
   // folded by the optimizer.
@@ -1335,7 +1376,7 @@
 }
 
 /// AddressOfARRAY_REF - Return the address of an array element or slice.
-static Constant *AddressOfARRAY_REF(tree exp) {
+static Constant *AddressOfARRAY_REF(tree exp, TargetFolder &Folder) {
   tree array = TREE_OPERAND(exp, 0);
   tree index = TREE_OPERAND(exp, 1);
   tree index_type = TREE_TYPE(index);
@@ -1346,46 +1387,45 @@
          "Global with variable size?");
 
   // Get the index into the array as an LLVM integer constant.
-  Constant *IndexVal = getAsRegister(index);
+  Constant *IndexVal = getAsRegister(index, Folder);
 
   // 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 = getAsRegister(lower_bound);
-    IndexVal = TheFolder->CreateSub(IndexVal, LowerBoundVal, hasNUW(index_type),
-                                    hasNSW(index_type));
+    Constant *LowerBoundVal = getAsRegister(lower_bound, Folder);
+    IndexVal = Folder.CreateSub(IndexVal, LowerBoundVal, hasNUW(index_type),
+                                hasNSW(index_type));
   }
 
   // Avoid any assumptions about how the array type is represented in LLVM by
   // doing the GEP on a pointer to the first array element.
-  Constant *ArrayAddr = AddressOf(array);
+  Constant *ArrayAddr = AddressOfImpl(array, Folder);
   const Type *EltTy = ConvertType(TREE_TYPE(TREE_TYPE(array)));
-  ArrayAddr = TheFolder->CreateBitCast(ArrayAddr, EltTy->getPointerTo());
+  ArrayAddr = Folder.CreateBitCast(ArrayAddr, EltTy->getPointerTo());
 
   return POINTER_TYPE_OVERFLOW_UNDEFINED ?
-    TheFolder->CreateInBoundsGetElementPtr(ArrayAddr, &IndexVal, 1) :
-    TheFolder->CreateGetElementPtr(ArrayAddr, &IndexVal, 1);
+    Folder.CreateInBoundsGetElementPtr(ArrayAddr, &IndexVal, 1) :
+    Folder.CreateGetElementPtr(ArrayAddr, &IndexVal, 1);
 }
 
 /// AddressOfCOMPONENT_REF - Return the address of a field in a record.
-static Constant *AddressOfCOMPONENT_REF(tree exp) {
+static Constant *AddressOfCOMPONENT_REF(tree exp, TargetFolder &Folder) {
   tree field_decl = TREE_OPERAND(exp, 1);
 
   // Compute the field offset in units from the start of the record.
   Constant *Offset;
   if (TREE_OPERAND(exp, 2)) {
-    Offset = getAsRegister(TREE_OPERAND(exp, 2));
+    Offset = getAsRegister(TREE_OPERAND(exp, 2), Folder);
     // 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;
     if (factor != 1)
-      Offset = TheFolder->CreateMul(Offset,
-                                    ConstantInt::get(Offset->getType(),
-                                                     factor));
+      Offset = Folder.CreateMul(Offset, ConstantInt::get(Offset->getType(),
+                                                         factor));
   } else {
     assert(DECL_FIELD_OFFSET(field_decl) && "Field offset not available!");
-    Offset = getAsRegister(DECL_FIELD_OFFSET(field_decl));
+    Offset = getAsRegister(DECL_FIELD_OFFSET(field_decl), Folder);
   }
 
   // Here BitStart gives the offset of the field in bits from Offset.
@@ -1393,35 +1433,34 @@
   // Incorporate as much of it as possible into the pointer computation.
   uint64_t Units = BitStart / BITS_PER_UNIT;
   if (Units > 0) {
-    Offset = TheFolder->CreateAdd(Offset,
-                                  ConstantInt::get(Offset->getType(),
-                                                   Units));
+    Offset = Folder.CreateAdd(Offset, ConstantInt::get(Offset->getType(),
+                                                       Units));
     BitStart -= Units * BITS_PER_UNIT;
   }
   assert(BitStart == 0 &&
          "It's a bitfield reference or we didn't get to the field!");
 
   const Type *UnitPtrTy = GetUnitPointerType(Context);
-  Constant *StructAddr = AddressOf(TREE_OPERAND(exp, 0));
-  Constant *FieldPtr = TheFolder->CreateBitCast(StructAddr, UnitPtrTy);
-  FieldPtr = TheFolder->CreateInBoundsGetElementPtr(FieldPtr, &Offset, 1);
+  Constant *StructAddr = AddressOfImpl(TREE_OPERAND(exp, 0), Folder);
+  Constant *FieldPtr = Folder.CreateBitCast(StructAddr, UnitPtrTy);
+  FieldPtr = Folder.CreateInBoundsGetElementPtr(FieldPtr, &Offset, 1);
 
   return FieldPtr;
 }
 
 /// AddressOfDecl - Return the address of a global.
-static Constant *AddressOfDecl(tree exp) {
+static Constant *AddressOfDecl(tree exp, TargetFolder &) {
   return cast<GlobalValue>(DEFINITION_LLVM(exp));
 }
 
 /// AddressOfINDIRECT_REF - Return the address of a dereference.
-static Constant *AddressOfINDIRECT_REF(tree exp) {
+static Constant *AddressOfINDIRECT_REF(tree exp, TargetFolder &Folder) {
   // The address is just the dereferenced operand.  Get it as an LLVM constant.
-  return getAsRegister(TREE_OPERAND(exp, 0));
+  return getAsRegister(TREE_OPERAND(exp, 0), Folder);
 }
 
 /// AddressOfLABEL_DECL - Return the address of a label.
-static Constant *AddressOfLABEL_DECL(tree exp) {
+static Constant *AddressOfLABEL_DECL(tree exp, TargetFolder &) {
   extern TreeToLLVM *TheTreeToLLVM;
 
   assert(TheTreeToLLVM &&
@@ -1438,12 +1477,8 @@
   return TheTreeToLLVM->AddressOfLABEL_DECL(exp);
 }
 
-/// AddressOf - Given an expression with a constant address such as a constant,
-/// a global variable or a label, returns the address.  The type of the returned
-/// is always a pointer type and, as long as 'exp' does not have void type, the
-/// type of the pointee is the memory type that corresponds to the type of exp
-/// (see ConvertType).
-Constant *AddressOf(tree exp) {
+/// AddressOfImpl - Implementation of AddressOf.
+static Constant *AddressOfImpl(tree exp, TargetFolder &Folder) {
   Constant *Addr;
 
   switch (TREE_CODE(exp)) {
@@ -1455,29 +1490,29 @@
   case REAL_CST:
   case STRING_CST:
   case VECTOR_CST:
-    Addr = AddressOfCST(exp);
+    Addr = AddressOfCST(exp, Folder);
     break;
   case ARRAY_RANGE_REF:
   case ARRAY_REF:
-    Addr = AddressOfARRAY_REF(exp);
+    Addr = AddressOfARRAY_REF(exp, Folder);
     break;
   case COMPONENT_REF:
-    Addr = AddressOfCOMPONENT_REF(exp);
+    Addr = AddressOfCOMPONENT_REF(exp, Folder);
     break;
   case COMPOUND_LITERAL_EXPR: // FIXME: not gimple - defined by C front-end
-    Addr = AddressOf(DECL_EXPR_DECL(TREE_OPERAND(exp, 0)));
+    Addr = AddressOfImpl(DECL_EXPR_DECL(TREE_OPERAND(exp, 0)), Folder);
     break;
   case CONST_DECL:
   case FUNCTION_DECL:
   case VAR_DECL:
-    Addr = AddressOfDecl(exp);
+    Addr = AddressOfDecl(exp, Folder);
     break;
   case INDIRECT_REF:
   case MISALIGNED_INDIRECT_REF:
-    Addr = AddressOfINDIRECT_REF(exp);
+    Addr = AddressOfINDIRECT_REF(exp, Folder);
     break;
   case LABEL_DECL:
-    Addr = AddressOfLABEL_DECL(exp);
+    Addr = AddressOfLABEL_DECL(exp, Folder);
     break;
   }
 
@@ -1489,5 +1524,15 @@
   else
     Ty = ConvertType(TREE_TYPE(exp))->getPointerTo();
 
-  return TheFolder->CreateBitCast(Addr, Ty);
+  return Folder.CreateBitCast(Addr, Ty);
+}
+
+/// AddressOf - Given an expression with a constant address such as a constant,
+/// a global variable or a label, returns the address.  The type of the returned
+/// is always a pointer type and, as long as 'exp' does not have void type, the
+/// type of the pointee is the memory type that corresponds to the type of exp
+/// (see ConvertType).
+Constant *AddressOf(tree exp) {
+  TargetFolder Folder(&getTargetData());
+  return AddressOfImpl(exp, Folder);
 }





More information about the llvm-commits mailing list