From: Nick Desaulniers Date: Tue, 24 Jan 2023 22:54:50 +0000 (-0800) Subject: [InlineCost] model calls to llvm.objectsize.* X-Git-Tag: upstream/17.0.6~19743 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f1764d5b594ff6edbf8d17d196eb0b7a653ac0fc;p=platform%2Fupstream%2Fllvm.git [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: https://github.com/ClangBuiltLinux/linux/issues/1302 Reviewed By: manojgupta Differential Revision: https://reviews.llvm.org/D111456 --- diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index bce71b2..5bcc8a2 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -22,6 +22,7 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -419,6 +420,7 @@ protected: bool simplifyCallSite(Function *F, CallBase &Call); bool simplifyInstruction(Instruction &I); bool simplifyIntrinsicCallIsConstant(CallBase &CB); + bool simplifyIntrinsicCallObjectSize(CallBase &CB); ConstantInt *stripAndComputeInBoundsConstantOffsets(Value *&V); /// Return true if the given argument to the function being considered for @@ -1602,6 +1604,20 @@ bool CallAnalyzer::simplifyIntrinsicCallIsConstant(CallBase &CB) { return true; } +bool CallAnalyzer::simplifyIntrinsicCallObjectSize(CallBase &CB) { + // As per the langref, "The fourth argument to llvm.objectsize determines if + // the value should be evaluated at runtime." + if(cast(CB.getArgOperand(3))->isOne()) + return false; + + Value *V = lowerObjectSizeCall(&cast(CB), DL, nullptr, + /*MustSucceed=*/true); + Constant *C = dyn_cast_or_null(V); + if (C) + SimplifiedValues[&CB] = C; + return C; +} + bool CallAnalyzer::visitBitCast(BitCastInst &I) { // Propagate constants through bitcasts. if (simplifyInstruction(I)) @@ -2214,6 +2230,8 @@ bool CallAnalyzer::visitCallBase(CallBase &Call) { return true; case Intrinsic::is_constant: return simplifyIntrinsicCallIsConstant(Call); + case Intrinsic::objectsize: + return simplifyIntrinsicCallObjectSize(Call); } } diff --git a/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll b/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll new file mode 100644 index 0000000..bdbbb10 --- /dev/null +++ b/llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll @@ -0,0 +1,50 @@ +; RUN: opt -passes=inline -S %s -inline-threshold=20 2>&1 | FileCheck %s + +%struct.nodemask_t = type { [16 x i64] } +@numa_nodes_parsed = external constant %struct.nodemask_t, align 8 + +declare void @foo() +declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) + +; Test that we inline @callee into @caller. +define i64 @caller() { +; CHECK-LABEL: @caller( +; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], 128 +; CHECK-NEXT: br i1 [[TMP2]], label %[[CALLEE_EXIT:.*]], label %[[HANDLER_TYPE_MISMATCH94_I:.*]] +; CHECK: [[HANDLER_TYPE_MISMATCH94_I]]: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label %[[CALLEE_EXIT]] +; CHECK: [[CALLEE_EXIT]]: +; CHECK-NEXT: ret i64 [[TMP1]] +; + %1 = tail call i64 @callee() + ret i64 %1 +} + +; Testing the InlineCost of the call to @llvm.objectsize.i64.p0i8. +; Do not change the linkage of @callee; that will give it a severe discount in +; cost (LastCallToStaticBonus). +define i64 @callee() { + %1 = tail call i64 @llvm.objectsize.i64.p0(ptr @numa_nodes_parsed, i1 false, i1 false, i1 false) + %2 = icmp uge i64 %1, 128 + br i1 %2, label %cont95, label %handler.type_mismatch94 + +handler.type_mismatch94: + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + call void @foo() + br label %cont95 + +cont95: + ret i64 %1 +} +