Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d3b1cf0
[Wasm RyuJIT] Wasm control flow basics
AndyAyersMS Nov 4, 2025
ca2c9b4
fix release build
AndyAyersMS Nov 6, 2025
39e0bd3
fix llvm build
AndyAyersMS Nov 6, 2025
e8882ab
Fix typos
AndyAyersMS Nov 7, 2025
890548e
Fix more typos
AndyAyersMS Nov 7, 2025
e2f71b1
[Wasm RyuJIT] Implement Wasm DFS and Loop Finding
AndyAyersMS Nov 7, 2025
4c97a19
fixes
AndyAyersMS Nov 7, 2025
3b3a13d
first cut at integrating SCCs
AndyAyersMS Nov 10, 2025
be764e3
transform sccs pre-lower
AndyAyersMS Nov 11, 2025
39f4793
handle blocks only reachable by EH
AndyAyersMS Nov 12, 2025
f1e5dcc
format
AndyAyersMS Nov 12, 2025
bc53647
remove unreachable first
AndyAyersMS Nov 13, 2025
ff1d0ac
fix dump
AndyAyersMS Nov 13, 2025
587f012
merge main
AndyAyersMS Nov 14, 2025
9ec1465
fixup after merge
AndyAyersMS Nov 14, 2025
ab5c6f1
add fgwasm.h to wasm headers
AndyAyersMS Nov 14, 2025
80c3311
merge main
AndyAyersMS Nov 15, 2025
b2b865f
bail out if there are blocks only reachable by EH. Adjust the scc tra…
AndyAyersMS Nov 17, 2025
3846d86
introduce FgWasm class
AndyAyersMS Nov 17, 2025
e413382
Puzzled
AndyAyersMS Nov 17, 2025
488e148
give FgWasm some state
AndyAyersMS Nov 17, 2025
0c382da
no more recursive lambda
AndyAyersMS Nov 18, 2025
cf4e92d
start to encapsulate dfs
AndyAyersMS Nov 18, 2025
b25a32a
encapsulate dfs and traits
AndyAyersMS Nov 18, 2025
bd35fcf
Merge branch 'main' into WasmIrreducibleLoopTransformation
AndyAyersMS Nov 18, 2025
8f6d722
review feedback
AndyAyersMS Nov 19, 2025
ea15336
fix typos
AndyAyersMS Nov 19, 2025
8187895
rename method
AndyAyersMS Nov 19, 2025
e5b2631
add more eh ret types in places
AndyAyersMS Nov 19, 2025
bf0b3bb
disable by default
AndyAyersMS Nov 22, 2025
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
31 changes: 21 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4940,6 +4940,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
}
#endif

#ifdef DEBUG
// If we are going to simulate generating wasm control flow,
// transform any strongly connected components into reducible flow.
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_DFS_BLOCKS_WASM, &Compiler::fgDfsBlocksAndRemove);
DoPhase(this, PHASE_WASM_TRANSFORM_SCCS, &Compiler::fgWasmTransformSccs);
}
#endif
Comment on lines +4943 to +4952

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional this was placed before PHASE_ASYNC, even though it is eventually going to have to be after?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional. It should be moved to just after the async transformation.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #121973


// rationalize trees
Rationalizer rat(this); // PHASE_RATIONALIZE
rat.Run();
Expand DownExpand Up@@ -4982,6 +4993,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

FinalizeEH();

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// We can not add any new tracked variables after this point.
lvaTrackedFixed = true;

Expand DownExpand Up@@ -5016,16 +5037,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
#endif

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// The common phase checks and dumps are no longer relevant past this point.
//
activePhaseChecks = PhaseChecks::CHECK_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -2764,6 +2764,7 @@ class Compiler
bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
unsigned short bbFindInnermostCommonTryRegion(unsigned tryIndex, BasicBlock* bbTwo);

unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
Expand DownExpand Up@@ -6250,6 +6251,7 @@ class Compiler

FlowGraphDfsTree* fgWasmDfs();
PhaseStatus fgWasmControlFlow();
PhaseStatus fgWasmTransformSccs();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ CompMemKindMacro(MaskConversionOpt)
CompMemKindMacro(TryRegionClone)
CompMemKindMacro(Async)
CompMemKindMacro(RangeCheckCloning)
CompMemKindMacro(WasmSccTransform)
CompMemKindMacro(WasmCfgLowering)
//clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compphases.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,8 @@ CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR",
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_POST_MORPH, "Repair profile post-morph", false, -1, false)
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_PRE_LAYOUT, "Repair profile pre-layout", false, -1, false)

CompPhaseNameMacro(PHASE_DFS_BLOCKS_WASM, "Wasm remove unreachable blocks", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_TRANSFORM_SCCS, "Wasm transform sccs", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_CONTROL_FLOW, "Wasm control flow", false, -1, false)

CompPhaseNameMacro(PHASE_ASYNC, "Transform async", false, -1, true)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4932,15 +4932,15 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
// Returns a new block, that is a successor of 'curr' and which branches unconditionally to 'succ'
//
// Assumptions:
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, or BBJ_SWITCH
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, BBJ_SWITCH, or BBJ_CALLFINALLYRET
//
// Notes:
// The returned block is empty.
// Can be invoked before pred lists are built.

BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS, BBJ_CALLFINALLYRET));
assert(fgPredsComputed);
assert(fgGetPredForBlock(succ, curr) != nullptr);

Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d3b1cf0
[Wasm RyuJIT] Wasm control flow basics
AndyAyersMS Nov 4, 2025
ca2c9b4
fix release build
AndyAyersMS Nov 6, 2025
39e0bd3
fix llvm build
AndyAyersMS Nov 6, 2025
e8882ab
Fix typos
AndyAyersMS Nov 7, 2025
890548e
Fix more typos
AndyAyersMS Nov 7, 2025
e2f71b1
[Wasm RyuJIT] Implement Wasm DFS and Loop Finding
AndyAyersMS Nov 7, 2025
4c97a19
fixes
AndyAyersMS Nov 7, 2025
3b3a13d
first cut at integrating SCCs
AndyAyersMS Nov 10, 2025
be764e3
transform sccs pre-lower
AndyAyersMS Nov 11, 2025
39f4793
handle blocks only reachable by EH
AndyAyersMS Nov 12, 2025
f1e5dcc
format
AndyAyersMS Nov 12, 2025
bc53647
remove unreachable first
AndyAyersMS Nov 13, 2025
ff1d0ac
fix dump
AndyAyersMS Nov 13, 2025
587f012
merge main
AndyAyersMS Nov 14, 2025
9ec1465
fixup after merge
AndyAyersMS Nov 14, 2025
ab5c6f1
add fgwasm.h to wasm headers
AndyAyersMS Nov 14, 2025
80c3311
merge main
AndyAyersMS Nov 15, 2025
b2b865f
bail out if there are blocks only reachable by EH. Adjust the scc tra…
AndyAyersMS Nov 17, 2025
3846d86
introduce FgWasm class
AndyAyersMS Nov 17, 2025
e413382
Puzzled
AndyAyersMS Nov 17, 2025
488e148
give FgWasm some state
AndyAyersMS Nov 17, 2025
0c382da
no more recursive lambda
AndyAyersMS Nov 18, 2025
cf4e92d
start to encapsulate dfs
AndyAyersMS Nov 18, 2025
b25a32a
encapsulate dfs and traits
AndyAyersMS Nov 18, 2025
bd35fcf
Merge branch 'main' into WasmIrreducibleLoopTransformation
AndyAyersMS Nov 18, 2025
8f6d722
review feedback
AndyAyersMS Nov 19, 2025
ea15336
fix typos
AndyAyersMS Nov 19, 2025
8187895
rename method
AndyAyersMS Nov 19, 2025
e5b2631
add more eh ret types in places
AndyAyersMS Nov 19, 2025
bf0b3bb
disable by default
AndyAyersMS Nov 22, 2025
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
31 changes: 21 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4940,6 +4940,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
}
#endif

#ifdef DEBUG
// If we are going to simulate generating wasm control flow,
// transform any strongly connected components into reducible flow.
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_DFS_BLOCKS_WASM, &Compiler::fgDfsBlocksAndRemove);
DoPhase(this, PHASE_WASM_TRANSFORM_SCCS, &Compiler::fgWasmTransformSccs);
}
#endif
Comment on lines +4943 to +4952

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional this was placed before PHASE_ASYNC, even though it is eventually going to have to be after?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional. It should be moved to just after the async transformation.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #121973


// rationalize trees
Rationalizer rat(this); // PHASE_RATIONALIZE
rat.Run();
Expand DownExpand Up@@ -4982,6 +4993,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

FinalizeEH();

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// We can not add any new tracked variables after this point.
lvaTrackedFixed = true;

Expand DownExpand Up@@ -5016,16 +5037,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
#endif

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// The common phase checks and dumps are no longer relevant past this point.
//
activePhaseChecks = PhaseChecks::CHECK_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -2764,6 +2764,7 @@ class Compiler
bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
unsigned short bbFindInnermostCommonTryRegion(unsigned tryIndex, BasicBlock* bbTwo);

unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
Expand DownExpand Up@@ -6250,6 +6251,7 @@ class Compiler

FlowGraphDfsTree* fgWasmDfs();
PhaseStatus fgWasmControlFlow();
PhaseStatus fgWasmTransformSccs();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ CompMemKindMacro(MaskConversionOpt)
CompMemKindMacro(TryRegionClone)
CompMemKindMacro(Async)
CompMemKindMacro(RangeCheckCloning)
CompMemKindMacro(WasmSccTransform)
CompMemKindMacro(WasmCfgLowering)
//clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compphases.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,8 @@ CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR",
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_POST_MORPH, "Repair profile post-morph", false, -1, false)
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_PRE_LAYOUT, "Repair profile pre-layout", false, -1, false)

CompPhaseNameMacro(PHASE_DFS_BLOCKS_WASM, "Wasm remove unreachable blocks", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_TRANSFORM_SCCS, "Wasm transform sccs", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_CONTROL_FLOW, "Wasm control flow", false, -1, false)

CompPhaseNameMacro(PHASE_ASYNC, "Transform async", false, -1, true)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4932,15 +4932,15 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
// Returns a new block, that is a successor of 'curr' and which branches unconditionally to 'succ'
//
// Assumptions:
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, or BBJ_SWITCH
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, BBJ_SWITCH, or BBJ_CALLFINALLYRET
//
// Notes:
// The returned block is empty.
// Can be invoked before pred lists are built.

BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS, BBJ_CALLFINALLYRET));
assert(fgPredsComputed);
assert(fgGetPredForBlock(succ, curr) != nullptr);

Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d3b1cf0
[Wasm RyuJIT] Wasm control flow basics
AndyAyersMS Nov 4, 2025
ca2c9b4
fix release build
AndyAyersMS Nov 6, 2025
39e0bd3
fix llvm build
AndyAyersMS Nov 6, 2025
e8882ab
Fix typos
AndyAyersMS Nov 7, 2025
890548e
Fix more typos
AndyAyersMS Nov 7, 2025
e2f71b1
[Wasm RyuJIT] Implement Wasm DFS and Loop Finding
AndyAyersMS Nov 7, 2025
4c97a19
fixes
AndyAyersMS Nov 7, 2025
3b3a13d
first cut at integrating SCCs
AndyAyersMS Nov 10, 2025
be764e3
transform sccs pre-lower
AndyAyersMS Nov 11, 2025
39f4793
handle blocks only reachable by EH
AndyAyersMS Nov 12, 2025
f1e5dcc
format
AndyAyersMS Nov 12, 2025
bc53647
remove unreachable first
AndyAyersMS Nov 13, 2025
ff1d0ac
fix dump
AndyAyersMS Nov 13, 2025
587f012
merge main
AndyAyersMS Nov 14, 2025
9ec1465
fixup after merge
AndyAyersMS Nov 14, 2025
ab5c6f1
add fgwasm.h to wasm headers
AndyAyersMS Nov 14, 2025
80c3311
merge main
AndyAyersMS Nov 15, 2025
b2b865f
bail out if there are blocks only reachable by EH. Adjust the scc tra…
AndyAyersMS Nov 17, 2025
3846d86
introduce FgWasm class
AndyAyersMS Nov 17, 2025
e413382
Puzzled
AndyAyersMS Nov 17, 2025
488e148
give FgWasm some state
AndyAyersMS Nov 17, 2025
0c382da
no more recursive lambda
AndyAyersMS Nov 18, 2025
cf4e92d
start to encapsulate dfs
AndyAyersMS Nov 18, 2025
b25a32a
encapsulate dfs and traits
AndyAyersMS Nov 18, 2025
bd35fcf
Merge branch 'main' into WasmIrreducibleLoopTransformation
AndyAyersMS Nov 18, 2025
8f6d722
review feedback
AndyAyersMS Nov 19, 2025
ea15336
fix typos
AndyAyersMS Nov 19, 2025
8187895
rename method
AndyAyersMS Nov 19, 2025
e5b2631
add more eh ret types in places
AndyAyersMS Nov 19, 2025
bf0b3bb
disable by default
AndyAyersMS Nov 22, 2025
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
31 changes: 21 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4940,6 +4940,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
}
#endif

#ifdef DEBUG
// If we are going to simulate generating wasm control flow,
// transform any strongly connected components into reducible flow.
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_DFS_BLOCKS_WASM, &Compiler::fgDfsBlocksAndRemove);
DoPhase(this, PHASE_WASM_TRANSFORM_SCCS, &Compiler::fgWasmTransformSccs);
}
#endif
Comment on lines +4943 to +4952

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional this was placed before PHASE_ASYNC, even though it is eventually going to have to be after?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional. It should be moved to just after the async transformation.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #121973


// rationalize trees
Rationalizer rat(this); // PHASE_RATIONALIZE
rat.Run();
Expand DownExpand Up@@ -4982,6 +4993,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

FinalizeEH();

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// We can not add any new tracked variables after this point.
lvaTrackedFixed = true;

Expand DownExpand Up@@ -5016,16 +5037,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
#endif

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// The common phase checks and dumps are no longer relevant past this point.
//
activePhaseChecks = PhaseChecks::CHECK_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -2764,6 +2764,7 @@ class Compiler
bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
unsigned short bbFindInnermostCommonTryRegion(unsigned tryIndex, BasicBlock* bbTwo);

unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
Expand DownExpand Up@@ -6250,6 +6251,7 @@ class Compiler

FlowGraphDfsTree* fgWasmDfs();
PhaseStatus fgWasmControlFlow();
PhaseStatus fgWasmTransformSccs();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ CompMemKindMacro(MaskConversionOpt)
CompMemKindMacro(TryRegionClone)
CompMemKindMacro(Async)
CompMemKindMacro(RangeCheckCloning)
CompMemKindMacro(WasmSccTransform)
CompMemKindMacro(WasmCfgLowering)
//clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compphases.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,8 @@ CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR",
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_POST_MORPH, "Repair profile post-morph", false, -1, false)
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_PRE_LAYOUT, "Repair profile pre-layout", false, -1, false)

CompPhaseNameMacro(PHASE_DFS_BLOCKS_WASM, "Wasm remove unreachable blocks", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_TRANSFORM_SCCS, "Wasm transform sccs", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_CONTROL_FLOW, "Wasm control flow", false, -1, false)

CompPhaseNameMacro(PHASE_ASYNC, "Transform async", false, -1, true)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4932,15 +4932,15 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
// Returns a new block, that is a successor of 'curr' and which branches unconditionally to 'succ'
//
// Assumptions:
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, or BBJ_SWITCH
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, BBJ_SWITCH, or BBJ_CALLFINALLYRET
//
// Notes:
// The returned block is empty.
// Can be invoked before pred lists are built.

BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS, BBJ_CALLFINALLYRET));
assert(fgPredsComputed);
assert(fgGetPredForBlock(succ, curr) != nullptr);

Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d3b1cf0
[Wasm RyuJIT] Wasm control flow basics
AndyAyersMS Nov 4, 2025
ca2c9b4
fix release build
AndyAyersMS Nov 6, 2025
39e0bd3
fix llvm build
AndyAyersMS Nov 6, 2025
e8882ab
Fix typos
AndyAyersMS Nov 7, 2025
890548e
Fix more typos
AndyAyersMS Nov 7, 2025
e2f71b1
[Wasm RyuJIT] Implement Wasm DFS and Loop Finding
AndyAyersMS Nov 7, 2025
4c97a19
fixes
AndyAyersMS Nov 7, 2025
3b3a13d
first cut at integrating SCCs
AndyAyersMS Nov 10, 2025
be764e3
transform sccs pre-lower
AndyAyersMS Nov 11, 2025
39f4793
handle blocks only reachable by EH
AndyAyersMS Nov 12, 2025
f1e5dcc
format
AndyAyersMS Nov 12, 2025
bc53647
remove unreachable first
AndyAyersMS Nov 13, 2025
ff1d0ac
fix dump
AndyAyersMS Nov 13, 2025
587f012
merge main
AndyAyersMS Nov 14, 2025
9ec1465
fixup after merge
AndyAyersMS Nov 14, 2025
ab5c6f1
add fgwasm.h to wasm headers
AndyAyersMS Nov 14, 2025
80c3311
merge main
AndyAyersMS Nov 15, 2025
b2b865f
bail out if there are blocks only reachable by EH. Adjust the scc tra…
AndyAyersMS Nov 17, 2025
3846d86
introduce FgWasm class
AndyAyersMS Nov 17, 2025
e413382
Puzzled
AndyAyersMS Nov 17, 2025
488e148
give FgWasm some state
AndyAyersMS Nov 17, 2025
0c382da
no more recursive lambda
AndyAyersMS Nov 18, 2025
cf4e92d
start to encapsulate dfs
AndyAyersMS Nov 18, 2025
b25a32a
encapsulate dfs and traits
AndyAyersMS Nov 18, 2025
bd35fcf
Merge branch 'main' into WasmIrreducibleLoopTransformation
AndyAyersMS Nov 18, 2025
8f6d722
review feedback
AndyAyersMS Nov 19, 2025
ea15336
fix typos
AndyAyersMS Nov 19, 2025
8187895
rename method
AndyAyersMS Nov 19, 2025
e5b2631
add more eh ret types in places
AndyAyersMS Nov 19, 2025
bf0b3bb
disable by default
AndyAyersMS Nov 22, 2025
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
31 changes: 21 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4940,6 +4940,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
}
#endif

#ifdef DEBUG
// If we are going to simulate generating wasm control flow,
// transform any strongly connected components into reducible flow.
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_DFS_BLOCKS_WASM, &Compiler::fgDfsBlocksAndRemove);
DoPhase(this, PHASE_WASM_TRANSFORM_SCCS, &Compiler::fgWasmTransformSccs);
}
#endif
Comment on lines +4943 to +4952

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional this was placed before PHASE_ASYNC, even though it is eventually going to have to be after?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional. It should be moved to just after the async transformation.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #121973


// rationalize trees
Rationalizer rat(this); // PHASE_RATIONALIZE
rat.Run();
Expand DownExpand Up@@ -4982,6 +4993,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

FinalizeEH();

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// We can not add any new tracked variables after this point.
lvaTrackedFixed = true;

Expand DownExpand Up@@ -5016,16 +5037,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
#endif

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// The common phase checks and dumps are no longer relevant past this point.
//
activePhaseChecks = PhaseChecks::CHECK_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -2764,6 +2764,7 @@ class Compiler
bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
unsigned short bbFindInnermostCommonTryRegion(unsigned tryIndex, BasicBlock* bbTwo);

unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
Expand DownExpand Up@@ -6250,6 +6251,7 @@ class Compiler

FlowGraphDfsTree* fgWasmDfs();
PhaseStatus fgWasmControlFlow();
PhaseStatus fgWasmTransformSccs();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ CompMemKindMacro(MaskConversionOpt)
CompMemKindMacro(TryRegionClone)
CompMemKindMacro(Async)
CompMemKindMacro(RangeCheckCloning)
CompMemKindMacro(WasmSccTransform)
CompMemKindMacro(WasmCfgLowering)
//clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compphases.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,8 @@ CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR",
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_POST_MORPH, "Repair profile post-morph", false, -1, false)
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_PRE_LAYOUT, "Repair profile pre-layout", false, -1, false)

CompPhaseNameMacro(PHASE_DFS_BLOCKS_WASM, "Wasm remove unreachable blocks", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_TRANSFORM_SCCS, "Wasm transform sccs", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_CONTROL_FLOW, "Wasm control flow", false, -1, false)

CompPhaseNameMacro(PHASE_ASYNC, "Transform async", false, -1, true)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4932,15 +4932,15 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
// Returns a new block, that is a successor of 'curr' and which branches unconditionally to 'succ'
//
// Assumptions:
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, or BBJ_SWITCH
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, BBJ_SWITCH, or BBJ_CALLFINALLYRET
//
// Notes:
// The returned block is empty.
// Can be invoked before pred lists are built.

BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS, BBJ_CALLFINALLYRET));
assert(fgPredsComputed);
assert(fgGetPredForBlock(succ, curr) != nullptr);

Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d3b1cf0
[Wasm RyuJIT] Wasm control flow basics
AndyAyersMS Nov 4, 2025
ca2c9b4
fix release build
AndyAyersMS Nov 6, 2025
39e0bd3
fix llvm build
AndyAyersMS Nov 6, 2025
e8882ab
Fix typos
AndyAyersMS Nov 7, 2025
890548e
Fix more typos
AndyAyersMS Nov 7, 2025
e2f71b1
[Wasm RyuJIT] Implement Wasm DFS and Loop Finding
AndyAyersMS Nov 7, 2025
4c97a19
fixes
AndyAyersMS Nov 7, 2025
3b3a13d
first cut at integrating SCCs
AndyAyersMS Nov 10, 2025
be764e3
transform sccs pre-lower
AndyAyersMS Nov 11, 2025
39f4793
handle blocks only reachable by EH
AndyAyersMS Nov 12, 2025
f1e5dcc
format
AndyAyersMS Nov 12, 2025
bc53647
remove unreachable first
AndyAyersMS Nov 13, 2025
ff1d0ac
fix dump
AndyAyersMS Nov 13, 2025
587f012
merge main
AndyAyersMS Nov 14, 2025
9ec1465
fixup after merge
AndyAyersMS Nov 14, 2025
ab5c6f1
add fgwasm.h to wasm headers
AndyAyersMS Nov 14, 2025
80c3311
merge main
AndyAyersMS Nov 15, 2025
b2b865f
bail out if there are blocks only reachable by EH. Adjust the scc tra…
AndyAyersMS Nov 17, 2025
3846d86
introduce FgWasm class
AndyAyersMS Nov 17, 2025
e413382
Puzzled
AndyAyersMS Nov 17, 2025
488e148
give FgWasm some state
AndyAyersMS Nov 17, 2025
0c382da
no more recursive lambda
AndyAyersMS Nov 18, 2025
cf4e92d
start to encapsulate dfs
AndyAyersMS Nov 18, 2025
b25a32a
encapsulate dfs and traits
AndyAyersMS Nov 18, 2025
bd35fcf
Merge branch 'main' into WasmIrreducibleLoopTransformation
AndyAyersMS Nov 18, 2025
8f6d722
review feedback
AndyAyersMS Nov 19, 2025
ea15336
fix typos
AndyAyersMS Nov 19, 2025
8187895
rename method
AndyAyersMS Nov 19, 2025
e5b2631
add more eh ret types in places
AndyAyersMS Nov 19, 2025
bf0b3bb
disable by default
AndyAyersMS Nov 22, 2025
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
31 changes: 21 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4940,6 +4940,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
}
#endif

#ifdef DEBUG
// If we are going to simulate generating wasm control flow,
// transform any strongly connected components into reducible flow.
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_DFS_BLOCKS_WASM, &Compiler::fgDfsBlocksAndRemove);
DoPhase(this, PHASE_WASM_TRANSFORM_SCCS, &Compiler::fgWasmTransformSccs);
}
#endif
Comment on lines +4943 to +4952

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional this was placed before PHASE_ASYNC, even though it is eventually going to have to be after?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional. It should be moved to just after the async transformation.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #121973


// rationalize trees
Rationalizer rat(this); // PHASE_RATIONALIZE
rat.Run();
Expand DownExpand Up@@ -4982,6 +4993,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

FinalizeEH();

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// We can not add any new tracked variables after this point.
lvaTrackedFixed = true;

Expand DownExpand Up@@ -5016,16 +5037,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
#endif

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// The common phase checks and dumps are no longer relevant past this point.
//
activePhaseChecks = PhaseChecks::CHECK_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -2764,6 +2764,7 @@ class Compiler
bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
unsigned short bbFindInnermostCommonTryRegion(unsigned tryIndex, BasicBlock* bbTwo);

unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
Expand DownExpand Up@@ -6250,6 +6251,7 @@ class Compiler

FlowGraphDfsTree* fgWasmDfs();
PhaseStatus fgWasmControlFlow();
PhaseStatus fgWasmTransformSccs();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ CompMemKindMacro(MaskConversionOpt)
CompMemKindMacro(TryRegionClone)
CompMemKindMacro(Async)
CompMemKindMacro(RangeCheckCloning)
CompMemKindMacro(WasmSccTransform)
CompMemKindMacro(WasmCfgLowering)
//clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compphases.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,8 @@ CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR",
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_POST_MORPH, "Repair profile post-morph", false, -1, false)
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_PRE_LAYOUT, "Repair profile pre-layout", false, -1, false)

CompPhaseNameMacro(PHASE_DFS_BLOCKS_WASM, "Wasm remove unreachable blocks", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_TRANSFORM_SCCS, "Wasm transform sccs", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_CONTROL_FLOW, "Wasm control flow", false, -1, false)

CompPhaseNameMacro(PHASE_ASYNC, "Transform async", false, -1, true)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4932,15 +4932,15 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
// Returns a new block, that is a successor of 'curr' and which branches unconditionally to 'succ'
//
// Assumptions:
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, or BBJ_SWITCH
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, BBJ_SWITCH, or BBJ_CALLFINALLYRET
//
// Notes:
// The returned block is empty.
// Can be invoked before pred lists are built.

BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS, BBJ_CALLFINALLYRET));
assert(fgPredsComputed);
assert(fgGetPredForBlock(succ, curr) != nullptr);

Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d3b1cf0
[Wasm RyuJIT] Wasm control flow basics
AndyAyersMS Nov 4, 2025
ca2c9b4
fix release build
AndyAyersMS Nov 6, 2025
39e0bd3
fix llvm build
AndyAyersMS Nov 6, 2025
e8882ab
Fix typos
AndyAyersMS Nov 7, 2025
890548e
Fix more typos
AndyAyersMS Nov 7, 2025
e2f71b1
[Wasm RyuJIT] Implement Wasm DFS and Loop Finding
AndyAyersMS Nov 7, 2025
4c97a19
fixes
AndyAyersMS Nov 7, 2025
3b3a13d
first cut at integrating SCCs
AndyAyersMS Nov 10, 2025
be764e3
transform sccs pre-lower
AndyAyersMS Nov 11, 2025
39f4793
handle blocks only reachable by EH
AndyAyersMS Nov 12, 2025
f1e5dcc
format
AndyAyersMS Nov 12, 2025
bc53647
remove unreachable first
AndyAyersMS Nov 13, 2025
ff1d0ac
fix dump
AndyAyersMS Nov 13, 2025
587f012
merge main
AndyAyersMS Nov 14, 2025
9ec1465
fixup after merge
AndyAyersMS Nov 14, 2025
ab5c6f1
add fgwasm.h to wasm headers
AndyAyersMS Nov 14, 2025
80c3311
merge main
AndyAyersMS Nov 15, 2025
b2b865f
bail out if there are blocks only reachable by EH. Adjust the scc tra…
AndyAyersMS Nov 17, 2025
3846d86
introduce FgWasm class
AndyAyersMS Nov 17, 2025
e413382
Puzzled
AndyAyersMS Nov 17, 2025
488e148
give FgWasm some state
AndyAyersMS Nov 17, 2025
0c382da
no more recursive lambda
AndyAyersMS Nov 18, 2025
cf4e92d
start to encapsulate dfs
AndyAyersMS Nov 18, 2025
b25a32a
encapsulate dfs and traits
AndyAyersMS Nov 18, 2025
bd35fcf
Merge branch 'main' into WasmIrreducibleLoopTransformation
AndyAyersMS Nov 18, 2025
8f6d722
review feedback
AndyAyersMS Nov 19, 2025
ea15336
fix typos
AndyAyersMS Nov 19, 2025
8187895
rename method
AndyAyersMS Nov 19, 2025
e5b2631
add more eh ret types in places
AndyAyersMS Nov 19, 2025
bf0b3bb
disable by default
AndyAyersMS Nov 22, 2025
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
31 changes: 21 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4940,6 +4940,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
}
#endif

#ifdef DEBUG
// If we are going to simulate generating wasm control flow,
// transform any strongly connected components into reducible flow.
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_DFS_BLOCKS_WASM, &Compiler::fgDfsBlocksAndRemove);
DoPhase(this, PHASE_WASM_TRANSFORM_SCCS, &Compiler::fgWasmTransformSccs);
}
#endif
Comment on lines +4943 to +4952

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional this was placed before PHASE_ASYNC, even though it is eventually going to have to be after?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional. It should be moved to just after the async transformation.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #121973


// rationalize trees
Rationalizer rat(this); // PHASE_RATIONALIZE
rat.Run();
Expand DownExpand Up@@ -4982,6 +4993,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

FinalizeEH();

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// We can not add any new tracked variables after this point.
lvaTrackedFixed = true;

Expand DownExpand Up@@ -5016,16 +5037,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
#endif

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// The common phase checks and dumps are no longer relevant past this point.
//
activePhaseChecks = PhaseChecks::CHECK_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -2764,6 +2764,7 @@ class Compiler
bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
unsigned short bbFindInnermostCommonTryRegion(unsigned tryIndex, BasicBlock* bbTwo);

unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
Expand DownExpand Up@@ -6250,6 +6251,7 @@ class Compiler

FlowGraphDfsTree* fgWasmDfs();
PhaseStatus fgWasmControlFlow();
PhaseStatus fgWasmTransformSccs();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ CompMemKindMacro(MaskConversionOpt)
CompMemKindMacro(TryRegionClone)
CompMemKindMacro(Async)
CompMemKindMacro(RangeCheckCloning)
CompMemKindMacro(WasmSccTransform)
CompMemKindMacro(WasmCfgLowering)
//clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compphases.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,8 @@ CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR",
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_POST_MORPH, "Repair profile post-morph", false, -1, false)
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_PRE_LAYOUT, "Repair profile pre-layout", false, -1, false)

CompPhaseNameMacro(PHASE_DFS_BLOCKS_WASM, "Wasm remove unreachable blocks", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_TRANSFORM_SCCS, "Wasm transform sccs", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_CONTROL_FLOW, "Wasm control flow", false, -1, false)

CompPhaseNameMacro(PHASE_ASYNC, "Transform async", false, -1, true)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4932,15 +4932,15 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
// Returns a new block, that is a successor of 'curr' and which branches unconditionally to 'succ'
//
// Assumptions:
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, or BBJ_SWITCH
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, BBJ_SWITCH, or BBJ_CALLFINALLYRET
//
// Notes:
// The returned block is empty.
// Can be invoked before pred lists are built.

BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS, BBJ_CALLFINALLYRET));
assert(fgPredsComputed);
assert(fgGetPredForBlock(succ, curr) != nullptr);

Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d3b1cf0
[Wasm RyuJIT] Wasm control flow basics
AndyAyersMS Nov 4, 2025
ca2c9b4
fix release build
AndyAyersMS Nov 6, 2025
39e0bd3
fix llvm build
AndyAyersMS Nov 6, 2025
e8882ab
Fix typos
AndyAyersMS Nov 7, 2025
890548e
Fix more typos
AndyAyersMS Nov 7, 2025
e2f71b1
[Wasm RyuJIT] Implement Wasm DFS and Loop Finding
AndyAyersMS Nov 7, 2025
4c97a19
fixes
AndyAyersMS Nov 7, 2025
3b3a13d
first cut at integrating SCCs
AndyAyersMS Nov 10, 2025
be764e3
transform sccs pre-lower
AndyAyersMS Nov 11, 2025
39f4793
handle blocks only reachable by EH
AndyAyersMS Nov 12, 2025
f1e5dcc
format
AndyAyersMS Nov 12, 2025
bc53647
remove unreachable first
AndyAyersMS Nov 13, 2025
ff1d0ac
fix dump
AndyAyersMS Nov 13, 2025
587f012
merge main
AndyAyersMS Nov 14, 2025
9ec1465
fixup after merge
AndyAyersMS Nov 14, 2025
ab5c6f1
add fgwasm.h to wasm headers
AndyAyersMS Nov 14, 2025
80c3311
merge main
AndyAyersMS Nov 15, 2025
b2b865f
bail out if there are blocks only reachable by EH. Adjust the scc tra…
AndyAyersMS Nov 17, 2025
3846d86
introduce FgWasm class
AndyAyersMS Nov 17, 2025
e413382
Puzzled
AndyAyersMS Nov 17, 2025
488e148
give FgWasm some state
AndyAyersMS Nov 17, 2025
0c382da
no more recursive lambda
AndyAyersMS Nov 18, 2025
cf4e92d
start to encapsulate dfs
AndyAyersMS Nov 18, 2025
b25a32a
encapsulate dfs and traits
AndyAyersMS Nov 18, 2025
bd35fcf
Merge branch 'main' into WasmIrreducibleLoopTransformation
AndyAyersMS Nov 18, 2025
8f6d722
review feedback
AndyAyersMS Nov 19, 2025
ea15336
fix typos
AndyAyersMS Nov 19, 2025
8187895
rename method
AndyAyersMS Nov 19, 2025
e5b2631
add more eh ret types in places
AndyAyersMS Nov 19, 2025
bf0b3bb
disable by default
AndyAyersMS Nov 22, 2025
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
31 changes: 21 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4940,6 +4940,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
}
#endif

#ifdef DEBUG
// If we are going to simulate generating wasm control flow,
// transform any strongly connected components into reducible flow.
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_DFS_BLOCKS_WASM, &Compiler::fgDfsBlocksAndRemove);
DoPhase(this, PHASE_WASM_TRANSFORM_SCCS, &Compiler::fgWasmTransformSccs);
}
#endif
Comment on lines +4943 to +4952

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional this was placed before PHASE_ASYNC, even though it is eventually going to have to be after?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional. It should be moved to just after the async transformation.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #121973


// rationalize trees
Rationalizer rat(this); // PHASE_RATIONALIZE
rat.Run();
Expand DownExpand Up@@ -4982,6 +4993,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

FinalizeEH();

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// We can not add any new tracked variables after this point.
lvaTrackedFixed = true;

Expand DownExpand Up@@ -5016,16 +5037,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
#endif

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// The common phase checks and dumps are no longer relevant past this point.
//
activePhaseChecks = PhaseChecks::CHECK_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -2764,6 +2764,7 @@ class Compiler
bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
unsigned short bbFindInnermostCommonTryRegion(unsigned tryIndex, BasicBlock* bbTwo);

unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
Expand DownExpand Up@@ -6250,6 +6251,7 @@ class Compiler

FlowGraphDfsTree* fgWasmDfs();
PhaseStatus fgWasmControlFlow();
PhaseStatus fgWasmTransformSccs();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ CompMemKindMacro(MaskConversionOpt)
CompMemKindMacro(TryRegionClone)
CompMemKindMacro(Async)
CompMemKindMacro(RangeCheckCloning)
CompMemKindMacro(WasmSccTransform)
CompMemKindMacro(WasmCfgLowering)
//clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compphases.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,8 @@ CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR",
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_POST_MORPH, "Repair profile post-morph", false, -1, false)
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_PRE_LAYOUT, "Repair profile pre-layout", false, -1, false)

CompPhaseNameMacro(PHASE_DFS_BLOCKS_WASM, "Wasm remove unreachable blocks", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_TRANSFORM_SCCS, "Wasm transform sccs", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_CONTROL_FLOW, "Wasm control flow", false, -1, false)

CompPhaseNameMacro(PHASE_ASYNC, "Transform async", false, -1, true)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4932,15 +4932,15 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
// Returns a new block, that is a successor of 'curr' and which branches unconditionally to 'succ'
//
// Assumptions:
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, or BBJ_SWITCH
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, BBJ_SWITCH, or BBJ_CALLFINALLYRET
//
// Notes:
// The returned block is empty.
// Can be invoked before pred lists are built.

BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS, BBJ_CALLFINALLYRET));
assert(fgPredsComputed);
assert(fgGetPredForBlock(succ, curr) != nullptr);

Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d3b1cf0
[Wasm RyuJIT] Wasm control flow basics
AndyAyersMS Nov 4, 2025
ca2c9b4
fix release build
AndyAyersMS Nov 6, 2025
39e0bd3
fix llvm build
AndyAyersMS Nov 6, 2025
e8882ab
Fix typos
AndyAyersMS Nov 7, 2025
890548e
Fix more typos
AndyAyersMS Nov 7, 2025
e2f71b1
[Wasm RyuJIT] Implement Wasm DFS and Loop Finding
AndyAyersMS Nov 7, 2025
4c97a19
fixes
AndyAyersMS Nov 7, 2025
3b3a13d
first cut at integrating SCCs
AndyAyersMS Nov 10, 2025
be764e3
transform sccs pre-lower
AndyAyersMS Nov 11, 2025
39f4793
handle blocks only reachable by EH
AndyAyersMS Nov 12, 2025
f1e5dcc
format
AndyAyersMS Nov 12, 2025
bc53647
remove unreachable first
AndyAyersMS Nov 13, 2025
ff1d0ac
fix dump
AndyAyersMS Nov 13, 2025
587f012
merge main
AndyAyersMS Nov 14, 2025
9ec1465
fixup after merge
AndyAyersMS Nov 14, 2025
ab5c6f1
add fgwasm.h to wasm headers
AndyAyersMS Nov 14, 2025
80c3311
merge main
AndyAyersMS Nov 15, 2025
b2b865f
bail out if there are blocks only reachable by EH. Adjust the scc tra…
AndyAyersMS Nov 17, 2025
3846d86
introduce FgWasm class
AndyAyersMS Nov 17, 2025
e413382
Puzzled
AndyAyersMS Nov 17, 2025
488e148
give FgWasm some state
AndyAyersMS Nov 17, 2025
0c382da
no more recursive lambda
AndyAyersMS Nov 18, 2025
cf4e92d
start to encapsulate dfs
AndyAyersMS Nov 18, 2025
b25a32a
encapsulate dfs and traits
AndyAyersMS Nov 18, 2025
bd35fcf
Merge branch 'main' into WasmIrreducibleLoopTransformation
AndyAyersMS Nov 18, 2025
8f6d722
review feedback
AndyAyersMS Nov 19, 2025
ea15336
fix typos
AndyAyersMS Nov 19, 2025
8187895
rename method
AndyAyersMS Nov 19, 2025
e5b2631
add more eh ret types in places
AndyAyersMS Nov 19, 2025
bf0b3bb
disable by default
AndyAyersMS Nov 22, 2025
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
31 changes: 21 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4940,6 +4940,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
}
#endif

#ifdef DEBUG
// If we are going to simulate generating wasm control flow,
// transform any strongly connected components into reducible flow.
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_DFS_BLOCKS_WASM, &Compiler::fgDfsBlocksAndRemove);
DoPhase(this, PHASE_WASM_TRANSFORM_SCCS, &Compiler::fgWasmTransformSccs);
}
#endif
Comment on lines +4943 to +4952

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional this was placed before PHASE_ASYNC, even though it is eventually going to have to be after?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional. It should be moved to just after the async transformation.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #121973


// rationalize trees
Rationalizer rat(this); // PHASE_RATIONALIZE
rat.Run();
Expand DownExpand Up@@ -4982,6 +4993,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

FinalizeEH();

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// We can not add any new tracked variables after this point.
lvaTrackedFixed = true;

Expand DownExpand Up@@ -5016,16 +5037,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
#endif

#ifdef DEBUG
// Optionally, simulate generating wasm control flow
// (eventually this will become part of the wasm target)
//
if (JitConfig.JitWasmControlFlow() > 0)
{
DoPhase(this, PHASE_WASM_CONTROL_FLOW, &Compiler::fgWasmControlFlow);
}
#endif

// The common phase checks and dumps are no longer relevant past this point.
//
activePhaseChecks = PhaseChecks::CHECK_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -2764,6 +2764,7 @@ class Compiler
bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
unsigned short bbFindInnermostCommonTryRegion(unsigned tryIndex, BasicBlock* bbTwo);

unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
Expand DownExpand Up@@ -6250,6 +6251,7 @@ class Compiler

FlowGraphDfsTree* fgWasmDfs();
PhaseStatus fgWasmControlFlow();
PhaseStatus fgWasmTransformSccs();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compmemkind.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,6 +68,7 @@ CompMemKindMacro(MaskConversionOpt)
CompMemKindMacro(TryRegionClone)
CompMemKindMacro(Async)
CompMemKindMacro(RangeCheckCloning)
CompMemKindMacro(WasmSccTransform)
CompMemKindMacro(WasmCfgLowering)
//clang-format on

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compphases.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,8 @@ CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR",
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_POST_MORPH, "Repair profile post-morph", false, -1, false)
CompPhaseNameMacro(PHASE_REPAIR_PROFILE_PRE_LAYOUT, "Repair profile pre-layout", false, -1, false)

CompPhaseNameMacro(PHASE_DFS_BLOCKS_WASM, "Wasm remove unreachable blocks", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_TRANSFORM_SCCS, "Wasm transform sccs", false, -1, false)
CompPhaseNameMacro(PHASE_WASM_CONTROL_FLOW, "Wasm control flow", false, -1, false)

CompPhaseNameMacro(PHASE_ASYNC, "Transform async", false, -1, true)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -4932,15 +4932,15 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
// Returns a new block, that is a successor of 'curr' and which branches unconditionally to 'succ'
//
// Assumptions:
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, or BBJ_SWITCH
// 'curr' must have a bbKind of BBJ_COND, BBJ_ALWAYS, BBJ_SWITCH, or BBJ_CALLFINALLYRET
//
// Notes:
// The returned block is empty.
// Can be invoked before pred lists are built.

BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS, BBJ_CALLFINALLYRET));
assert(fgPredsComputed);
assert(fgGetPredForBlock(succ, curr) != nullptr);

Expand Down
Loading
Loading