Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 2 additions & 8 deletions src/coreclr/jit/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ void BasicBlock::dspFlags() const
{BBF_INTERNAL, "internal"},
{BBF_FAILED_VERIFICATION, "failV"},
{BBF_HAS_SUPPRESSGC_CALL, "sup-gc"},
{BBF_LOOP_HEAD, "Loop"},
{BBF_LOOP_HEAD, "loophead"},
{BBF_HAS_LABEL, "label"},
{BBF_HAS_JMP, "jmp"},
{BBF_HAS_CALL, "hascall"},
Expand All @@ -513,7 +513,7 @@ void BasicBlock::dspFlags() const
{BBF_NO_CSE_IN, "no-cse"},
{BBF_CAN_ADD_PRED, "add-pred"},
{BBF_RETLESS_CALL, "retless"},
{BBF_LOOP_PREHEADER, "LoopPH"},
{BBF_LOOP_PREHEADER, "preheader"},
{BBF_COLD, "cold"},
{BBF_KEEP_BBJ_ALWAYS, "KEEP"},
{BBF_CLONED_FINALLY_BEGIN, "cfb"},
Expand Down Expand Up @@ -811,7 +811,6 @@ void BasicBlock::CloneBlockState(
to->bbCodeOffs = from->bbCodeOffs;
to->bbCodeOffsEnd = from->bbCodeOffsEnd;
VarSetOps::AssignAllowUninitRhs(compiler, to->bbScope, from->bbScope);
to->bbNatLoopNum = from->bbNatLoopNum;
#ifdef DEBUG
to->bbTgtStkDepth = from->bbTgtStkDepth;
#endif // DEBUG
Expand Down Expand Up @@ -1606,11 +1605,6 @@ BasicBlock* BasicBlock::New(Compiler* compiler)
block->bbMemorySsaNumOut[memoryKind] = 0;
}

// Make sure we reserve a NOT_IN_LOOP value that isn't a legal table index.
static_assert_no_msg(BasicBlock::MAX_LOOP_NUM < BasicBlock::NOT_IN_LOOP);

block->bbNatLoopNum = BasicBlock::NOT_IN_LOOP;

block->bbPreorderNum = 0;
block->bbPostorderNum = 0;

Expand Down
12 changes: 2 additions & 10 deletions src/coreclr/jit/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ typedef BitVec_ValRet_T ASSERT_VALRET_TP;
// This define is used with string concatenation to put this in printf format strings (Note that %u means unsigned int)
#define FMT_BB "BB%02u"

// Use this format for loop table indices.
// Use this format for loop indices
#define FMT_LP "L%02u"

// And this format for profile weights
Expand Down Expand Up @@ -393,7 +393,7 @@ enum BasicBlockFlags : unsigned __int64
BBF_HAS_NULLCHECK = MAKE_BBFLAG(11), // BB contains a null check
BBF_HAS_SUPPRESSGC_CALL = MAKE_BBFLAG(12), // BB contains a call to a method with SuppressGCTransitionAttribute
BBF_RUN_RARELY = MAKE_BBFLAG(13), // BB is rarely run (catch clauses, blocks with throws etc)
BBF_LOOP_HEAD = MAKE_BBFLAG(14), // BB is the head of a loop
BBF_LOOP_HEAD = MAKE_BBFLAG(14), // BB is the head of a loop (can reach a predecessor)
BBF_HAS_LABEL = MAKE_BBFLAG(15), // BB needs a label
BBF_LOOP_ALIGN = MAKE_BBFLAG(16), // Block is lexically the first block in a loop we intend to align.
BBF_HAS_ALIGN = MAKE_BBFLAG(17), // BB ends with 'align' instruction
Expand Down Expand Up @@ -1251,14 +1251,6 @@ struct BasicBlock : private LIR::Range
#define BBCT_FILTER_HANDLER 0xFFFFFFFF
#define handlerGetsXcptnObj(hndTyp) ((hndTyp) != BBCT_NONE && (hndTyp) != BBCT_FAULT && (hndTyp) != BBCT_FINALLY)

// The following fields are used for loop detection
typedef unsigned char loopNumber;
static const unsigned NOT_IN_LOOP = UCHAR_MAX;
static const unsigned MAX_LOOP_NUM = 64;

loopNumber bbNatLoopNum; // Index, in optLoopTable, of most-nested loop that contains this block,
// or else NOT_IN_LOOP if this block is not in a loop.

