Skip to content

Commit 87ae15c

Browse files
author
Sergey Andreenko
authored
replace the linear time algorithm from lclvars with the constant one. (#10401)
add new block flag DOMINATED_BY_NOT_NORMAL_ENTRY It allows to answer the question: "Is block dominated by non normal entry" - in O(1).
1 parent 4475fd6 commit 87ae15c

File tree

4 files changed

+73
-29
lines changed

4 files changed

+73
-29
lines changed

src/jit/block.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,8 @@ struct BasicBlock : private LIR::Range
438438
#define BBF_CLONED_FINALLY_BEGIN 0x100000000 // First block of a cloned finally region
439439
#define BBF_CLONED_FINALLY_END 0x200000000 // Last block of a cloned finally region
440440

441+
#define BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY 0x400000000 // Block is dominated by exceptional entry.
442+
441443
// Flags that relate blocks to loop structure.
442444

443445
#define BBF_LOOP_FLAGS (BBF_LOOP_PREHEADER | BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1)
@@ -877,12 +879,6 @@ struct BasicBlock : private LIR::Range
877879
unsigned bbDfsNum; // The index of this block in DFS reverse post order
878880
// relative to the flow graph.
879881

880-
#if ASSERTION_PROP
881-
// A set of blocks which dominate this one *except* the normal entry block. This is lazily initialized
882-
// and used only by Assertion Prop, intersected with fgEnterBlks!
883-
BlockSet bbDoms;
884-
#endif
885-
886882
IL_OFFSET bbCodeOffs; // IL offset of the beginning of the block
887883
IL_OFFSET bbCodeOffsEnd; // IL offset past the end of the block. Thus, the [bbCodeOffs..bbCodeOffsEnd)
888884
// range is not inclusive of the end offset. The count of IL bytes in the block
@@ -1077,13 +1073,7 @@ struct BasicBlock : private LIR::Range
10771073
GenTree* FirstNonPhiDefOrCatchArgAsg();
10781074

10791075
BasicBlock()
1080-
:
1081-
#if ASSERTION_PROP
1082-
BLOCKSET_INIT_NOCOPY(bbDoms, BlockSetOps::UninitVal())
1083-
,
1084-
#endif // ASSERTION_PROP
1085-
VARSET_INIT_NOCOPY(bbLiveIn, VarSetOps::UninitVal())
1086-
, VARSET_INIT_NOCOPY(bbLiveOut, VarSetOps::UninitVal())
1076+
: VARSET_INIT_NOCOPY(bbLiveIn, VarSetOps::UninitVal()), VARSET_INIT_NOCOPY(bbLiveOut, VarSetOps::UninitVal())
10871077
{
10881078
}
10891079

@@ -1170,6 +1160,16 @@ struct BasicBlock : private LIR::Range
11701160

11711161
void MakeLIR(GenTree* firstNode, GenTree* lastNode);
11721162
bool IsLIR();
1163+
1164+
void SetDominatedByExceptionalEntryFlag()
1165+
{
1166+
bbFlags |= BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY;
1167+
}
1168+
1169+
bool IsDominatedByExceptionalEntryFlag()
1170+
{
1171+
return (bbFlags & BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY) != 0;
1172+
}
11731173
};
11741174

11751175
template <>

src/jit/compiler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,6 +2809,9 @@ class Compiler
28092809
static fgWalkPreFn lvaMarkLclRefsCallback;
28102810
void lvaMarkLclRefs(GenTreePtr tree);
28112811

2812+
bool IsDominatedByExceptionalEntry(BasicBlock* block);
2813+
void SetVolatileHint(LclVarDsc* varDsc);
2814+
28122815
// Keeps the mapping from SSA #'s to VN's for the implicit memory variables.
28132816
PerSsaArray lvMemoryPerSsaData;
28142817
unsigned lvMemoryNumSsaNames;
@@ -4085,6 +4088,8 @@ class Compiler
40854088
// Based on: A Simple, Fast Dominance Algorithm
40864089
// by Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
40874090

4091+
void fgCompDominatedByExceptionalEntryBlocks();
4092+
40884093
BlockSet_ValRet_T fgGetDominatorSet(BasicBlock* block); // Returns a set of blocks that dominate the given block.
40894094
// Note: this is relatively slow compared to calling fgDominate(),
40904095
// especially if dealing with a single block versus block check.

src/jit/flowgraph.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,6 +2413,7 @@ void Compiler::fgComputeDoms()
24132413
bbRoot.bbNum = 0;
24142414
bbRoot.bbIDom = &bbRoot;
24152415
bbRoot.bbDfsNum = 0;
2416+
bbRoot.bbFlags = 0;
24162417
flRoot.flNext = nullptr;
24172418
flRoot.flBlock = &bbRoot;
24182419

