public static CFGNode[] ConstructCFG(List <IInstruction> instructions) { CFGNode[] nodes = new CFGNode[instructions.Count]; int end = instructions.Count - 1; for (int i = end; i >= 0; i--) { nodes[i] = new CFGNode(instructions[i], i == end ? null : nodes[i + 1]); } // Map Labels to instructions Dictionary <LabelInstruction, CFGNode> labels = new Dictionary <LabelInstruction, CFGNode>(); List <LabelInstruction> activeLabels = new List <LabelInstruction>(); for (int i = 0; i < instructions.Count; i++) { if (instructions[i] is LabelInstruction label) { activeLabels.Add(label); } else if (activeLabels.Count > 0) { foreach (var activeLabel in activeLabels) { labels[activeLabel] = nodes[i]; } activeLabels.Clear(); } } foreach (var node in nodes) { LabelInstruction?target = node.Instruction switch { ConditionalJump conditionalJump => conditionalJump.Target, UnconditionalJump unconditionalJump => unconditionalJump.Target, _ => null, }; if (target != null && labels.TryGetValue(target.Value, out var successor)) { node.Successors.Add(successor); } } return(nodes); }
private IEnumerable <NasmInstruction> CompileInstruction(int i, IInstruction instruction) { yield return(NasmInstruction.Comment(instruction.ToString())); yield return(NasmInstruction.Comment("In = { " + string.Join(", ", RegisterAllocation.GetAllInAt(i)) + " }")); foreach (var inst in instruction switch { UnaryComputationAssignment inst => CompileCore(inst), BinaryComputationAssignment inst => CompileCore(inst), ConditionalJump inst => CompileCore(inst), UnconditionalJump inst => CompileCore(inst), LabelInstruction inst => CompileCore(inst), CallInstruction inst => CompileCore(i, inst), ReturnInstruction inst => CompileCore(inst), ParameterQueryAssignment inst => CompileCore(inst), _ => throw new ArgumentException(nameof(instruction)) })