예제 #1
0
        /// <summary>
        /// Removes the basic block with a particular tag from this
        /// control-flow graph.
        /// </summary>
        /// <param name="tag">The basic block's tag.</param>
        /// <returns>
        /// A new control-flow graph that does not contain the basic block.
        /// </returns>
        public FlowGraph RemoveBasicBlock(BasicBlockTag tag)
        {
            AssertContainsBasicBlock(tag);

            var newGraph = new FlowGraph(this, new RemoveBasicBlockUpdate(tag));

            var oldData   = blocks[tag];
            var oldParams = oldData.Parameters;
            var oldInsns  = oldData.InstructionTags;

            var paramTypeBuilder   = newGraph.blockParamTypes.ToBuilder();
            var valueParentBuilder = newGraph.valueParents.ToBuilder();

            int oldParamCount = oldParams.Count;

            for (int i = 0; i < oldParamCount; i++)
            {
                paramTypeBuilder.Remove(oldParams[i].Tag);
                valueParentBuilder.Remove(oldParams[i].Tag);
            }

            valueParentBuilder.RemoveRange(oldInsns);

            newGraph.blockParamTypes = paramTypeBuilder.ToImmutable();
            newGraph.valueParents    = valueParentBuilder.ToImmutable();
            newGraph.instructions    = newGraph.instructions.RemoveRange(oldInsns);
            newGraph.blocks          = newGraph.blocks.Remove(tag);

            return(newGraph);
        }
예제 #2
0
 internal BasicBlock(FlowGraph graph, BasicBlockTag tag, BasicBlockData data)
 {
     this       = default(BasicBlock);
     this.Graph = graph;
     this.Tag   = tag;
     this.data  = data;
 }
예제 #3
0
        internal NamedInstruction InsertInstructionInBasicBlock(
            BasicBlockTag blockTag,
            Instruction instruction,
            ValueTag insnTag,
            int index)
        {
            AssertContainsBasicBlock(blockTag);
            AssertNotContainsValue(insnTag);

            var oldBlockData = blocks[blockTag];
            var newBlockData = new BasicBlockData(
                oldBlockData.Parameters,
                oldBlockData.InstructionTags.Insert(index, insnTag),
                oldBlockData.Flow);

            var newGraph = new FlowGraph(this, new AddInstructionUpdate(insnTag, instruction));

            newGraph.blocks       = newGraph.blocks.SetItem(blockTag, newBlockData);
            newGraph.instructions = newGraph.instructions.Add(insnTag, instruction);
            newGraph.valueParents = newGraph.valueParents.Add(insnTag, blockTag);
            return(new NamedInstruction(
                       new BasicBlock(newGraph, blockTag, newBlockData),
                       insnTag,
                       instruction,
                       index));
        }
예제 #4
0
        /// <summary>
        /// Moves this instruction from its current location to a
        /// the end of a basic block.
        /// </summary>
        /// <param name="block">
        /// The block to move this instruction to.
        /// </param>
        public void MoveTo(BasicBlockTag block)
        {
            var data   = this.Instruction;
            var target = Graph.GetBasicBlock(block);

            Graph.RemoveInstruction(Tag);
            target.AppendInstruction(data, Tag);
        }
예제 #5
0
        /// <summary>
        /// Creates a new control-flow graph that takes the basic block
        /// with a particular tag as entry point.
        /// </summary>
        /// <param name="tag">The tag of the new entry point block.</param>
        /// <returns>A control-flow graph.</returns>
        public FlowGraph WithEntryPoint(BasicBlockTag tag)
        {
            AssertContainsBasicBlock(tag);
            var newGraph = new FlowGraph(this, new SetEntryPointUpdate(tag));

            newGraph.EntryPointTag = tag;
            return(newGraph);
        }
예제 #6
0
        /// <summary>
        /// Moves this instruction from its current location to a
        /// particular position in a block.
        /// </summary>
        /// <param name="index">
        /// The position in <paramref name="block"/> at which to insert
        /// this instruction.
        /// </param>
        /// <param name="block">
        /// The block to move this instruction to.
        /// </param>
        public void MoveTo(int index, BasicBlockTag block)
        {
            var data   = this.Instruction;
            var target = Graph.GetBasicBlock(block);

            Graph.RemoveInstruction(Tag);
            target.InsertInstruction(index, data, Tag);
        }