// TODO-Cleanup: Get rid of bbStkDepth and use bbStackDepthOnEntry() instead
union {
unsigned short bbStkDepth; // stack depth on entry
Expand Down
127 changes: 28 additions & 99 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@ Histogram computeReachabilitySetsIterationTable(computeReachabilitySetsIteration

unsigned totalLoopMethods; // counts the total number of methods that have natural loops
unsigned maxLoopsPerMethod; // counts the maximum number of loops a method has
unsigned totalLoopOverflows; // # of methods that identified more loops than we can represent
unsigned totalLoopCount; // counts the total number of natural loops
unsigned totalUnnatLoopCount; // counts the total number of (not-necessarily natural) loops
unsigned totalUnnatLoopOverflows; // # of methods that identified more unnatural loops than we can represent
Expand Down Expand Up @@ -1576,7 +1575,6 @@ void Compiler::compShutdown()
jitprintf("Total number of methods with loops is %5u\n", totalLoopMethods);
jitprintf("Total number of loops is %5u\n", totalLoopCount);
jitprintf("Maximum number of loops per method is %5u\n", maxLoopsPerMethod);
jitprintf("# of methods overflowing nat loop table is %5u\n", totalLoopOverflows);
jitprintf("Total number of 'unnatural' loops is %5u\n", totalUnnatLoopCount);
jitprintf("# of methods overflowing unnat loop limit is %5u\n", totalUnnatLoopOverflows);
jitprintf("Total number of loops with an iterator is %5u\n", iterLoopCount);
Expand Down Expand Up @@ -5254,10 +5252,9 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
//
// Remarks:
// All innermost loops whose block weight meets a threshold are candidates for alignment.
// The top block of the loop is marked with the BBF_LOOP_ALIGN flag to indicate this
// (the loop table itself is not changed).
// The top block of the loop is marked with the BBF_LOOP_ALIGN flag to indicate this.
//
// Depends on the loop table, and on block weights being set.
// Depends on block weights being set.
//
bool Compiler::shouldAlignLoop(FlowGraphNaturalLoop* loop, BasicBlock* top)
{
Expand Down Expand Up @@ -5839,25 +5836,17 @@ void Compiler::RecomputeFlowGraphAnnotations()

fgComputeReachability();
optSetBlockWeights();
optFindLoops();

fgInvalidateDfsTree();
m_dfsTree = fgComputeDfs();
optFindNewLoops();
optFindLoops();

if (fgHasLoops)
{
optFindAndScaleGeneralLoopBlocks();
}

m_domTree = FlowGraphDominatorTree::Build(m_dfsTree);

// Dominators and the loop table are computed above for old<->new loop
// crossreferencing, but they are not actually used for optimization
// anymore.
optLoopTableValid = false;
optLoopTable = nullptr;
optLoopCount = 0;
}

/*****************************************************************************/
Expand Down Expand Up @@ -9084,7 +9073,7 @@ void JitTimer::PrintCsvMethodStats(Compiler* comp)
fprintf(s_csvFile, "%u,", comp->info.compILCodeSize);
fprintf(s_csvFile, "%u,", comp->fgBBcount);
fprintf(s_csvFile, "%u,", comp->opts.MinOpts());
fprintf(s_csvFile, "%u,", comp->optLoopCount);
fprintf(s_csvFile, "%u,", comp->optNumNaturalLoopsFound);
fprintf(s_csvFile, "%u,", comp->optLoopsCloned);
#if FEATURE_LOOP_ALIGN
#ifdef DEBUG
Expand Down Expand Up @@ -9337,16 +9326,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* cCVarSet, dCVarSet : Display a "converted" VARSET_TP: the varset is assumed to be tracked variable
* indices. These are converted to variable numbers and sorted. (Calls
* dumpConvertedVarSet()).
* cLoop, dLoop : Display the blocks of a loop, including the trees, given a loop number (call
* optPrintLoopInfo()).
* cLoopPtr, dLoopPtr : Display the blocks of a loop, including the trees, given a LoopDsc* (call
* optPrintLoopInfo()).
* cLoops, dLoops : Display the loop table (call optPrintLoopTable()).
* cNewLoops, dNewLoops : Display the loop table (call FlowGraphNaturalLoops::Dump()) with
* cLoops, dLoops : Display the loops (call FlowGraphNaturalLoops::Dump()) with
* Compiler::m_loops.
* cNewLoopsA, dNewLoopsA : Display the loop table (call FlowGraphNaturalLoops::Dump()) with a given
* cLoopsA, dLoopsA : Display the loops (call FlowGraphNaturalLoops::Dump()) with a given
* loops arg.
* cNewLoop, dNewLoop : Display a single loop (call FlowGraphNaturalLoop::Dump()) with given
* cLoop, dLoop : Display a single loop (call FlowGraphNaturalLoop::Dump()) with given
* loop arg.
* cTreeFlags, dTreeFlags : Display tree flags for a specified tree.
* cVN, dVN : Display a ValueNum (call vnPrint()).
Expand All @@ -9361,7 +9345,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* dFindTree : Find a tree in the IR, specifying a tree id. Sets `dbTree` and `dbTreeBlock`.
* dFindStmt : Find a Statement in the IR, specifying a statement id. Sets `dbStmt`.
* dFindBlock : Find a block in the IR, specifying a block number. Sets `dbBlock`.
* dFindLoop : Find a loop in the loop table, specifying a loop number. Sets `dbLoop`.
* dFindLoop : Find a loop specifying a loop index. Sets `dbLoop`.
*/

// Make the debug helpers available (under #ifdef DEBUG) even though they are unreferenced. When the Microsoft
Expand Down Expand Up @@ -9401,12 +9385,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#pragma comment(linker, "/include:cDoms")
#pragma comment(linker, "/include:cLiveness")
#pragma comment(linker, "/include:cCVarSet")
#pragma comment(linker, "/include:cLoop")
#pragma comment(linker, "/include:cLoopPtr")
#pragma comment(linker, "/include:cLoops")
#pragma comment(linker, "/include:cNewLoops")
#pragma comment(linker, "/include:cNewLoopsA")
#pragma comment(linker, "/include:cNewLoop")
#pragma comment(linker, "/include:cLoopsA")
#pragma comment(linker, "/include:cLoop")
#pragma comment(linker, "/include:cTreeFlags")
#pragma comment(linker, "/include:cVN")

Expand All @@ -9431,11 +9412,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#pragma comment(linker, "/include:dLiveness")
#pragma comment(linker, "/include:dCVarSet")
#pragma comment(linker, "/include:dLoop")
#pragma comment(linker, "/include:dLoopPtr")
#pragma comment(linker, "/include:dLoops")
#pragma comment(linker, "/include:dNewLoops")
#pragma comment(linker, "/include:dNewLoopsA")
#pragma comment(linker, "/include:dNewLoop")
#pragma comment(linker, "/include:dTreeFlags")
#pragma comment(linker, "/include:dVN")

Expand Down Expand Up @@ -9473,11 +9450,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#pragma comment(linker, "/include:_cLiveness")
#pragma comment(linker, "/include:_cCVarSet")
#pragma comment(linker, "/include:_cLoop")
#pragma comment(linker, "/include:_cLoopPtr")
#pragma comment(linker, "/include:_cLoops")
#pragma comment(linker, "/include:_cNewLoops")
#pragma comment(linker, "/include:_cNewLoopsA")
#pragma comment(linker, "/include:_cNewLoop")
#pragma comment(linker, "/include:_cLoopsA")
#pragma comment(linker, "/include:_cTreeFlags")
#pragma comment(linker, "/include:_cVN")

Expand All @@ -9501,12 +9475,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#pragma comment(linker, "/include:_dDoms")
#pragma comment(linker, "/include:_dLiveness")
#pragma comment(linker, "/include:_dCVarSet")
#pragma comment(linker, "/include:_dLoop")
#pragma comment(linker, "/include:_dLoopPtr")
#pragma comment(linker, "/include:_dLoops")
#pragma comment(linker, "/include:_dNewLoops")
#pragma comment(linker, "/include:_dNewLoopsA")
#pragma comment(linker, "/include:_dNewLoop")
#pragma comment(linker, "/include:_dLoopsA")
#pragma comment(linker, "/include:_dLoop")
#pragma comment(linker, "/include:_dTreeFlags")
#pragma comment(linker, "/include:_dVN")

Expand Down Expand Up @@ -9682,44 +9653,21 @@ JITDBGAPI void __cdecl cCVarSet(Compiler* comp, VARSET_VALARG_TP vars)
printf("\n"); // dumpConvertedVarSet() doesn't emit a trailing newline
}

JITDBGAPI void __cdecl cLoop(Compiler* comp, unsigned loopNum)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
printf("===================================================================== *Loop %u\n", sequenceNumber++);
comp->optPrintLoopInfo(loopNum, /* verbose */ true);
printf("\n");
}