@@ -2535,6 +2536,8 @@ void Compiler::fgComputeDoms()
25352536
}
25362537
}
25372538

2539+
fgCompDominatedByExceptionalEntryBlocks();
2540+
25382541
#ifdef DEBUG
25392542
if (verbose)
25402543
{
@@ -25081,3 +25084,30 @@ unsigned Compiler::fgMeasureIR()
2508125084

2508225085
return nodeCount;
2508325086
}
25087+
25088+
//------------------------------------------------------------------------
25089+
// fgCompDominatedByExceptionalEntryBlocks: compute blocks that are
25090+
// dominated by not normal entry.
25091+
//
25092+
void Compiler::fgCompDominatedByExceptionalEntryBlocks()
25093+
{
25094+
assert(fgEnterBlksSetValid);
25095+
if (BlockSetOps::Count(this, fgEnterBlks) != 1) // There are exception entries.
25096+
{
25097+
for (unsigned i = 1; i <= fgBBNumMax; ++i)
25098+
{
25099+
BasicBlock* block = fgBBInvPostOrder[i];
25100+
if (BlockSetOps::IsMember(this, fgEnterBlks, block->bbNum))
25101+
{
25102+
if (fgFirstBB != block) // skip the normal entry.
25103+
{
25104+
block->SetDominatedByExceptionalEntryFlag();
25105+
}
25106+
}
25107+
else if (block->bbIDom->IsDominatedByExceptionalEntryFlag())
25108+
{
25109+
block->SetDominatedByExceptionalEntryFlag();
25110+
}
25111+
}
25112+
}
25113+
}

src/jit/lclvars.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,23 +3622,9 @@ void Compiler::lvaMarkLclRefs(GenTreePtr tree)
36223622
}
36233623

36243624
#if ASSERTION_PROP
3625-
/* Exclude the normal entry block */
3626-
if (fgDomsComputed && (lvaMarkRefsCurBlock->bbNum != 1) && lvaMarkRefsCurBlock->bbIDom != nullptr)
3625+
if (fgDomsComputed && IsDominatedByExceptionalEntry(lvaMarkRefsCurBlock))
36273626
{
3628-
// If any entry block except the normal entry block dominates the block, then mark the local with the
3629-
// lvVolatileHint flag.
3630-
3631-
if (BlockSetOps::MayBeUninit(lvaMarkRefsCurBlock->bbDoms))
3632-
{
3633-
// Lazy init (If a block is not dominated by any other block, we'll redo this every time, but it'll be fast)
3634-
BlockSetOps::AssignNoCopy(this, lvaMarkRefsCurBlock->bbDoms, fgGetDominatorSet(lvaMarkRefsCurBlock));
3635-
BlockSetOps::RemoveElemD(this, lvaMarkRefsCurBlock->bbDoms, fgFirstBB->bbNum);
3636-
}
3637-
assert(fgEnterBlksSetValid);
3638-
if (!BlockSetOps::IsEmptyIntersection(this, lvaMarkRefsCurBlock->bbDoms, fgEnterBlks))
3639-
{
3640-
varDsc->lvVolatileHint = 1;
3641-
}
3627+
SetVolatileHint(varDsc);
36423628
}
36433629

36443630
/* Record if the variable has a single def or not */
@@ -3723,6 +3709,29 @@ void Compiler::lvaMarkLclRefs(GenTreePtr tree)
37233709
#endif
37243710
}
37253711

3712+
//------------------------------------------------------------------------
3713+
// IsDominatedByExceptionalEntry: Check is the block dominated by an exception entry block.
3714+
//
3715+
// Arguments:
3716+
// block - the checking block.
3717+
//
3718+
bool Compiler::IsDominatedByExceptionalEntry(BasicBlock* block)
3719+
{
3720+
assert(fgDomsComputed);
3721+
return block->IsDominatedByExceptionalEntryFlag();
3722+
}
3723+
3724+
//------------------------------------------------------------------------
3725+
// SetVolatileHint: Set a local var's volatile hint.
3726+
//
3727+
// Arguments:
3728+
// varDsc - the local variable that needs the hint.
3729+
//
3730+
void Compiler::SetVolatileHint(LclVarDsc* varDsc)
3731+
{
3732+
varDsc->lvVolatileHint = true;
3733+
}
3734+
37263735
/*****************************************************************************
37273736
*
37283737
* Helper passed to Compiler::fgWalkTreePre() to do variable ref marking.

0 commit comments

Comments
 (0)