예제 #7
0
        /// <summary>
        /// Creates a new basic block that includes all basic blocks in this
        /// graph plus an empty basic block. The latter basic block is returned.
        /// </summary>
        /// <param name="name">The (preferred) name of the basic block's tag.</param>
        /// <returns>An empty basic block in a new control-flow graph.</returns>
        public BasicBlock AddBasicBlock(string name)
        {
            var tag  = new BasicBlockTag(name);
            var data = new BasicBlockData();

            var newGraph = new FlowGraph(this, new AddBasicBlockUpdate(tag));

            newGraph.blocks = newGraph.blocks.Add(tag, data);
            return(new BasicBlock(newGraph, tag, data));
        }
예제 #8
0
        internal BasicBlock UpdateBasicBlockParameters(
            BasicBlockTag tag,
            ImmutableList <BlockParameter> parameters)
        {
            AssertContainsBasicBlock(tag);
            var oldBlock = blocks[tag];

            var newData = new BasicBlockData(
                parameters,
                oldBlock.InstructionTags,
                oldBlock.Flow);

            var oldData   = blocks[tag];
            var oldParams = oldData.Parameters;

            var newGraph = new FlowGraph(this, new BasicBlockParametersUpdate(tag));

            var paramTypeBuilder   = newGraph.blockParamTypes.ToBuilder();
            var valueParentBuilder = newGraph.valueParents.ToBuilder();

            // Remove the basic block's parameters from the value parent
            // and parameter type dictionaries.
            int oldParamCount = oldParams.Count;

            for (int i = 0; i < oldParamCount; i++)
            {
                paramTypeBuilder.Remove(oldParams[i].Tag);
                valueParentBuilder.Remove(oldParams[i].Tag);
            }

            // Add the new basic block parameters to the value parent and
            // parameter type dictionaries.
            int newParamCount = parameters.Count;

            for (int i = 0; i < newParamCount; i++)
            {
                var item = parameters[i];

                ContractHelpers.Assert(
                    !valueParentBuilder.ContainsKey(item.Tag),
                    "Value tag '" + item.Tag.Name + "' cannot appear twice in the same control-flow graph.");

                paramTypeBuilder.Add(item.Tag, item.Type);
                valueParentBuilder.Add(item.Tag, tag);
            }

            newGraph.blockParamTypes = paramTypeBuilder.ToImmutable();
            newGraph.valueParents    = valueParentBuilder.ToImmutable();
            newGraph.blocks          = newGraph.blocks.SetItem(tag, newData);

            return(new BasicBlock(newGraph, tag, newData));
        }
예제 #9
0
        internal BasicBlock UpdateBasicBlockFlow(BasicBlockTag tag, BlockFlow flow)
        {
            AssertContainsBasicBlock(tag);
            var oldBlock = blocks[tag];

            var newData = new BasicBlockData(
                oldBlock.Parameters,
                oldBlock.InstructionTags,
                flow);

            var newGraph = new FlowGraph(this, new BasicBlockFlowUpdate(tag));

            newGraph.blocks = newGraph.blocks.SetItem(tag, newData);

            return(new BasicBlock(newGraph, tag, newData));
        }
예제 #10
0
 /// <summary>
 /// Creates a basic block builder from a graph and a tag.
 /// </summary>
 /// <param name="graph">The basic block builder's defining graph.</param>
 /// <param name="tag">The basic block's tag.</param>
 internal BasicBlockBuilder(FlowGraphBuilder graph, BasicBlockTag tag)
 {
     this.Graph = graph;
     this.Tag   = tag;
 }
예제 #11
0
 /// <summary>
 /// Checks if this control-flow graph contains a basic block
 /// with a particular tag.
 /// </summary>
 /// <param name="tag">The basic block's tag.</param>
 /// <returns>
 /// <c>true</c> if this control-flow graph contains a basic block
 /// with the given tag; otherwise, <c>false</c>.
 /// </returns>
 public bool ContainsBasicBlock(BasicBlockTag tag)
 {
     return(ImmutableGraph.ContainsBasicBlock(tag));
 }