JITDBGAPI void __cdecl cLoopPtr(Compiler* comp, const Compiler::LoopDsc* loop)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
printf("===================================================================== *LoopPtr %u\n", sequenceNumber++);
comp->optPrintLoopInfo(loop, /* verbose */ true);
printf("\n");
}

JITDBGAPI void __cdecl cLoops(Compiler* comp)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
printf("===================================================================== *Loops %u\n", sequenceNumber++);
comp->optPrintLoopTable();
}

JITDBGAPI void __cdecl cNewLoops(Compiler* comp)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
printf("===================================================================== *NewLoops %u\n", sequenceNumber++);
FlowGraphNaturalLoops::Dump(comp->m_loops);
}

JITDBGAPI void __cdecl cNewLoopsA(Compiler* comp, FlowGraphNaturalLoops* loops)
JITDBGAPI void __cdecl cLoopsA(Compiler* comp, FlowGraphNaturalLoops* loops)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
printf("===================================================================== *NewLoopsA %u\n", sequenceNumber++);
FlowGraphNaturalLoops::Dump(loops);
}

JITDBGAPI void __cdecl cNewLoop(Compiler* comp, FlowGraphNaturalLoop* loop)
JITDBGAPI void __cdecl cLoop(Compiler* comp, FlowGraphNaturalLoop* loop)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
printf("===================================================================== *NewLoop %u\n", sequenceNumber++);
Expand Down Expand Up @@ -9778,10 +9726,6 @@ JITDBGAPI void __cdecl cTreeFlags(Compiler* comp, GenTree* tree)
{
chars += printf("[VAR_USEASG]");
}
if (tree->gtFlags & GTF_VAR_ITERATOR)
{
chars += printf("[VAR_ITERATOR]");
}
if (tree->gtFlags & GTF_VAR_MOREUSES)
{
chars += printf("[VAR_MOREUSES]");
Expand Down Expand Up @@ -10318,34 +10262,19 @@ JITDBGAPI void __cdecl dCVarSet(VARSET_VALARG_TP vars)
cCVarSet(JitTls::GetCompiler(), vars);
}

