[PATCH] D13088: [InlineCost] Adjust inlining cost for implicit null checks

Chen Li via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 13:31:01 PDT 2015


chenli updated this revision to Diff 35548.
chenli added a comment.

Update patch and test case.


http://reviews.llvm.org/D13088

Files:
  lib/Analysis/InlineCost.cpp
  test/Transforms/Inline/implicit_null_check.ll

Index: test/Transforms/Inline/implicit_null_check.ll
===================================================================
--- /dev/null
+++ test/Transforms/Inline/implicit_null_check.ll
@@ -0,0 +1,26 @@
+; RUN: opt < %s -inline -inline-threshold=6 -S | FileCheck %s
+
+define i32 @callee(i32* %x) {
+entry:
+; The comparison and implicit null check should be free.
+; The only cost is the load instruction and it is 5.
+  %cond = icmp eq i32* %x, null
+  br i1 %cond, label %is_null, label %not_null, !make.implicit !0
+
+is_null:
+  ret i32 42
+
+not_null:
+  %t = load i32, i32* %x
+  ret i32 %t
+}
+
+define i32 @caller(i32* %arg) {
+; CHECK-LABEL: @caller
+; CHECK: %cond.i = icmp eq i32* %arg, null
+  %r = call i32 @callee(i32* %arg)
+  ret i32 %r
+}
+
+!0 = !{}
+
Index: lib/Analysis/InlineCost.cpp
===================================================================
--- lib/Analysis/InlineCost.cpp
+++ lib/Analysis/InlineCost.cpp
@@ -30,6 +30,7 @@
 #include "llvm/IR/InstVisitor.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -122,6 +123,10 @@
   /// inlined through this particular callsite. 
   bool isKnownNonNullInCallee(Value *V);
 
+
+  /// Return true if all users of the comparison are marked as make_implicit.
+  bool isImplicitNullCheckCmp(CmpInst &I) ;
+
   // Custom analysis routines.
   bool analyzeBlock(BasicBlock *BB, SmallPtrSetImpl<const Value *> &EphValues);
 
@@ -541,6 +546,17 @@
   return false;
 }
 
+bool CallAnalyzer::isImplicitNullCheckCmp(CmpInst &I) {
+  for (auto User : I.users()) {
+    if (auto Instr = dyn_cast<Instruction>(User))
+      if (Instr->getMetadata(LLVMContext::MD_make_implicit))
+        continue;
+
+    return false;
+  }
+  return true;
+}
+
 bool CallAnalyzer::visitCmpInst(CmpInst &I) {
   Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
   // First try to handle simplified comparisons.
@@ -602,6 +618,13 @@
     disableSROA(CostIt);
   }
 
+  // Implicit null checks act as unconditional branches, and
+  // their comparisons should be treated as simplified and
+  // free of cost. See the comments in visitBranchInst.
+  if (I.isEquality() && isa<ConstantPointerNull>(I.getOperand(1))
+      && isImplicitNullCheckCmp(I))
+    return true;
+
   return false;
 }
 
@@ -853,9 +876,10 @@
   // shouldn't exist at all, but handling them makes the behavior of the
   // inliner more regular and predictable. Interestingly, conditional branches
   // which will fold away are also free.
-  return BI.isUnconditional() || isa<ConstantInt>(BI.getCondition()) ||
-         dyn_cast_or_null<ConstantInt>(
-             SimplifiedValues.lookup(BI.getCondition()));
+	return BI.isUnconditional() || isa<ConstantInt>(BI.getCondition()) ||
+	       BI.getMetadata(LLVMContext::MD_make_implicit) ||
+		     dyn_cast_or_null<ConstantInt>(
+		         SimplifiedValues.lookup(BI.getCondition()));
 }
 
 bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13088.35548.patch
Type: text/x-patch
Size: 3042 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150923/88f284a0/attachment.bin>


More information about the llvm-commits mailing list