Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 45 additions & 5 deletions src/coreclr/jit/fgprofilesynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,55 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
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())
// Ignore static constructors - they're never expected to be called more than once.
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;

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;
}
}
}

// fgPgoSingleEdge targets mostly small wrapper-like methods, so we ignore single-edge code
// with a lot of calls.
int callsCount = 0;
const int MaxCallsForSingleEdgeBlocks = 10;
if (m_comp->fgPgoSingleEdge)
{
// Loop all BBs again because the previous block-only loop was more likely to
// bail out early.
for (BasicBlock* const block : m_comp->Blocks())
{
for (Statement* const stmt : block->Statements())
{
if ((stmt->GetRootNode() != nullptr) && ((stmt->GetRootNode()->gtFlags & GTF_CALL) != 0))
{
for (GenTree* const tree : stmt->TreeList())
{
if (tree->IsCall())
{
callsCount++;
if (callsCount > MaxCallsForSingleEdgeBlocks)
{
m_comp->fgPgoSingleEdge = false;
JITDUMP("Too many calls for fgPgoSingleEdge - bail out.\n")
goto TOO_MANY_CALLS;
}
}
}
}
}
}
}
TOO_MANY_CALLS:

m_comp->Metrics.ProfileSynthesizedBlendedOrRepaired++;

Expand Down
18 changes: 4 additions & 14 deletions src/coreclr/jit/jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

/*****************************************************************************/
Expand Down
Loading