JITDBGAPI void __cdecl dLoop(unsigned loopNum)
{
cLoop(JitTls::GetCompiler(), loopNum);
}

JITDBGAPI void __cdecl dLoopPtr(const Compiler::LoopDsc* loop)
{
cLoopPtr(JitTls::GetCompiler(), loop);
}

JITDBGAPI void __cdecl dLoops()
{
cLoops(JitTls::GetCompiler());
}

JITDBGAPI void __cdecl dNewLoops()
{
cNewLoops(JitTls::GetCompiler());
}

JITDBGAPI void __cdecl dNewLoopsA(FlowGraphNaturalLoops* loops)
JITDBGAPI void __cdecl dLoopsA(FlowGraphNaturalLoops* loops)
{
cNewLoopsA(JitTls::GetCompiler(), loops);
cLoopsA(JitTls::GetCompiler(), loops);
}

JITDBGAPI void __cdecl dNewLoop(FlowGraphNaturalLoop* loop)
JITDBGAPI void __cdecl dLoop(FlowGraphNaturalLoop* loop)
{
cNewLoop(JitTls::GetCompiler(), loop);
cLoop(JitTls::GetCompiler(), loop);
}

JITDBGAPI void __cdecl dTreeFlags(GenTree* tree)
Expand Down Expand Up @@ -10382,11 +10311,11 @@ JITDBGAPI void __cdecl dBlockList(BasicBlockList* list)
// Trees, Stmts, and/or Blocks using id or bbNum.
// That can be used in watch window or as a way to get address of fields for data breakpoints.

GenTree* dbTree;
Statement* dbStmt;
BasicBlock* dbTreeBlock;
BasicBlock* dbBlock;
Compiler::LoopDsc* dbLoop;
GenTree* dbTree;
Statement* dbStmt;
BasicBlock* dbTreeBlock;
BasicBlock* dbBlock;
FlowGraphNaturalLoop* dbLoop;

// Debug APIs for finding Trees, Stmts, and/or Blocks.
// As a side effect, they set the debug variables above.
Expand Down Expand Up @@ -10478,18 +10407,18 @@ JITDBGAPI BasicBlock* __cdecl dFindBlock(unsigned bbNum)
return nullptr;
}

JITDBGAPI Compiler::LoopDsc* __cdecl dFindLoop(unsigned loopNum)
JITDBGAPI FlowGraphNaturalLoop* __cdecl dFindLoop(unsigned index)
{
Compiler* comp = JitTls::GetCompiler();
dbLoop = nullptr;

if (loopNum >= comp->optLoopCount)
if ((comp->m_loops == nullptr) || (index >= comp->m_loops->NumLoops()))
{
printf("loopNum %u out of range\n", loopNum);
printf("Index %u out of range\n", index);
return nullptr;
}

dbLoop = &comp->optLoopTable[loopNum];
dbLoop = comp->m_loops->GetLoopByIndex(index);
return dbLoop;
}

Expand Down
Loading