protected internal override void VisitLdLoc(LdLoc inst) { if (inst.Variable == thisVariable) { inst.ReplaceWith(target.Clone()); return; } base.VisitLdLoc(inst); }
static void DoPropagate(ILVariable v, ILInstruction copiedExpr, Block block, ref int i, ILTransformContext context) { context.Step($"Copy propagate {v.Name}", copiedExpr); // un-inline the arguments of the ldArg instruction ILVariable[] uninlinedArgs = new ILVariable[copiedExpr.Children.Count]; for (int j = 0; j < uninlinedArgs.Length; j++) { var arg = copiedExpr.Children[j]; var type = context.TypeSystem.Compilation.FindType(arg.ResultType.ToKnownTypeCode()); uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType, arg.ILRange.Start) { Name = "C_" + arg.ILRange.Start }; block.Instructions.Insert(i++, new StLoc(uninlinedArgs[j], arg)); } CollectionExtensions.AddRange(v.Function.Variables, uninlinedArgs); // perform copy propagation: foreach (var expr in v.LoadInstructions.ToArray()) { var clone = copiedExpr.Clone(); for (int j = 0; j < uninlinedArgs.Length; j++) { clone.Children[j].ReplaceWith(new LdLoc(uninlinedArgs[j])); } expr.ReplaceWith(clone); } block.Instructions.RemoveAt(i); int c = ILInlining.InlineInto(block, i, aggressive: false, context: context); i -= c + 1; }
public ILInstruction Instr() { if (Instruction is null) { return(null); } if (InstructionWasGivenOut) { return(Instruction.Clone()); } else { InstructionWasGivenOut = true; return(Instruction); } }