[llvm] d163e75 - [Attributor] Enable heap-to-stack of any size
William S. Moses via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 6 10:18:46 PST 2021
Author: William S. Moses
Date: 2021-03-06T12:57:32-05:00
New Revision: d163e75c81c1609855b98cbdffa0141c70d8578d
URL: https://github.com/llvm/llvm-project/commit/d163e75c81c1609855b98cbdffa0141c70d8578d
DIFF: https://github.com/llvm/llvm-project/commit/d163e75c81c1609855b98cbdffa0141c70d8578d.diff
LOG: [Attributor] Enable heap-to-stack of any size
Enable Attributor's heap-to-stack to lower unbounded allocations given a max size of -1
Differential Revision: https://reviews.llvm.org/D97873
Added:
llvm/test/Transforms/Attributor/lowerheap.ll
Modified:
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 4157be82ffdf..1c0fbdb8cba0 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -5004,21 +5004,20 @@ struct AAHeapToStackImpl : public AAHeapToStack {
<< "\n");
Align Alignment;
- Constant *Size;
+ Value *Size;
if (isCallocLikeFn(MallocCall, TLI)) {
- auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
- auto *SizeT = cast<ConstantInt>(MallocCall->getOperand(1));
- APInt TotalSize = SizeT->getValue() * Num->getValue();
- Size =
- ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
+ auto *Num = MallocCall->getOperand(0);
+ auto *SizeT = MallocCall->getOperand(1);
+ IRBuilder<> B(MallocCall);
+ Size = B.CreateMul(Num, SizeT, "h2s.calloc.size");
} else if (isAlignedAllocLikeFn(MallocCall, TLI)) {
- Size = cast<ConstantInt>(MallocCall->getOperand(1));
+ Size = MallocCall->getOperand(1);
Alignment = MaybeAlign(cast<ConstantInt>(MallocCall->getOperand(0))
->getValue()
.getZExtValue())
.valueOrOne();
} else {
- Size = cast<ConstantInt>(MallocCall->getOperand(0));
+ Size = MallocCall->getOperand(0);
}
unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
@@ -5166,6 +5165,12 @@ ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
}
if (IsMalloc) {
+ if (MaxHeapToStackSize == -1) {
+ if (UsesCheck(I) || FreeCheck(I)) {
+ MallocCalls.insert(&I);
+ return true;
+ }
+ }
if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
if (Size->getValue().ule(MaxHeapToStackSize))
if (UsesCheck(I) || FreeCheck(I)) {
@@ -5173,6 +5178,12 @@ ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
return true;
}
} else if (IsAlignedAllocLike && isa<ConstantInt>(I.getOperand(0))) {
+ if (MaxHeapToStackSize == -1) {
+ if (UsesCheck(I) || FreeCheck(I)) {
+ MallocCalls.insert(&I);
+ return true;
+ }
+ }
// Only if the alignment and sizes are constant.
if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
if (Size->getValue().ule(MaxHeapToStackSize))
@@ -5181,6 +5192,12 @@ ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
return true;
}
} else if (IsCalloc) {
+ if (MaxHeapToStackSize == -1) {
+ if (UsesCheck(I) || FreeCheck(I)) {
+ MallocCalls.insert(&I);
+ return true;
+ }
+ }
bool Overflow = false;
if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
diff --git a/llvm/test/Transforms/Attributor/lowerheap.ll b/llvm/test/Transforms/Attributor/lowerheap.ll
new file mode 100644
index 000000000000..d8b5ce7b40a3
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/lowerheap.ll
@@ -0,0 +1,63 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
+; RUN: opt -max-heap-to-stack-size=-1 -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
+; RUN: opt -max-heap-to-stack-size=-1 -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
+; RUN: opt -max-heap-to-stack-size=-1 -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
+; RUN: opt -max-heap-to-stack-size=-1 -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
+
+declare i64 @subfn(i8*) #0
+
+declare noalias i8* @malloc(i64)
+declare noalias i8* @calloc(i64, i64)
+declare void @free(i8*)
+
+define i64 @f(i64 %len) {
+; IS________OPM-LABEL: define {{[^@]+}}@f
+; IS________OPM-SAME: (i64 [[LEN:%.*]]) {
+; IS________OPM-NEXT: entry:
+; IS________OPM-NEXT: [[MEM:%.*]] = call noalias i8* @malloc(i64 [[LEN]])
+; IS________OPM-NEXT: [[RES:%.*]] = call i64 @subfn(i8* [[MEM]]) [[ATTR1:#.*]]
+; IS________OPM-NEXT: call void @free(i8* [[MEM]])
+; IS________OPM-NEXT: ret i64 [[RES]]
+;
+; IS________NPM-LABEL: define {{[^@]+}}@f
+; IS________NPM-SAME: (i64 [[LEN:%.*]]) {
+; IS________NPM-NEXT: entry:
+; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 [[LEN]], align 1
+; IS________NPM-NEXT: [[RES:%.*]] = call i64 @subfn(i8* [[TMP0]]) [[ATTR2:#.*]]
+; IS________NPM-NEXT: ret i64 [[RES]]
+;
+entry:
+ %mem = call i8* @malloc(i64 %len)
+ %res = call i64 @subfn(i8* %mem)
+ call void @free(i8* %mem)
+ ret i64 %res
+}
+
+
+define i64 @g(i64 %len) {
+; IS________OPM-LABEL: define {{[^@]+}}@g
+; IS________OPM-SAME: (i64 [[LEN:%.*]]) {
+; IS________OPM-NEXT: entry:
+; IS________OPM-NEXT: [[MEM:%.*]] = call noalias i8* @calloc(i64 [[LEN]], i64 noundef 8)
+; IS________OPM-NEXT: [[RES:%.*]] = call i64 @subfn(i8* [[MEM]]) [[ATTR1]]
+; IS________OPM-NEXT: call void @free(i8* [[MEM]])
+; IS________OPM-NEXT: ret i64 [[RES]]
+;
+; IS________NPM-LABEL: define {{[^@]+}}@g
+; IS________NPM-SAME: (i64 [[LEN:%.*]]) {
+; IS________NPM-NEXT: entry:
+; IS________NPM-NEXT: [[TMP0:%.*]] = mul i64 [[LEN]], 8
+; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[TMP0]], align 1
+; IS________NPM-NEXT: [[CALLOC_BC:%.*]] = bitcast i8* [[TMP1]] to i8*
+; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[CALLOC_BC]], i8 0, i64 [[TMP0]], i1 false)
+; IS________NPM-NEXT: [[RES:%.*]] = call i64 @subfn(i8* [[TMP1]]) [[ATTR2]]
+; IS________NPM-NEXT: ret i64 [[RES]]
+;
+entry:
+ %mem = call i8* @calloc(i64 %len, i64 8)
+ %res = call i64 @subfn(i8* %mem)
+ call void @free(i8* %mem)
+ ret i64 %res
+}
+
+attributes #0 = { nounwind willreturn }
More information about the llvm-commits
mailing list