public BasicBlock(ControlFlowGraph cfg, int nBlock, int at_instruction, EHInfo copy_ehState_from) { ControlFlowGraph = cfg; InputBlockNum = nBlock; FromInstruction = at_instruction; ToInstruction = at_instruction; Instructions = new List<FlatStatement>(); if (at_instruction>=0) Instructions.Add(ControlFlowGraph.InputInstructions[at_instruction]); if (copy_ehState_from != null) { EHInfo = new LS2IL.EHInfo(copy_ehState_from); } ResetRegisterScan(); }
/// <summary> /// /// </summary> /// <param name="cfg">Control Flow Graph with </param> /// <returns>total number of registers in the updated graph</returns> public static int Pack(ControlFlowGraph cfg) { // make sure the register scan is current. cfg.ScanRegisters(); DefaultRegisterPacker packer = new DefaultRegisterPacker(cfg); return packer.PackRegisters(); }
public DefaultRegisterPacker(ControlFlowGraph cfg) { CFG = cfg; }
public void FlattenToInstructions(LS2ILGeneratorOptions options) { List<FlatStatement> list = Flatten(); ControlFlowGraph cfg = new ControlFlowGraph(this, list); cfg.Build(options.FilterUnusedInstructions); if (options.CondenseRegisters) { PackedRegisters = RegisterPackers.Pack(cfg); } else { PackedRegisters = this.Registers.Count; } if (PackedRegisters > 256) { throw new NotSupportedException("Too many registers used in function " + this.IMethodSymbol.GetFullyQualifiedName()); } list = cfg.Flatten(); if (options.ElevateLongValues) { foreach (FlatStatement fs in list) { if (fs.Operands == null) continue; string emitted = fs.Emit(); if (emitted.Length < 192) continue; // let's shorten this baby up. for (int i = 0; i < fs.Operands.Count; i++) { FlatOperand fo = fs.Operands[i]; if (fo.OperandType != FlatOperandType.OPND_IMMEDIATE) continue; if (fo.ImmediateValue.ToString().Length > 63) { int nValue = FunctionValues.Count; FunctionValues.Add(fo.ImmediateValue); fs.Operands[i] = FlatOperand.FunctionValueRef(nValue, fo.ImmediateValue); } } } } if (options.FlattenLabels) { FlattenLabels(list); foreach (FlatValue fv in FunctionValues) { if (fv.ValueType == FlatValueType.VT_Label) { // get label target int labelValue; if (!EmittedLabels.TryGetValue(fv.ValueText, out labelValue)) { throw new LS2ILLabelException("Unresolved label " + fv.ValueText); } fv.ValueType = FlatValueType.VT_Int32; fv.ValueText = labelValue.ToString(); fv.Object = labelValue; } else if (fv.Object is FlatArrayBuilder) { FlatArrayBuilder fab = (FlatArrayBuilder)fv.Object; fab.FlattenLabels(this); } else if (fv.Object is FlatTableBuilder) { FlatTableBuilder fab = (FlatTableBuilder)fv.Object; fab.FlattenLabels(this); } } } if (options.FlattenLabels) { foreach (FlatStatement fs in list) { if (fs.Instruction != Instruction.meta_LABEL) EmitInstruction(fs.Emit()); } } else { foreach (FlatStatement fs in list) { EmitInstruction(fs.Emit()); } } }