Skip to content

Commit f1764d5

Browse files
[InlineCost] model calls to llvm.objectsize.*
Very similar to https://reviews.llvm.org/D111272. We very often can evaluate calls to llvm.objectsize.* regardless of inlining. Don't count calls to llvm.objectsize.* against the InlineCost when we can evaluate the call to a constant. Link: ClangBuiltLinux/linux#1302 Reviewed By: manojgupta Differential Revision: https://reviews.llvm.org/D111456
1 parent 7532e88 commit f1764d5

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

llvm/lib/Analysis/InlineCost.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/Analysis/ConstantFolding.h"
2323
#include "llvm/Analysis/InstructionSimplify.h"
2424
#include "llvm/Analysis/LoopInfo.h"
25+
#include "llvm/Analysis/MemoryBuiltins.h"
2526
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
2627
#include "llvm/Analysis/ProfileSummaryInfo.h"
2728
#include "llvm/Analysis/TargetLibraryInfo.h"
@@ -419,6 +420,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
419420
bool simplifyCallSite(Function *F, CallBase &Call);
420421
bool simplifyInstruction(Instruction &I);
421422
bool simplifyIntrinsicCallIsConstant(CallBase &CB);
423+
bool simplifyIntrinsicCallObjectSize(CallBase &CB);
422424
ConstantInt *stripAndComputeInBoundsConstantOffsets(Value *&V);
423425

424426
/// Return true if the given argument to the function being considered for
@@ -1602,6 +1604,20 @@ bool CallAnalyzer::simplifyIntrinsicCallIsConstant(CallBase &CB) {
16021604
return true;
16031605
}
16041606

1607+
bool CallAnalyzer::simplifyIntrinsicCallObjectSize(CallBase &CB) {
1608+
// As per the langref, "The fourth argument to llvm.objectsize determines if
1609+
// the value should be evaluated at runtime."
1610+
if(cast<ConstantInt>(CB.getArgOperand(3))->isOne())
1611+
return false;
1612+
1613+
Value *V = lowerObjectSizeCall(&cast<IntrinsicInst>(CB), DL, nullptr,
1614+
/*MustSucceed=*/true);
1615+
Constant *C = dyn_cast_or_null<Constant>(V);
1616+
if (C)
1617+
SimplifiedValues[&CB] = C;
1618+
return C;
1619+
}
1620+
16051621
bool CallAnalyzer::visitBitCast(BitCastInst &I) {
16061622
// Propagate constants through bitcasts.
16071623
if (simplifyInstruction(I))
@@ -2214,6 +2230,8 @@ bool CallAnalyzer::visitCallBase(CallBase &Call) {
22142230
return true;
22152231
case Intrinsic::is_constant:
22162232
return simplifyIntrinsicCallIsConstant(Call);
2233+
case Intrinsic::objectsize:
2234+
return simplifyIntrinsicCallObjectSize(Call);
22172235
}
22182236
}
22192237

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; RUN: opt -passes=inline -S %s -inline-threshold=20 2>&1 | FileCheck %s
2+
3+
%struct.nodemask_t = type { [16 x i64] }
4+
@numa_nodes_parsed = external constant %struct.nodemask_t, align 8
5+
6+
declare void @foo()
7+
declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg)
8+
9+
; Test that we inline @callee into @caller.
10+
define i64 @caller() {
11+
; CHECK-LABEL: @caller(
12+
; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false)
13+
; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 128
14+
; CHECK-NEXT: br i1 [[TMP2]], label %[[CALLEE_EXIT:.*]], label %[[HANDLER_TYPE_MISMATCH94_I:.*]]
15+
; CHECK: [[HANDLER_TYPE_MISMATCH94_I]]:
16+
; CHECK-NEXT: call void @foo()
17+
; CHECK-NEXT: call void @foo()
18+
; CHECK-NEXT: call void @foo()
19+
; CHECK-NEXT: call void @foo()
20+
; CHECK-NEXT: call void @foo()
21+
; CHECK-NEXT: call void @foo()
22+
; CHECK-NEXT: br label %[[CALLEE_EXIT]]
23+
; CHECK: [[CALLEE_EXIT]]:
24+
; CHECK-NEXT: ret i64 [[TMP1]]
25+
;
26+
%1 = tail call i64 @callee()
27+
ret i64 %1
28+
}
29+
30+
; Testing the InlineCost of the call to @llvm.objectsize.i64.p0i8.
31+
; Do not change the linkage of @callee; that will give it a severe discount in
32+
; cost (LastCallToStaticBonus).
33+
define i64 @callee() {
34+
%1 = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false)
35+
%2 = icmp uge i64 %1, 128
36+
br i1 %2, label %cont95, label %handler.type_mismatch94
37+
38+
handler.type_mismatch94:
39+
call void @foo()
40+
call void @foo()
41+
call void @foo()
42+
call void @foo()
43+
call void @foo()
44+
call void @foo()
45+
br label %cont95
46+
47+
cont95:
48+
ret i64 %1
49+
}
50+

0 commit comments

Comments
 (0)