Skip to content

Commit

Permalink
Add dumpers for new loop data structures (dotnet#96080)
Browse files Browse the repository at this point in the history
Specifically, add: `FlowGraphNaturalLoops::Dump()` and `FlowGraphNaturalLoop::Dump()`.

Add corresponding debugger helpers `dNewLoops()` (dumps `Compiler::m_loops`), `dNewLoopsA()` (takes a `FlowGraphNaturalLoops*` argument), `dNewLoop()` (takes a `FlowGraphNaturalLoop*` argument), and their corresponding `c` versions.

A simple dump looks like:
```
***************  (New) Natural loop graph
L00 header: BB05
  Members (3): [BB05..BB07]
  Entry: BB04 -> BB05
  Exit: BB07 -> BB08
  Back: BB07 -> BB05
```

The loop block members are displayed as a block range if the loop blocks happen to all be lexically contiguous without any non-loop blocks in the range.

If there are one or more non-loop blocks in the `bbNext` order range, then a list of ranges is displayed, e.g.:
```
L00 header: BB02
  Members (39): [BB02..BB12];[BB14..BB17];[BB19..BB21];[BB23..BB24];[BB26..BB28];[BB30..BB32];BB34;[BB62..BB72];BB74
  Entry: BB01 -> BB02
  Exit: BB23 -> BB57; BB24 -> BB25; BB20 -> BB36; BB21 -> BB22; BB15 -> BB58; BB16 -> BB59; BB17 -> BB18; BB11 -> BB47; BB12 -> BB13; BB09 -> BB35; BB10 -> BB35; BB10 -> BB61; BB10 -> BB60; BB10 -> BB48; BB10 -> BB56; BB32 -> BB33; BB28 -> BB29; BB74 -> BB75; BB72 -> BB73
  Back: BB28 -> BB02; BB32 -> BB02; BB34 -> BB02; BB69 -> BB02; BB70 -> BB02
```

Otherwise, the full set of loop blocks is displayed individually.

A more complicated example:
```
***************  (New) Natural loop graph
L00 header: BB02
  Members (118): [BB02..BB20];[BB22..BB24];[BB26..BB29];[BB31..BB35];[BB37..BB123]
  Entry: BB01 -> BB02
  Exit: BB123 -> BB124; BB29 -> BB30; BB31 -> BB128; BB45 -> BB130; BB42 -> BB130; BB38 -> BB130; BB35 -> BB36; BB24 -> BB25; BB20 -> BB21
  Back: BB123 -> BB02
L01 header: BB03 parent: L00
  Members (116): [BB03..BB20];[BB22..BB24];[BB26..BB29];[BB31..BB35];[BB37..BB122]
  Entry: BB02 -> BB03
  Exit: BB14 -> BB123; BB15 -> BB123; BB29 -> BB30; BB31 -> BB128; BB45 -> BB130; BB42 -> BB130; BB38 -> BB130; BB35 -> BB36; BB24 -> BB25; BB20 -> BB21
  Back: BB121 -> BB03
L02 header: BB04 parent: L01
  Members (103): [BB04..BB12];[BB14..BB20];[BB22..BB24];[BB26..BB29];[BB31..BB35];[BB37..BB111]
  Entry: BB03 -> BB04
  Exit: BB14 -> BB123; BB15 -> BB123; BB29 -> BB30; BB31 -> BB128; BB45 -> BB130; BB42 -> BB130; BB38 -> BB130; BB35 -> BB36; BB24 -> BB25; BB20 -> BB21; BB11 -> BB122; BB12 -> BB13
  Back: BB111 -> BB04
L03 header: BB05 parent: L02
  Members (17): [BB05..BB12];[BB14..BB16];[BB18..BB20];[BB22..BB24]
  Entry: BB04 -> BB05
  Exit: BB14 -> BB123; BB15 -> BB123; BB16 -> BB17; BB24 -> BB25; BB20 -> BB21; BB11 -> BB122; BB12 -> BB13
  Back: BB24 -> BB05
L04 header: BB06 parent: L03
  Members (13): [BB06..BB12];[BB14..BB16];[BB18..BB20]
  Entry: BB05 -> BB06
  Exit: BB14 -> BB123; BB15 -> BB123; BB16 -> BB17; BB19 -> BB22; BB20 -> BB21; BB11 -> BB122; BB12 -> BB13
  Back: BB20 -> BB06
L05 header: BB07 parent: L04
  Members (10): [BB07..BB12];[BB14..BB16];BB18
  Entry: BB06 -> BB07
  Exit: BB14 -> BB123; BB15 -> BB123; BB16 -> BB17; BB18 -> BB19; BB11 -> BB122; BB12 -> BB13
  Back: BB18 -> BB07
L06 header: BB08 parent: L05
  Members (8): [BB08..BB12];[BB14..BB16]
  Entry: BB07 -> BB08
  Exit: BB14 -> BB123; BB15 -> BB123; BB16 -> BB17; BB10 -> BB18; BB11 -> BB122; BB12 -> BB13
  Back: BB16 -> BB08
L07 header: BB09 parent: L06
  Members (4): [BB09..BB12]
  Entry: BB08 -> BB09
  Exit: BB09 -> BB14; BB10 -> BB18; BB11 -> BB122; BB12 -> BB13
  Back: BB12 -> BB09
L08 header: BB58 parent: L02
  Members (34): [BB58..BB91]
  Entry: BB57 -> BB58
  Exit: BB91 -> BB92
  Back: BB91 -> BB58
```
  • Loading branch information
BruceForstall authored Dec 19, 2023
1 parent f5f4889 commit bd26d7e
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 2 deletions.
48 changes: 48 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9399,6 +9399,12 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* 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
* Compiler::m_loops.
* cNewLoopsA, dNewLoopsA : Display the loop table (call FlowGraphNaturalLoops::Dump()) with a given
* loops arg.
* cNewLoop, dNewLoop : Display a single loop (call FlowGraphNaturalLoop::Dump()) with given
* loop arg.
* cTreeFlags, dTreeFlags : Display tree flags for a specified tree.
*
* The following don't require a Compiler* to work:
Expand Down Expand Up @@ -9454,6 +9460,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#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:cTreeFlags")

// Functions which call the c* functions getting Compiler* using `JitTls::GetCompiler()`
Expand All @@ -9479,6 +9488,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#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")

// Functions which don't require a Compiler*
Expand Down Expand Up @@ -9725,6 +9737,27 @@ JITDBGAPI void __cdecl cLoops(Compiler* comp)
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)
{
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)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
printf("===================================================================== *NewLoop %u\n", sequenceNumber++);
FlowGraphNaturalLoop::Dump(loop);
}

