diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index d1b21fd..f3a44fe 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -446,6 +446,8 @@ def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">,
   HelpText<"Defines the __DEPRECATED macro">;
 def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">,
   HelpText<"Undefines the __DEPRECATED macro">;
+def finstrument_functions_size : Separate<["-"], "finstrument-functions-size">,
+  HelpText<"Minimum size of functions to instrument">;
 
 //===----------------------------------------------------------------------===//
 // Header Search Options
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index dd2ef31..f6a6781 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -475,6 +475,8 @@ def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_f_
 def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
 def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Generate calls to instrument function entry and exit">;
+def finstrument_functions_size_EQ : Joined<["-"], "finstrument-functions-size=">, Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Set a minimum number of basic blocks for function instrumentation">;
 def fkeep_inline_functions : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>;
 def flat__namespace : Flag<["-"], "flat_namespace">;
 def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index bbb75ab..b3fa05f 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -58,6 +58,9 @@ CODEGENOPT(HiddenWeakVTables , 1, 0) ///< Emit weak vtables, RTTI, and thunks wi
                                      ///< hidden visibility.
 CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
                                        ///< enabled.
+VALUE_CODEGENOPT(InstrumentFunctionsSize, 32, 0) ///< If set, only functions with
+                                                 ///< at least this many basic
+                                                 ///< blocks are instrumented.
 CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
 CODEGENOPT(LessPreciseFPMAD  , 1, 0) ///< Enable less precise MAD instructions to
                                      ///< be generated.
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index e2a18d3..aa291d4 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -187,8 +187,18 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
   // Emit function epilog (to return).
   EmitReturnBlock();
 
-  if (ShouldInstrumentFunction())
-    EmitFunctionInstrumentation("__cyg_profile_func_exit");
+  if (ShouldInstrumentFunction()) {
+      // The size of the function isn't known during StartFunction, so in order
+      // to instrument selectively based on function size, we need to wait
+      // until the end and insert both the entry and exit instrumentation
+      llvm::BasicBlock *CurBlock = Builder.GetInsertBlock();
+      llvm::BasicBlock *BeginBlock = &CurFn->getEntryBlock();
+
+      Builder.SetInsertPoint(BeginBlock, BeginBlock->begin());
+      EmitFunctionInstrumentation("__cyg_profile_func_enter");
+      Builder.SetInsertPoint(CurBlock);
+      EmitFunctionInstrumentation("__cyg_profile_func_exit");
+  }
 
   // Emit debug descriptor for function end.
   if (CGDebugInfo *DI = getDebugInfo()) {
@@ -239,7 +249,10 @@ bool CodeGenFunction::ShouldInstrumentFunction() {
     return false;
   if (!CurFuncDecl || CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>())
     return false;
-  return true;
+
+  // If not specified, defaults to 0.
+  int Size = CGM.getCodeGenOpts().InstrumentFunctionsSize;
+  return CurFn->getBasicBlockList().size() >= Size;
 }
 
 /// EmitFunctionInstrumentation - Emit LLVM code to call the specified
@@ -409,9 +422,6 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
     DI->EmitFunctionStart(GD, FnType, CurFn, Builder);
   }
 
-  if (ShouldInstrumentFunction())
-    EmitFunctionInstrumentation("__cyg_profile_func_enter");
-
   if (CGM.getCodeGenOpts().InstrumentForProfiling)
     EmitMCountInstrumentation();
 
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index eac4bc6..6f44b9a 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -2317,6 +2317,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 
   Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
 
+  if (Arg *A = Args.getLastArg(options::OPT_finstrument_functions_size_EQ)) {
+    CmdArgs.push_back("-finstrument-functions-size");
+    CmdArgs.push_back(A->getValue());
+  }
+
   if (Args.hasArg(options::OPT_ftest_coverage) ||
       Args.hasArg(options::OPT_coverage))
     CmdArgs.push_back("-femit-coverage-notes");
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index d856c31..1c638ed 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -381,6 +381,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
   Opts.SanitizeRecover = !Args.hasArg(OPT_fno_sanitize_recover);
 
   Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
