Skip to content

JIT: Generalize check for full interruptibility #95299

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 29, 2023
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
8 changes: 0 additions & 8 deletions src/coreclr/jit/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,14 +495,6 @@ void BasicBlock::dspFlags()
{
printf("Loop ");
}
if (bbFlags & BBF_LOOP_CALL0)
{
printf("Loop0 ");
}
if (bbFlags & BBF_LOOP_CALL1)
{
printf("Loop1 ");
}
if (bbFlags & BBF_HAS_LABEL)
{
printf("label ");
Expand Down
60 changes: 29 additions & 31 deletions src/coreclr/jit/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,43 +392,41 @@ enum BasicBlockFlags : unsigned __int64
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_CALL0 = MAKE_BBFLAG(15), // BB starts a loop that sometimes won't call
BBF_LOOP_CALL1 = MAKE_BBFLAG(16), // BB starts a loop that will always call
BBF_HAS_LABEL = MAKE_BBFLAG(17), // BB needs a label
BBF_LOOP_ALIGN = MAKE_BBFLAG(18), // Block is lexically the first block in a loop we intend to align.
BBF_HAS_ALIGN = MAKE_BBFLAG(19), // BB ends with 'align' instruction
BBF_HAS_JMP = MAKE_BBFLAG(20), // BB executes a JMP instruction (instead of return)
BBF_GC_SAFE_POINT = MAKE_BBFLAG(21), // BB has a GC safe point (a call). More abstractly, BB does not require a
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
BBF_HAS_JMP = MAKE_BBFLAG(18), // BB executes a JMP instruction (instead of return)
BBF_GC_SAFE_POINT = MAKE_BBFLAG(19), // BB has a GC safe point (a call). More abstractly, BB does not require a
// (further) poll -- this may be because this BB has a call, or, in some
// cases, because the BB occurs in a loop, and we've determined that all
// paths in the loop body leading to BB include a call.
BBF_HAS_IDX_LEN = MAKE_BBFLAG(22), // BB contains simple index or length expressions on an SD array local var.
BBF_HAS_MD_IDX_LEN = MAKE_BBFLAG(23), // BB contains simple index, length, or lower bound expressions on an MD array local var.
BBF_HAS_MDARRAYREF = MAKE_BBFLAG(24), // Block has a multi-dimensional array reference
BBF_HAS_NEWOBJ = MAKE_BBFLAG(25), // BB contains 'new' of an object type.
BBF_HAS_IDX_LEN = MAKE_BBFLAG(20), // BB contains simple index or length expressions on an SD array local var.
BBF_HAS_MD_IDX_LEN = MAKE_BBFLAG(21), // BB contains simple index, length, or lower bound expressions on an MD array local var.
BBF_HAS_MDARRAYREF = MAKE_BBFLAG(22), // Block has a multi-dimensional array reference
BBF_HAS_NEWOBJ = MAKE_BBFLAG(23), // BB contains 'new' of an object type.

BBF_RETLESS_CALL = MAKE_BBFLAG(26), // BBJ_CALLFINALLY that will never return (and therefore, won't need a paired
BBF_RETLESS_CALL = MAKE_BBFLAG(24), // BBJ_CALLFINALLY that will never return (and therefore, won't need a paired
// BBJ_ALWAYS); see isBBCallAlwaysPair().
BBF_LOOP_PREHEADER = MAKE_BBFLAG(27), // BB is a loop preheader block
BBF_COLD = MAKE_BBFLAG(28), // BB is cold
BBF_PROF_WEIGHT = MAKE_BBFLAG(29), // BB weight is computed from profile data
BBF_KEEP_BBJ_ALWAYS = MAKE_BBFLAG(30), // A special BBJ_ALWAYS block, used by EH code generation. Keep the jump kind
BBF_LOOP_PREHEADER = MAKE_BBFLAG(25), // BB is a loop preheader block
BBF_COLD = MAKE_BBFLAG(26), // BB is cold
BBF_PROF_WEIGHT = MAKE_BBFLAG(27), // BB weight is computed from profile data
BBF_KEEP_BBJ_ALWAYS = MAKE_BBFLAG(28), // A special BBJ_ALWAYS block, used by EH code generation. Keep the jump kind
// as BBJ_ALWAYS. Used for the paired BBJ_ALWAYS block following the
// BBJ_CALLFINALLY block, as well as, on x86, the final step block out of a
// finally.
BBF_HAS_CALL = MAKE_BBFLAG(31), // BB contains a call
BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY = MAKE_BBFLAG(32), // Block is dominated by exceptional entry.
BBF_BACKWARD_JUMP = MAKE_BBFLAG(33), // BB is surrounded by a backward jump/switch arc
BBF_BACKWARD_JUMP_SOURCE = MAKE_BBFLAG(34), // Block is a source of a backward jump
BBF_BACKWARD_JUMP_TARGET = MAKE_BBFLAG(35), // Block is a target of a backward jump
BBF_PATCHPOINT = MAKE_BBFLAG(36), // Block is a patchpoint
BBF_PARTIAL_COMPILATION_PATCHPOINT = MAKE_BBFLAG(37), // Block is a partial compilation patchpoint
BBF_HAS_HISTOGRAM_PROFILE = MAKE_BBFLAG(38), // BB contains a call needing a histogram profile
BBF_TAILCALL_SUCCESSOR = MAKE_BBFLAG(39), // BB has pred that has potential tail call
BBF_RECURSIVE_TAILCALL = MAKE_BBFLAG(40), // Block has recursive tailcall that may turn into a loop
BBF_NO_CSE_IN = MAKE_BBFLAG(41), // Block should kill off any incoming CSE
BBF_CAN_ADD_PRED = MAKE_BBFLAG(42), // Ok to add pred edge to this block, even when "safe" edge creation disabled
BBF_NONE_QUIRK = MAKE_BBFLAG(43), // Block was created as a BBJ_ALWAYS to the next block,
BBF_HAS_CALL = MAKE_BBFLAG(29), // BB contains a call
BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY = MAKE_BBFLAG(30), // Block is dominated by exceptional entry.
BBF_BACKWARD_JUMP = MAKE_BBFLAG(31), // BB is surrounded by a backward jump/switch arc
BBF_BACKWARD_JUMP_SOURCE = MAKE_BBFLAG(32), // Block is a source of a backward jump
BBF_BACKWARD_JUMP_TARGET = MAKE_BBFLAG(33), // Block is a target of a backward jump
BBF_PATCHPOINT = MAKE_BBFLAG(34), // Block is a patchpoint
BBF_PARTIAL_COMPILATION_PATCHPOINT = MAKE_BBFLAG(35), // Block is a partial compilation patchpoint
BBF_HAS_HISTOGRAM_PROFILE = MAKE_BBFLAG(36), // BB contains a call needing a histogram profile
BBF_TAILCALL_SUCCESSOR = MAKE_BBFLAG(37), // BB has pred that has potential tail call
BBF_RECURSIVE_TAILCALL = MAKE_BBFLAG(38), // Block has recursive tailcall that may turn into a loop
BBF_NO_CSE_IN = MAKE_BBFLAG(39), // Block should kill off any incoming CSE
BBF_CAN_ADD_PRED = MAKE_BBFLAG(40), // Ok to add pred edge to this block, even when "safe" edge creation disabled
BBF_NONE_QUIRK = MAKE_BBFLAG(41), // Block was created as a BBJ_ALWAYS to the next block,
// and should be treated as if it falls through.
// This is just to reduce diffs from removing BBJ_NONE.
// (TODO: Remove this quirk after refactoring Compiler::fgFindInsertPoint)
Expand All @@ -437,7 +435,7 @@ enum BasicBlockFlags : unsigned __int64

// Flags that relate blocks to loop structure.

BBF_LOOP_FLAGS = BBF_LOOP_PREHEADER | BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1 | BBF_LOOP_ALIGN,
BBF_LOOP_FLAGS = BBF_LOOP_PREHEADER | BBF_LOOP_HEAD | BBF_LOOP_ALIGN,

// Flags to update when two blocks are compacted

Expand All @@ -446,7 +444,7 @@ enum BasicBlockFlags : unsigned __int64

// Flags a block should not have had before it is split.

BBF_SPLIT_NONEXIST = BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1 | BBF_RETLESS_CALL | BBF_LOOP_PREHEADER | BBF_COLD,
BBF_SPLIT_NONEXIST = BBF_LOOP_HEAD | BBF_RETLESS_CALL | BBF_LOOP_PREHEADER | BBF_COLD,

// Flags lost by the top block when a block is split.
// Note, this is a conservative guess.
Expand Down
8 changes: 1 addition & 7 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5778,6 +5778,7 @@ class Compiler
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);

