fix PR6623: when optimizing for size, don't inline memcpy/memsets
authorChris Lattner <sabre@nondot.org>
Mon, 31 May 2010 17:30:14 +0000 (17:30 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 31 May 2010 17:30:14 +0000 (17:30 +0000)
that are too large.  This causes the freebsd bootloader to be too
large apparently.

It's unclear if this should be an -Os or -Oz thing.  Thoughts welcome.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105228 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAG.cpp
test/CodeGen/X86/memcpy.ll

index 86e00ce6e20f4878f9c072a03385e8953827030c..c1b5ec253873560c6e66d074988fd6a8c3b486c6 100644 (file)
@@ -3266,6 +3266,15 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
     if (VT.bitsGT(LVT))
       VT = LVT;
   }
+  
+  // If we're optimizing for size, and there is a limit, bump the maximum number
+  // of operations inserted down to 4.  This is a wild guess that approximates
+  // the size of a call to memcpy or memset (3 arguments + call).
+  if (Limit != ~0U) {
+    const Function *F = DAG.getMachineFunction().getFunction();
+    if (F->hasFnAttr(Attribute::OptimizeForSize))
+      Limit = 4;
+  }
 
   unsigned NumMemOps = 0;
   while (Size != 0) {
index 16bf7c5a38c9bdd9a529190af8c73150ad7ca5e4..7bc31bec163def423d389f304c5ca0bd7eff1cce 100644 (file)
@@ -25,3 +25,33 @@ entry:
 ; CHECK: memcpy
 }
 
+; Large constant memcpy's should lower to a call when optimizing for size.
+; PR6623
+define void @test3(i8* nocapture %A, i8* nocapture %B) nounwind optsize noredzone {
+entry:
+  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false)
+  ret void
+; CHECK: test3:
+; CHECK: memcpy
+}
+
+; Large constant memcpy's should be inlined when not optimizing for size.
+define void @test4(i8* nocapture %A, i8* nocapture %B) nounwind noredzone {
+entry:
+  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A, i8* %B, i64 64, i32 1, i1 false)
+  ret void
+; CHECK: test4:
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+; CHECK: movq
+}
+