public static void Deconstruct(ControlFlowGraph cfg) { for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) { Operation operation = block.Operations.First; while (operation != default && operation.Instruction == Instruction.Phi) { Operation nextNode = operation.ListNext; Operand local = Local(operation.Destination.Type); PhiOperation phi = operation.AsPhi(); for (int index = 0; index < phi.SourcesCount; index++) { BasicBlock predecessor = phi.GetBlock(cfg, index); Operand source = phi.GetSource(index); predecessor.Append(Operation(Instruction.Copy, local, source)); phi.SetSource(index, default); } Operation copyOp = Operation(Instruction.Copy, operation.Destination, local); block.Operations.AddBefore(operation, copyOp); operation.Destination = default; block.Operations.Remove(operation); operation = nextNode; } } }
private void DumpNode(ControlFlowGraph cfg, Operation node) { for (int index = 0; index < node.DestinationsCount; index++) { DumpOperand(node.GetDestination(index)); if (index == node.DestinationsCount - 1) { _builder.Append(" = "); } else { _builder.Append(", "); } } switch (node) { case Operation operation: if (operation.Instruction == Instruction.Phi) { PhiOperation phi = operation.AsPhi(); _builder.Append("Phi "); for (int index = 0; index < phi.SourcesCount; index++) { _builder.Append('('); DumpBlockName(phi.GetBlock(cfg, index)); _builder.Append(": "); DumpOperand(phi.GetSource(index)); _builder.Append(')'); if (index < phi.SourcesCount - 1) { _builder.Append(", "); } } break; } bool comparison = false; _builder.Append(operation.Instruction); if (operation.Instruction == Instruction.Extended) { _builder.Append('.').Append(operation.Intrinsic); } else if (operation.Instruction == Instruction.BranchIf || operation.Instruction == Instruction.Compare) { comparison = true; } _builder.Append(' '); for (int index = 0; index < operation.SourcesCount; index++) { Operand source = operation.GetSource(index); if (index < operation.SourcesCount - 1) { DumpOperand(source); _builder.Append(", "); } else if (comparison) { _builder.Append((Comparison)source.AsInt32()); } else { DumpOperand(source); } } break; } if (_symbolNames.Count == 1) { _builder.Append(" ;; ").Append(_symbolNames.First().Value); } else if (_symbolNames.Count > 1) { _builder.Append(" ;;"); foreach ((ulong value, string name) in _symbolNames) { _builder.Append(" 0x").Append(value.ToString("X")).Append(" = ").Append(name); } } // Reset the set of symbols for the next Node we're going to dump. _symbolNames.Clear(); }