diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index ca4bd2a1366010..21321d7c69a480 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2550,8 +2550,9 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.genFPorder = true; opts.genFPopt = true; - opts.instrCount = 0; - opts.lvRefCount = 0; + opts.instrCount = 0; + opts.callInstrCount = 0; + opts.lvRefCount = 0; #ifdef PROFILING_SUPPORTED opts.compJitELTHookEnabled = false; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 9a2305d3eefb1c..e1fe40fbff91d7 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9913,8 +9913,9 @@ class Compiler compSupportsISA = isas; } - unsigned compFlags; // method attributes - unsigned instrCount = 0; + unsigned compFlags; // method attributes + unsigned instrCount = 0; // number of IL opcodes + unsigned callInstrCount = 0; // number of IL opcodes (calls only). unsigned lvRefCount; codeOptimize compCodeOpt; // what type of code optimizations diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 4fa17a9c6c8207..76f841f8b2e275 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -3171,6 +3171,7 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case CEE_CALLVIRT: case CEE_CALLI: { + opts.callInstrCount++; if (compIsForInlining() || // Ignore tail call in the inlinee. Period. (!tailCall && !compTailCallStress()) // A new BB with BBJ_RETURN would have been created @@ -3289,6 +3290,7 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed // These ctrl-flow opcodes don't need any special handling case CEE_NEWOBJ: // CTRL_CALL + opts.callInstrCount++; break; // what's left are forgotten instructions diff --git a/src/coreclr/jit/fgprofilesynthesis.cpp b/src/coreclr/jit/fgprofilesynthesis.cpp index 1e90c43c81b824..5c1693315ab9a7 100644 --- a/src/coreclr/jit/fgprofilesynthesis.cpp +++ b/src/coreclr/jit/fgprofilesynthesis.cpp @@ -249,14 +249,23 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option) m_comp->fgPgoSynthesized = true; m_comp->fgPgoConsistent = !m_approximate; - // A simple check whether the current method has more than one edge. - m_comp->fgPgoSingleEdge = true; - for (BasicBlock* const block : m_comp->Blocks()) + // If a method has just one edge, we simulate having PGO data for it since we typically + // don't instrument such methods. To avoid giving excessive inlining boost to large and/or + // infrequently executed methods, we apply the following heuristics to exclude: + // + const bool preferSize = m_comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT); + const bool isCctor = (m_comp->info.compFlags & FLG_CCTOR) == FLG_CCTOR; + m_comp->fgPgoSingleEdge = !isCctor && !preferSize && (m_comp->opts.callInstrCount < 10); + + if (m_comp->fgPgoSingleEdge) { - if (block->NumSucc() > 1) + for (BasicBlock* const block : m_comp->Blocks()) { - m_comp->fgPgoSingleEdge = false; - break; + if (block->NumSucc() > 1) + { + m_comp->fgPgoSingleEdge = false; + break; + } } } diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index 3a3b85ba1d4863..d1e69950efc631 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -738,16 +738,9 @@ inline size_t unsigned_abs(int64_t x) #define FEATURE_TAILCALL_OPT_SHARED_RETURN 0 #endif // !FEATURE_TAILCALL_OPT -#define CLFLG_CODESIZE 0x00001 -#define CLFLG_CODESPEED 0x00002 -#define CLFLG_CSE 0x00004 -#define CLFLG_REGVAR 0x00008 -#define CLFLG_RNGCHKOPT 0x00010 -#define CLFLG_DEADSTORE 0x00020 -#define CLFLG_CODEMOTION 0x00040 -#define CLFLG_QMARK 0x00080 -#define CLFLG_TREETRANS 0x00100 -#define CLFLG_INLINING 0x00200 +#define CLFLG_REGVAR 0x00008 +#define CLFLG_TREETRANS 0x00100 +#define CLFLG_INLINING 0x00200 #if FEATURE_STRUCTPROMOTE #define CLFLG_STRUCTPROMOTE 0x00400 @@ -761,10 +754,7 @@ inline size_t unsigned_abs(int64_t x) #define FEATURE_LOOP_ALIGN 0 #endif -#define CLFLG_MAXOPT \ - (CLFLG_CSE | CLFLG_REGVAR | CLFLG_RNGCHKOPT | CLFLG_DEADSTORE | CLFLG_CODEMOTION | CLFLG_QMARK | CLFLG_TREETRANS | \ - CLFLG_INLINING | CLFLG_STRUCTPROMOTE) - +#define CLFLG_MAXOPT (CLFLG_REGVAR | CLFLG_TREETRANS | CLFLG_INLINING | CLFLG_STRUCTPROMOTE) #define CLFLG_MINOPT (CLFLG_TREETRANS) /*****************************************************************************/