PhaseStatus fgSetBlockOrder();
bool fgHasCycleWithoutGCSafePoint();

FlowGraphDfsTree* fgComputeDfs();

Expand All @@ -5787,14 +5788,9 @@ class Compiler

bool fgCastNeeded(GenTree* tree, var_types toType);

// The following check for loops that don't execute calls
bool fgLoopCallMarked;

void fgLoopCallTest(BasicBlock* srcBB, BasicBlock* dstBB);
void fgLoopCallMark();

void fgMarkLoopHead(BasicBlock* block);

unsigned fgGetCodeEstimate(BasicBlock* block);

#if DUMP_FLOWGRAPHS
Expand Down Expand Up @@ -8013,8 +8009,6 @@ class Compiler
protected:
ssize_t optGetArrayRefScaleAndIndex(GenTree* mul, GenTree** pIndex DEBUGARG(bool bRngChk));

bool optReachWithoutCall(BasicBlock* srcBB, BasicBlock* dstBB);

/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Expand Down
7 changes: 2 additions & 5 deletions src/coreclr/jit/fgbasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ void Compiler::fgInit()
fgReachabilitySetsValid = false;
#endif // DEBUG

/* We don't know yet which loops will always execute calls */
fgLoopCallMarked = false;

/* Initialize the basic block list */

fgFirstBB = nullptr;
Expand Down Expand Up @@ -4770,8 +4767,8 @@ BasicBlock* Compiler::fgSplitBlockAtEnd(BasicBlock* curr)
newBlock->bbFlags = curr->bbFlags;

// Remove flags that the new block can't have.
newBlock->bbFlags &= ~(BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1 | BBF_FUNCLET_BEG | BBF_LOOP_PREHEADER |
BBF_KEEP_BBJ_ALWAYS | BBF_PATCHPOINT | BBF_BACKWARD_JUMP_TARGET | BBF_LOOP_ALIGN);
newBlock->bbFlags &= ~(BBF_LOOP_HEAD | BBF_FUNCLET_BEG | BBF_LOOP_PREHEADER | BBF_KEEP_BBJ_ALWAYS | BBF_PATCHPOINT |
BBF_BACKWARD_JUMP_TARGET | BBF_LOOP_ALIGN);

// Remove the GC safe bit on the new block. It seems clear that if we split 'curr' at the end,
// such that all the code is left in 'curr', and 'newBlock' just gets the control flow, then
Expand Down
Loading