private static Operand InsertPhi(DefMap[] globalDefs, BasicBlock block, Operand operand) { // This block has a Phi that has not been materialized yet, but that // would define a new version of the variable we're looking for. We need // to materialize the Phi, add all the block/operand pairs into the Phi, and // then use the definition from that Phi. Operand local = Local(operand.Type); Operation operation = Operation.Factory.PhiOperation(local, block.Predecessors.Count); AddPhi(block, operation); globalDefs[block.Index].TryAddOperand(GetId(operand), local); PhiOperation phi = operation.AsPhi(); for (int index = 0; index < block.Predecessors.Count; index++) { BasicBlock predecessor = block.Predecessors[index]; phi.SetBlock(index, predecessor); phi.SetSource(index, FindDefOnPred(globalDefs, predecessor, operand)); } return(local); }
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(); }