예제 #12
0
 /// <summary>
 /// Gets the basic block with a particular tag.
 /// </summary>
 /// <param name="tag">The basic block's tag.</param>
 /// <returns>A basic block.</returns>
 public BasicBlockBuilder GetBasicBlock(BasicBlockTag tag)
 {
     return(new BasicBlockBuilder(this, tag));
 }
예제 #13
0
 /// <summary>
 /// Removes the basic block with a particular tag from this
 /// control-flow graph.
 /// </summary>
 /// <param name="tag">The basic block's tag.</param>
 public void RemoveBasicBlock(BasicBlockTag tag)
 {
     ImmutableGraph = ImmutableGraph.RemoveBasicBlock(tag);
 }
예제 #14
0
 /// <summary>
 /// Replaces this branch's target with another block.
 /// </summary>
 /// <param name="target">The new target block.</param>
 /// <returns>A new branch.</returns>
 public Branch WithTarget(BasicBlockTag target)
 {
     return(new Branch(target, Arguments));
 }
예제 #15
0
 /// <summary>
 /// Creates a branch that targets a particular block and
 /// passes a list of arguments.
 /// </summary>
 /// <param name="target">The target block.</param>
 /// <param name="arguments">
 /// A list of arguments to pass to the target block.
 /// </param>
 public Branch(BasicBlockTag target, IReadOnlyList <BranchArgument> arguments)
 {
     this.Target    = target;
     this.Arguments = arguments;
 }
예제 #16
0
 /// <summary>
 /// Creates a branch that targets a particular block and
 /// passes a list of arguments.
 /// </summary>
 /// <param name="target">The target block.</param>
 /// <param name="arguments">
 /// A list of arguments to pass to the target block.
 /// </param>
 public Branch(BasicBlockTag target, IReadOnlyList <ValueTag> arguments)
     : this(target, arguments.EagerSelect(BranchArgument.FromValue))
 {
 }
예제 #17
0
 /// <summary>
 /// Creates a branch that targets a particular block and
 /// passes no arguments.
 /// </summary>
 /// <param name="target">The target block.</param>
 public Branch(BasicBlockTag target)
     : this(target, EmptyArray <BranchArgument> .Value)
 {
 }
예제 #18
0
 /// <summary>
 /// Gets the basic block with a particular tag.
 /// </summary>
 /// <param name="tag">The basic block's tag.</param>
 /// <returns>A basic block.</returns>
 public BasicBlock GetBasicBlock(BasicBlockTag tag)
 {
     AssertContainsBasicBlock(tag);
     return(new BasicBlock(this, tag, blocks[tag]));
 }
예제 #19
0
 /// <summary>
 /// Checks if this control-flow graph contains a basic block
 /// with a particular tag.
 /// </summary>
 /// <param name="tag">The basic block's tag.</param>
 /// <returns>
 /// <c>true</c> if this control-flow graph contains a basic block
 /// with the given tag; otherwise, <c>false</c>.
 /// </returns>
 public bool ContainsBasicBlock(BasicBlockTag tag)
 {
     return(blocks.ContainsKey(tag));
 }
예제 #20
0
 /// <summary>
 /// Asserts that this control-flow graph must contain a basic block
 /// with a particular tag.
 /// </summary>
 /// <param name="tag">
 /// The tag of the basic block that must be in the graph.
 /// </param>
 /// <param name="message">
 /// The error message for when no basic block in this control-flow graph
 /// has the tag.
 /// </param>
 public void AssertContainsBasicBlock(BasicBlockTag tag, string message)
 {
     ContractHelpers.Assert(ContainsBasicBlock(tag), message);
 }
예제 #21
0
 /// <summary>
 /// Asserts that this control-flow graph must contain a basic block
 /// with a particular tag.
 /// </summary>
 /// <param name="tag">
 /// The tag of the basic block that must be in the graph.
 /// </param>
 public void AssertContainsBasicBlock(BasicBlockTag tag)
 {
     AssertContainsBasicBlock(tag, "The graph does not contain the given basic block.");
 }