From 19b08e67add524fa0c8c5e19b3b8da22f2528c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xuan=20Huang=20=28=E9=BB=84=E7=8E=84=29?= Date: Wed, 5 Oct 2022 18:42:10 -0400 Subject: [PATCH] [Bailout] When Inputs Detected In DepGraph Cycle Inputs occured in depGraph cycle is dangenrous and should be treated as an invariant since Forget _may_ generate broken code in this case, despite that technically this is a stricter then what we needed for the particular case of #633 and #634 and there could be case that this is safe (like many `cfg-` tests that I have to mark as `bailout.`) I expect the next diff will fix them though. commit-id:0b13ed02 --- compiler/forget/src/Diagnostic.ts | 8 ++++++++ .../forget/src/MiddleEnd/DepGraphAnalysis.ts | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/compiler/forget/src/Diagnostic.ts b/compiler/forget/src/Diagnostic.ts index b7659289e6..8362e3c6f2 100644 --- a/compiler/forget/src/Diagnostic.ts +++ b/compiler/forget/src/Diagnostic.ts @@ -126,6 +126,7 @@ export type ErrorCode = | ParseCode<"E0018"> | ParseCode<"E0019"> | ParseCode<"E0020"> + | ParseCode<"E0021"> ; // prettier-ignore @@ -168,6 +169,7 @@ export type DiagnosticOpts = | { code: "E0018"; path: NodePath; context: null } | { code: "E0019"; path: NodePath; context: null } | { code: "E0020"; path: NodePath; context: null } + | { code: "E0021"; path: NodePath; context: { name: Name } } ; function getDiagnosticMessage(opts: DiagnosticOpts): DiagnosticMessage { @@ -320,6 +322,12 @@ ${getSource(opts.path)} body: "Forget does not support the use of the arguments object.", suggestion: null, }; + case "E0021": + return { + level: DiagnosticLevel.Error, + body: `Input "${opts.context.name}" is detected in a DepGraph cycle. This is dangenrous since Forget may (though not always) generate broken code like accessing "c_input" before it is defined.`, + suggestion: null, + }; default: assertExhaustive(opts, `Unhandled error code ${opts}`); } diff --git a/compiler/forget/src/MiddleEnd/DepGraphAnalysis.ts b/compiler/forget/src/MiddleEnd/DepGraphAnalysis.ts index 992f01d675..08d406782b 100644 --- a/compiler/forget/src/MiddleEnd/DepGraphAnalysis.ts +++ b/compiler/forget/src/MiddleEnd/DepGraphAnalysis.ts @@ -47,6 +47,7 @@ function run( } const sccGraph = valGraph.condense(); + checkSCCGraph(sccGraph, context); if (outputKinds.includes(OutputKind.SCCGraph)) { context.outputs[OutputKind.SCCGraph].push(sccGraph.snapshot()); @@ -184,6 +185,24 @@ function checkValGraph(valGraph: DepGraph.ValGraph) { } } +function checkSCCGraph(sccGraph: DepGraph.SCCGraph, context: CompilerContext) { + for (const scc of sccGraph.vertices) { + if (scc.isInput()) continue; + + for (const valVertex of scc.members) { + if (IR.isInputVal(valVertex.val)) { + context.bailout("InputInDepGraphCycle", { + code: "E0021", + path: valVertex.val.ast.path, + context: { + name: valVertex.val.binding.identifier.name, + }, + }); + } + } + } +} + export function computeCfgControlDeps( irFunc: IR.Func, cfg: CFG