aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorTim Shen <timshen@google.com>2021-02-19 12:19:34 -0800
committerTim Shen <timshen@google.com>2021-02-19 12:44:17 -0800
commita0757d8ebdefa1c54896d70d2a04f68fc23f7916 (patch)
tree43efc6e3c6b549073f26395fdaa1080ea43c6a45 /llvm/lib/IR/ConstantFold.cpp
parentf99ccf6516bdd5def4d3bc311330aec92f5cb99d (diff)
downloadllvm-a0757d8ebdefa1c54896d70d2a04f68fc23f7916.zip
llvm-a0757d8ebdefa1c54896d70d2a04f68fc23f7916.tar.gz
llvm-a0757d8ebdefa1c54896d70d2a04f68fc23f7916.tar.bz2
Patch by @wecing (Chenguang Wang).
The current getFoldedSizeOf() implementation uses naive recursion, which could be really slow when the input structure type is too complex. This issue was first brought up in http://llvm.org/bugs/show_bug.cgi?id=8281; this change fixes it by adding memoization. Differential Revision: https://reviews.llvm.org/D6594
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp38
1 files changed, 30 insertions, 8 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 95dd552..6d2770a 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -348,14 +348,22 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart,
}
}
+/// Wrapper around getFoldedSizeOfImpl() that adds caching.
+static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, bool Folded,
+ DenseMap<Type *, Constant *> &Cache);
+
/// Return a ConstantExpr with type DestTy for sizeof on Ty, with any known
/// factors factored out. If Folded is false, return null if no factoring was
/// possible, to avoid endlessly bouncing an unfoldable expression back into the
/// top-level folder.
-static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, bool Folded) {
+static Constant *getFoldedSizeOfImpl(Type *Ty, Type *DestTy, bool Folded,
+ DenseMap<Type *, Constant *> &Cache) {
+ // This is the actual implementation of getFoldedSizeOf(). To get the caching
+ // behavior, we need to call getFoldedSizeOf() when we recurse.
+
if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Constant *N = ConstantInt::get(DestTy, ATy->getNumElements());
- Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+ Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true, Cache);
return ConstantExpr::getNUWMul(E, N);
}
@@ -367,11 +375,11 @@ static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, bool Folded) {
return ConstantExpr::getNullValue(DestTy);
// Check for a struct with all members having the same size.
Constant *MemberSize =
- getFoldedSizeOf(STy->getElementType(0), DestTy, true);
+ getFoldedSizeOf(STy->getElementType(0), DestTy, true, Cache);
bool AllSame = true;
for (unsigned i = 1; i != NumElems; ++i)
if (MemberSize !=
- getFoldedSizeOf(STy->getElementType(i), DestTy, true)) {
+ getFoldedSizeOf(STy->getElementType(i), DestTy, true, Cache)) {
AllSame = false;
break;
}
@@ -385,10 +393,10 @@ static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, bool Folded) {
// to an arbitrary pointee.
if (PointerType *PTy = dyn_cast<PointerType>(Ty))
if (!PTy->getElementType()->isIntegerTy(1))
- return
- getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1),
- PTy->getAddressSpace()),
- DestTy, true);
+ return getFoldedSizeOf(
+ PointerType::get(IntegerType::get(PTy->getContext(), 1),
+ PTy->getAddressSpace()),
+ DestTy, true, Cache);
// 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.
@@ -403,6 +411,20 @@ static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, bool Folded) {
return C;
}
+static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, bool Folded,
+ DenseMap<Type *, Constant *> &Cache) {
+ // Check for previously generated folded size constant.
+ auto It = Cache.find(Ty);
+ if (It != Cache.end())
+ return It->second;
+ return Cache[Ty] = getFoldedSizeOfImpl(Ty, DestTy, Folded, Cache);
+}
+
+static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy, bool Folded) {
+ DenseMap<Type *, Constant *> Cache;
+ return getFoldedSizeOf(Ty, DestTy, Folded, Cache);
+}
+
/// Return a ConstantExpr with type DestTy for alignof on Ty, with any known
/// factors factored out. If Folded is false, return null if no factoring was
/// possible, to avoid endlessly bouncing an unfoldable expression back into the