Пример #1
0
        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);
        }
Пример #2
0
        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;
                }
            }
        }
Пример #3
0
        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();
        }