Fix for bug 8281 - Extremely slow assembling and disassembling of ptrtoint
Chenguang Wang
w3cing at gmail.com
Wed Dec 10 16:00:12 PST 2014
The constant folder calculates size of structs in a recursive manner,
which works poorly when the struct is not a tree-like structure but a
DAG. Refer to the bugzilla page for more details.
http://reviews.llvm.org/D6594
http://llvm.org/bugs/show_bug.cgi?id=8281
- Chenguang
-------------- next part --------------
diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp
index cdfb41f..962310e 100644
--- a/lib/IR/ConstantFold.cpp
+++ b/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 *ExtractConstantBytes(Constant *C, unsigned ByteStart,
///
static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy,
bool Folded) {
+ // check for previously generated folded size Constant.
+ DenseMap<Type *, Constant *> &TFS = Ty->getContext().pImpl->TypeFoldedSizes;
+ if (TFS.find(Ty) != TFS.end())
+ return TFS[Ty];
+
if (ArrayType *ATy = dyn_cast<ArrayType>(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<StructType>(Ty))
@@ -347,7 +353,7 @@ static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy,
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 @@ static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy,
}
if (AllSame) {
Constant *N = ConstantInt::get(DestTy, NumElems);
- return ConstantExpr::getNUWMul(MemberSize, N);
+ return TFS[Ty] = ConstantExpr::getNUWMul(MemberSize, N);
}
}
@@ -368,7 +374,7 @@ static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy,
// to an arbitrary pointee.
if (PointerType *PTy = dyn_cast<PointerType>(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 @@ static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy,
// 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
diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h
index 41822f0..7495e74 100644
--- a/lib/IR/LLVMContextImpl.h
+++ b/lib/IR/LLVMContextImpl.h
@@ -295,6 +295,8 @@ public:
ConstantInt *TheFalseVal;
LeakDetectorImpl<Value> LLVMObjects;
+
+ DenseMap<Type *, Constant *> TypeFoldedSizes;
// Basic type instances.
Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy;
More information about the llvm-commits
mailing list