Index: llvm/lib/IR/ConstantFold.cpp =================================================================== --- llvm/lib/IR/ConstantFold.cpp +++ llvm/lib/IR/ConstantFold.cpp @@ -17,6 +17,7 @@ //===----------------------------------------------------------------------===// #include "ConstantFold.h" +#include "LLVMContextImpl.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" #include "llvm/IR/Constants.h" @@ -353,10 +354,15 @@ /// possible, to avoid endlessly bouncing an unfoldable expression back into the /// top-level folder. 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)) @@ -364,7 +370,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); @@ -377,7 +383,7 @@ } if (AllSame) { Constant *N = ConstantInt::get(DestTy, NumElems); - return ConstantExpr::getNUWMul(MemberSize, N); + return TFS[Ty] = ConstantExpr::getNUWMul(MemberSize, N); } } @@ -385,7 +391,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); @@ -393,14 +399,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; } /// Return a ConstantExpr with type DestTy for alignof on Ty, with any known Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -1415,6 +1415,8 @@ std::unique_ptr TheNoneToken; + DenseMap TypeFoldedSizes; + // Basic type instances. Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy, TokenTy;