JITDBGAPI void __cdecl cTreeFlags(Compiler* comp, GenTree* tree)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
Expand Down Expand Up @@ -10417,6 +10450,21 @@ JITDBGAPI void __cdecl dLoops()
cLoops(JitTls::GetCompiler());
}

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

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

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

JITDBGAPI void __cdecl dTreeFlags(GenTree* tree)
{
cTreeFlags(JitTls::GetCompiler(), tree);
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2141,6 +2141,7 @@ class FlowGraphNaturalLoop

void MatchInit(NaturalLoopIterInfo* info, BasicBlock* initBlock, GenTree* init);
bool MatchLimit(NaturalLoopIterInfo* info, GenTree* test);

public:
BasicBlock* GetHeader() const
{
Expand Down Expand Up @@ -2230,6 +2231,10 @@ class FlowGraphNaturalLoop
bool AnalyzeIteration(NaturalLoopIterInfo* info);

bool HasDef(unsigned lclNum);

#ifdef DEBUG
static void Dump(FlowGraphNaturalLoop* loop);
#endif // DEBUG
};

// Represents a collection of the natural loops in the flow graph. See
Expand All @@ -2253,6 +2258,7 @@ class FlowGraphNaturalLoops
FlowGraphNaturalLoops(const FlowGraphDfsTree* dfs);

static bool FindNaturalLoopBlocks(FlowGraphNaturalLoop* loop, ArrayStack<BasicBlock*>& worklist);

public:
const FlowGraphDfsTree* GetDfsTree()
{
Expand Down Expand Up @@ -2330,6 +2336,10 @@ class FlowGraphNaturalLoops
}

static FlowGraphNaturalLoops* Find(const FlowGraphDfsTree* dfs);

#ifdef DEBUG
static void Dump(FlowGraphNaturalLoops* loops);
#endif // DEBUG
};

// Represents the dominator tree of the flow graph.
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/fgprofilesynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ void ProfileSynthesis::ComputeCyclicProbabilities(FlowGraphNaturalLoop* loop)
//
if (capped && (loop->ExitEdges().size() > 0))
{
// Figure out how much flow exits the loop with the capped probablility
// Figure out how much flow exits the loop with the capped probability
// and current block frequencies and exit likelihoods.
//
weight_t cappedExitWeight = 0.0;
Expand Down
Loading

0 comments on commit bd26d7e

Please sign in to comment.