+  Opts.InstrumentFunctionsSize =
+    Args.getLastArgIntValue(OPT_finstrument_functions_size, 0);
   Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
   Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data);
   Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);
diff --git a/test/CodeGen/instrument-functions-size.c b/test/CodeGen/instrument-functions-size.c
new file mode 100644
index 0000000..d7905a9
--- /dev/null
+++ b/test/CodeGen/instrument-functions-size.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions -finstrument-functions-size 2 | FileCheck %s
+
+// CHECK: define i32 @test1
+int test1(int x) {
+// CHECK-NOT: __cyg_profile_func_enter
+// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: ret i32
+  return x;
+}
+
+// CHECK: define i32 @test2
+int test2(int) __attribute__((no_instrument_function));
+int test2(int x) {
+  if(x) {test1(x);}
+// CHECK-NOT: __cyg_profile_func_enter
+// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: ret i32
+  return x;
+}
+
+// CHECK: define i32 @test3
+int test3(int x) {
+  if(x) {test1(x);}
+// CHECK: __cyg_profile_func_enter
+// CHECK: __cyg_profile_func_exit
+// CHECK: ret i32
+  return x;
+}
diff --git a/test/CodeGen/instrument-functions.c b/test/CodeGen/instrument-functions.c
index d80385e..41275c7 100644
--- a/test/CodeGen/instrument-functions.c
+++ b/test/CodeGen/instrument-functions.c
@@ -1,18 +1,18 @@
 // RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s
 
-// CHECK: @test1
+// CHECK: define i32 @test1
 int test1(int x) {
 // CHECK: __cyg_profile_func_enter
 // CHECK: __cyg_profile_func_exit
-// CHECK: ret
+// CHECK: ret i32
   return x;
 }
 
-// CHECK: @test2
+// CHECK: define i32 @test2
 int test2(int) __attribute__((no_instrument_function));
 int test2(int x) {
 // CHECK-NOT: __cyg_profile_func_enter
 // CHECK-NOT: __cyg_profile_func_exit
-// CHECK: ret
+// CHECK: ret i32
   return x;
 }
diff --git a/test/CodeGenCXX/instrument-functions-size.cpp b/test/CodeGenCXX/instrument-functions-size.cpp
new file mode 100644
index 0000000..6fcb839
--- /dev/null
+++ b/test/CodeGenCXX/instrument-functions-size.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions -finstrument-functions-size 2 | FileCheck %s
+
+// CHECK: define i32 @_Z5test1i
+int test1(int x) {
+// CHECK-NOT: __cyg_profile_func_enter
+// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: ret i32
+  return x;
+}
+
+// CHECK: define i32 @_Z5test2i
+int test2(int) __attribute__((no_instrument_function));
+int test2(int x) {
+  if(x) {test1(x);}
+// CHECK-NOT: __cyg_profile_func_enter
+// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: ret i32
+  return x;
+}
+
+// CHECK: define i32 @_Z5test3i
+int test3(int x) {
+  if(x) {test1(x);}
+// CHECK: __cyg_profile_func_enter
+// CHECK: __cyg_profile_func_exit
+// CHECK: ret i32
+  return x;
+}
diff --git a/test/CodeGenCXX/instrument-functions.cpp b/test/CodeGenCXX/instrument-functions.cpp
index 253e096..35d35dd 100644
--- a/test/CodeGenCXX/instrument-functions.cpp
+++ b/test/CodeGenCXX/instrument-functions.cpp
@@ -1,19 +1,19 @@
 // RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s
 
-// CHECK: @_Z5test1i
+// CHECK: define i32 @_Z5test1i
 int test1(int x) {
 // CHECK: __cyg_profile_func_enter
 // CHECK: __cyg_profile_func_exit
-// CHECK: ret
+// CHECK: ret i32
   return x;
 }
 
-// CHECK: @_Z5test2i
+// CHECK: define i32 @_Z5test2i
 int test2(int) __attribute__((no_instrument_function));
 int test2(int x) {
 // CHECK-NOT: __cyg_profile_func_enter
 // CHECK-NOT: __cyg_profile_func_exit
-// CHECK: ret
+// CHECK: ret i32
   return x;
 }
 
