/// <summary> /// Spills all active operands at the end of a basic block. /// </summary> /// <param name="block">The basic block to spill in.</param> private void SpillActiveOperands(BasicBlock block) { int regIdx = 0; foreach (Operand op in _activeOperands) { if (op != null && op is MemoryOperand) { Context ctx = new Context(InstructionSet, block); ctx.GotoLast(); InsertMove(ctx, op, new RegisterOperand(op.Type, _registerSet[regIdx])); } regIdx++; } Array.Clear(_activeOperands, 0, _activeOperands.Length); }
/// <summary> /// Adds PHI functions for all ref/out parameters of the method being compiled. /// </summary> private void AddPhiFunctionsForOutParameters() { Dictionary <StackOperand, StackOperand> liveIn = null; // Retrieve the well known epilogue block BasicBlock epilogue = FindBlock(Int32.MaxValue); Debug.Assert(epilogue != null, "Method doesn't have epilogue block?"); Context ctxEpilogue = new Context(InstructionSet, epilogue); ctxEpilogue.GotoLast(); // Iterate all parameter definitions foreach (RuntimeParameter rp in MethodCompiler.Method.Parameters) { // Retrieve the stack operand for the parameter StackOperand paramOp = (StackOperand)MethodCompiler.GetParameterOperand(rp.Position - 1); // Only add a PHI if the runtime parameter is out or ref... if (rp.IsOut || (paramOp.Type is RefSigType || paramOp.Type is PtrSigType)) { ctxEpilogue.AppendInstruction(IR.Instruction.PhiInstruction, paramOp); if (liveIn == null) { liveIn = new Dictionary <StackOperand, StackOperand> (); } liveIn.Add(paramOp, paramOp); } } // Save the in versions to force a merge later if (liveIn != null) { _liveness[epilogue.Sequence] = liveIn; } }