/// <summary> /// Emits selected control-flow instructions. /// </summary> /// <param name="flow">The instructions to emit.</param> public void Emit(SelectedFlowInstructions <TInstruction> flow) { // Selecting flow instructions is kind of tricky. We can readily // use the stack for the first logical instruction, but we can't // use it after that. foreach (var chunk in flow.Chunks) { // Prepare arguments. LoadDependencies(chunk.Dependencies); // Clear the resurrection list. resurrectionList.Clear(); // Append the instruction itself. instructionBlobs.AddLast(chunk.Instructions); } }
/// <summary> /// Creates a linear sequence of instructions for a basic block based on /// selected instructions for named instructions and block flow. /// </summary> /// <param name="block"> /// The basic blocks to place. /// </param> /// <param name="instructions"> /// A mapping of named instructions to their selected instructions. Named /// instructions that do not appear in this mapping should not be selected. /// </param> /// <param name="flow"> /// Selected instructions for <paramref name="block"/>'s control flow. /// </param> /// <returns> /// A linear sequence of instructions. /// </returns> protected virtual IReadOnlyList <TInstruction> ToInstructionStream( BasicBlock block, IReadOnlyDictionary <ValueTag, SelectedInstructions <TInstruction> > instructions, SelectedFlowInstructions <TInstruction> flow) { var instructionStream = new List <TInstruction>(); foreach (var insnTag in block.InstructionTags) { SelectedInstructions <TInstruction> selection; if (instructions.TryGetValue(insnTag, out selection)) { instructionStream.AddRange(selection.Instructions); } } foreach (var chunk in flow.Chunks) { instructionStream.AddRange(chunk.Instructions); } return(instructionStream); }
/// <inheritdoc/> protected override IReadOnlyList <TInstruction> ToInstructionStream( BasicBlock block, IReadOnlyDictionary <ValueTag, SelectedInstructions <TInstruction> > instructions, SelectedFlowInstructions <TInstruction> flow) { var builder = new StackBlockBuilder(this, block, instructions); // Move basic block arguments into their virtual registers. builder.EmitBlockPrologue(GetStackContentsOnEntry(block)); foreach (var insn in block.NamedInstructions) { SelectedInstructions <TInstruction> selection; if (instructions.TryGetValue(insn, out selection)) { // Place the instruction. builder.Emit(insn, selection); } } builder.Emit(flow); return(builder.ToInstructions()); }