internal BasicBlock(FlowGraph graph, BasicBlockTag tag, BasicBlockData data) { this = default(BasicBlock); this.Graph = graph; this.Tag = tag; this.data = data; }
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)); }
/// <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)); }
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)); }
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)); }
/// <summary> /// Removes a particular instruction from this control-flow graph. /// Returns a new control-flow graph that does not contain the /// instruction. /// </summary> /// <param name="instructionTag">The tag of the instruction to remove.</param> /// <returns> /// A control-flow graph that no longer contains the instruction. /// </returns> public FlowGraph RemoveInstruction(ValueTag instructionTag) { AssertContainsInstruction(instructionTag); var parentTag = valueParents[instructionTag]; var oldBlockData = blocks[parentTag]; var newBlockData = new BasicBlockData( oldBlockData.Parameters, oldBlockData.InstructionTags.Remove(instructionTag), oldBlockData.Flow); var newGraph = new FlowGraph(this, new RemoveInstructionUpdate(instructionTag)); newGraph.blocks = newGraph.blocks.SetItem(parentTag, newBlockData); newGraph.instructions = newGraph.instructions.Remove(instructionTag); newGraph.valueParents = newGraph.valueParents.Remove(instructionTag); return(newGraph); }