Index: lib/IR/ConstantFold.cpp =================================================================== --- lib/IR/ConstantFold.cpp +++ lib/IR/ConstantFold.cpp @@ -18,6 +18,7 @@ //===----------------------------------------------------------------------===// #include "ConstantFold.h" +#include "LLVMContextImpl.h" #include "llvm/ADT/SmallVector.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" @@ -336,10 +337,15 @@ /// static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, bool Folded) { + // check for previously generated folded size Constant. + DenseMap &TFS = Ty->getContext().pImpl->TypeFoldedSizes; + if (TFS.find(Ty) != TFS.end()) + return TFS[Ty]; + if (ArrayType *ATy = dyn_cast(Ty)) { Constant *N = ConstantInt::get(DestTy, ATy->getNumElements()); Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true); - return ConstantExpr::getNUWMul(E, N); + return TFS[Ty] = ConstantExpr::getNUWMul(E, N); } if (StructType *STy = dyn_cast(Ty)) @@ -347,7 +353,7 @@ unsigned NumElems = STy->getNumElements(); // An empty struct has size zero. if (NumElems == 0) - return ConstantExpr::getNullValue(DestTy); + return TFS[Ty] = ConstantExpr::getNullValue(DestTy); // Check for a struct with all members having the same size. Constant *MemberSize = getFoldedSizeOf(STy->getElementType(0), DestTy, true); @@ -360,7 +366,7 @@ } if (AllSame) { Constant *N = ConstantInt::get(DestTy, NumElems); - return ConstantExpr::getNUWMul(MemberSize, N); + return TFS[Ty] = ConstantExpr::getNUWMul(MemberSize, N); } } @@ -368,7 +374,7 @@ // to an arbitrary pointee. if (PointerType *PTy = dyn_cast(Ty)) if (!PTy->getElementType()->isIntegerTy(1)) - return + return TFS[Ty] = getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1), PTy->getAddressSpace()), DestTy, true); @@ -376,14 +382,14 @@ // If there's no interesting folding happening, bail so that we don't create // a constant that looks like it needs folding but really doesn't. if (!Folded) - return nullptr; + return TFS[Ty] = nullptr; // Base case: Get a regular sizeof expression. Constant *C = ConstantExpr::getSizeOf(Ty); C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false, DestTy, false), C, DestTy); - return C; + return TFS[Ty] = C; } /// getFoldedAlignOf - Return a ConstantExpr with type DestTy for alignof Index: lib/IR/LLVMContextImpl.h =================================================================== --- lib/IR/LLVMContextImpl.h +++ lib/IR/LLVMContextImpl.h @@ -295,6 +295,8 @@ ConstantInt *TheFalseVal; LeakDetectorImpl LLVMObjects; + + DenseMap TypeFoldedSizes; // Basic type instances. Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy;