@@ -44864,6 +44864,85 @@ function findOptionalPlaces(fn) {
4486444864 return optionals;
4486544865}
4486644866
44867+ function createControlDominators(fn, isControlVariable) {
44868+ const postDominators = computePostDominatorTree(fn, {
44869+ includeThrowsAsExitNode: false,
44870+ });
44871+ const postDominatorFrontierCache = new Map();
44872+ function isControlledBlock(id) {
44873+ let controlBlocks = postDominatorFrontierCache.get(id);
44874+ if (controlBlocks === undefined) {
44875+ controlBlocks = postDominatorFrontier(fn, postDominators, id);
44876+ postDominatorFrontierCache.set(id, controlBlocks);
44877+ }
44878+ for (const blockId of controlBlocks) {
44879+ const controlBlock = fn.body.blocks.get(blockId);
44880+ switch (controlBlock.terminal.kind) {
44881+ case 'if':
44882+ case 'branch': {
44883+ if (isControlVariable(controlBlock.terminal.test)) {
44884+ return true;
44885+ }
44886+ break;
44887+ }
44888+ case 'switch': {
44889+ if (isControlVariable(controlBlock.terminal.test)) {
44890+ return true;
44891+ }
44892+ for (const case_ of controlBlock.terminal.cases) {
44893+ if (case_.test !== null && isControlVariable(case_.test)) {
44894+ return true;
44895+ }
44896+ }
44897+ break;
44898+ }
44899+ }
44900+ }
44901+ return false;
44902+ }
44903+ return isControlledBlock;
44904+ }
44905+ function postDominatorFrontier(fn, postDominators, targetId) {
44906+ const visited = new Set();
44907+ const frontier = new Set();
44908+ const targetPostDominators = postDominatorsOf(fn, postDominators, targetId);
44909+ for (const blockId of [...targetPostDominators, targetId]) {
44910+ if (visited.has(blockId)) {
44911+ continue;
44912+ }
44913+ visited.add(blockId);
44914+ const block = fn.body.blocks.get(blockId);
44915+ for (const pred of block.preds) {
44916+ if (!targetPostDominators.has(pred)) {
44917+ frontier.add(pred);
44918+ }
44919+ }
44920+ }
44921+ return frontier;
44922+ }
44923+ function postDominatorsOf(fn, postDominators, targetId) {
44924+ var _a;
44925+ const result = new Set();
44926+ const visited = new Set();
44927+ const queue = [targetId];
44928+ while (queue.length) {
44929+ const currentId = queue.shift();
44930+ if (visited.has(currentId)) {
44931+ continue;
44932+ }
44933+ visited.add(currentId);
44934+ const current = fn.body.blocks.get(currentId);
44935+ for (const pred of current.preds) {
44936+ const predPostDominator = (_a = postDominators.get(pred)) !== null && _a !== void 0 ? _a : pred;
44937+ if (predPostDominator === targetId || result.has(predPostDominator)) {
44938+ result.add(pred);
44939+ }
44940+ queue.push(pred);
44941+ }
44942+ }
44943+ return result;
44944+ }
44945+
4486744946class StableSidemap {
4486844947 constructor(env) {
4486944948 this.map = new Map();
@@ -44939,42 +45018,7 @@ function inferReactivePlaces(fn) {
4493945018 const place = param.kind === 'Identifier' ? param : param.place;
4494045019 reactiveIdentifiers.markReactive(place);
4494145020 }
44942- const postDominators = computePostDominatorTree(fn, {
44943- includeThrowsAsExitNode: false,
44944- });
44945- const postDominatorFrontierCache = new Map();
44946- function isReactiveControlledBlock(id) {
44947- let controlBlocks = postDominatorFrontierCache.get(id);
44948- if (controlBlocks === undefined) {
44949- controlBlocks = postDominatorFrontier(fn, postDominators, id);
44950- postDominatorFrontierCache.set(id, controlBlocks);
44951- }
44952- for (const blockId of controlBlocks) {
44953- const controlBlock = fn.body.blocks.get(blockId);
44954- switch (controlBlock.terminal.kind) {
44955- case 'if':
44956- case 'branch': {
44957- if (reactiveIdentifiers.isReactive(controlBlock.terminal.test)) {
44958- return true;
44959- }
44960- break;
44961- }
44962- case 'switch': {
44963- if (reactiveIdentifiers.isReactive(controlBlock.terminal.test)) {
44964- return true;
44965- }
44966- for (const case_ of controlBlock.terminal.cases) {
44967- if (case_.test !== null &&
44968- reactiveIdentifiers.isReactive(case_.test)) {
44969- return true;
44970- }
44971- }
44972- break;
44973- }
44974- }
44975- }
44976- return false;
44977- }
45021+ const isReactiveControlledBlock = createControlDominators(fn, place => reactiveIdentifiers.isReactive(place));
4497845022 do {
4497945023 for (const [, block] of fn.body.blocks) {
4498045024 let hasReactiveControl = isReactiveControlledBlock(block.id);
@@ -45092,46 +45136,6 @@ function inferReactivePlaces(fn) {
4509245136 }
4509345137 propagateReactivityToInnerFunctions(fn, true);
4509445138}
45095- function postDominatorFrontier(fn, postDominators, targetId) {
45096- const visited = new Set();
45097- const frontier = new Set();
45098- const targetPostDominators = postDominatorsOf(fn, postDominators, targetId);
45099- for (const blockId of [...targetPostDominators, targetId]) {
45100- if (visited.has(blockId)) {
45101- continue;
45102- }
45103- visited.add(blockId);
45104- const block = fn.body.blocks.get(blockId);
45105- for (const pred of block.preds) {
45106- if (!targetPostDominators.has(pred)) {
45107- frontier.add(pred);
45108- }
45109- }
45110- }
45111- return frontier;
45112- }
45113- function postDominatorsOf(fn, postDominators, targetId) {
45114- var _a;
45115- const result = new Set();
45116- const visited = new Set();
45117- const queue = [targetId];
45118- while (queue.length) {
45119- const currentId = queue.shift();
45120- if (visited.has(currentId)) {
45121- continue;
45122- }
45123- visited.add(currentId);
45124- const current = fn.body.blocks.get(currentId);
45125- for (const pred of current.preds) {
45126- const predPostDominator = (_a = postDominators.get(pred)) !== null && _a !== void 0 ? _a : pred;
45127- if (predPostDominator === targetId || result.has(predPostDominator)) {
45128- result.add(pred);
45129- }
45130- queue.push(pred);
45131- }
45132- }
45133- return result;
45134- }
4513545139class ReactivityMap {
4513645140 constructor(aliasedIdentifiers) {
4513745141 this.hasChanges = false;
0 commit comments