Index: include/llvm/Analysis/InlineCost.h =================================================================== --- include/llvm/Analysis/InlineCost.h +++ include/llvm/Analysis/InlineCost.h @@ -33,6 +33,7 @@ const int IndirectCallThreshold = 100; const int CallPenalty = 25; const int LastCallToStaticBonus = -15000; + const int LastCallToLinkOnceODRBonus = -15000; const int ColdccPenalty = 2000; const int NoreturnPenalty = 10000; /// Do not inline functions which allocate this many bytes on the stack Index: lib/Analysis/InlineCost.cpp =================================================================== --- lib/Analysis/InlineCost.cpp +++ lib/Analysis/InlineCost.cpp @@ -45,7 +45,7 @@ const int OptSizeThreshold = 75; // Threshold to use when -Oz is specified (and there is no -inline-threshold). -const int OptMinSizeThreshold = 25; +const int OptMinSizeThreshold = 0; // Threshold to use when -O[34] is specified (and there is no // -inline-threshold). @@ -1256,10 +1256,15 @@ // If there is only one call of the function, and it has internal linkage, // the cost of inlining it drops dramatically. bool OnlyOneCallAndLocalLinkage = - F.hasLocalLinkage() && F.hasOneUse() && &F == CS.getCalledFunction(); + F.hasLocalLinkage() && F.hasOneUse() && &F == CS.getCalledFunction(); if (OnlyOneCallAndLocalLinkage) Cost += InlineConstants::LastCallToStaticBonus; + bool OnlyOneCallAndODRLinkage = + F.hasLinkOnceODRLinkage() && F.hasOneUse() && &F == CS.getCalledFunction(); + if (OnlyOneCallAndODRLinkage) + Cost += InlineConstants::LastCallToLinkOnceODRBonus; + // If this function uses the coldcc calling convention, prefer not to inline // it. if (F.getCallingConv() == CallingConv::Cold) Index: test/Transforms/Inline/ephemeral.ll =================================================================== --- test/Transforms/Inline/ephemeral.ll +++ test/Transforms/Inline/ephemeral.ll @@ -1,32 +1,30 @@ -; RUN: opt -S -Oz %s | FileCheck %s +; RUN: opt -S -inline %s | FileCheck %s @a = global i32 4 -define i1 @inner() { - %a1 = load volatile i32, i32* @a +define i32 @inner() minsize optsize { + %a1 = load i32, i32* @a %x1 = add i32 %a1, %a1 - %c = icmp eq i32 %x1, 0 ; Here are enough instructions to prevent inlining, but because they are used ; only by the @llvm.assume intrinsic, they're free (and, thus, inlining will ; still happen). %a2 = mul i32 %a1, %a1 - %a3 = sub i32 %a1, 5 + %a3 = sub i32 %a2, 5 %a4 = udiv i32 %a3, -13 %a5 = mul i32 %a4, %a4 %a6 = add i32 %a5, %x1 %ca = icmp sgt i32 %a6, -7 tail call void @llvm.assume(i1 %ca) - ret i1 %c + ret i32 %a1 } ; @inner() should be inlined for -Oz. ; CHECK-NOT: call i1 @inner -define i1 @outer() optsize { - %r = call i1 @inner() - ret i1 %r +define i32 @outer() minsize optsize { + %r = call i32 @inner() + ret i32 %r } declare void @llvm.assume(i1) nounwind - Index: test/Transforms/Inline/inline-fp.ll =================================================================== --- test/Transforms/Inline/inline-fp.ll +++ test/Transforms/Inline/inline-fp.ll @@ -132,5 +132,5 @@ declare float @llvm.pow.f32(float, float) optsize minsize -attributes #0 = { minsize optsize } -attributes #1 = { minsize optsize "use-soft-float"="true" } +attributes #0 = { optsize } +attributes #1 = { optsize "use-soft-float"="true" } Index: test/Transforms/Inline/inline_linkonceodr.ll =================================================================== --- /dev/null +++ test/Transforms/Inline/inline_linkonceodr.ll @@ -0,0 +1,16 @@ +; RUN: opt < %s -inline -inline-threshold=0 -S | FileCheck %s + +define linkonce_odr i32 @callee1(i32 %A, i32 %B) { + %C = sdiv i32 %A, %B + %D = sdiv i32 %A, %C + %E = sdiv i32 %A, %D + ret i32 %E +} + +define i32 @caller1(i32 %a, i32 %b) minsize { +; CHECK-LABEL: define i32 @caller1( +; CHECK-NEXT: sdiv + + %X = call i32 @callee1( i32 %a, i32 %b ) + ret i32 %X +}