Example #1
0
        /// <summary>
        /// Retrieves the local stack operand at the specified <paramref name="index"/>.
        /// </summary>
        /// <param name="index">The index of the stack operand to retrieve.</param>
        /// <returns>The operand at the specified index.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">The <paramref name="index"/> is not valid.</exception>
        public Operand GetLocalOperand(int index)
        {
            // HACK: Returning a new instance here breaks object identity. We should reuse operands,
            // which represent the same memory location. If we need to move a variable in an optimization
            // stage to a different memory location, it should actually be a new one so sharing object
            // only saves runtime space/perf.
            Debug.Assert(_localsSig != null, "Method doesn't have _locals.");
            Debug.Assert(index <= _localsSig.Types.Length, "Invalid local index requested.");
            if (_localsSig == null || _localsSig.Types.Length <= index)
            {
                throw new ArgumentOutOfRangeException("index", index, "Invalid parameter index");
            }


            Operand local = null;

            if (_locals.Count > index)
            {
                local = _locals[index];
            }

            if (local == null)
            {
                local          = new LocalVariableOperand(_architecture.StackFrameRegister, String.Format("L_{0}", index), index, _localsSig.Types[index]);
                _locals[index] = local;
            }

            return(local);
        }
        /// <summary>
        /// Retrieves the local stack operand at the specified <paramref name="index"/>.
        /// </summary>
        /// <param name="index">The index of the stack operand to retrieve.</param>
        /// <returns>The operand at the specified index.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">The <paramref name="index"/> is not valid.</exception>
        public Operand GetLocalOperand(int index)
        {
            // HACK: Returning a new instance here breaks object identity. We should reuse operands,
            // which represent the same memory location. If we need to move a variable in an optimization
            // stage to a different memory location, it should actually be a new one so sharing object
            // only saves runtime space/perf.
            // PG: Isn't that implemented below? Comment seems out of date with code

            Debug.Assert(localsSig != null, @"Method doesn't have locals.");
            Debug.Assert(index < localsSig.Locals.Length, @"Invalid local index requested.");

            if (localsSig == null || localsSig.Locals.Length < index)
            {
                throw new ArgumentOutOfRangeException(@"index", index, @"Invalid parameter index");
            }

            Operand local = locals[index];

            if (local == null)
            {
                VariableSignature localVariable = localsSig.Locals[index];

                //ScheduleDependencyForCompilation(localVariable.Type);

                local = new LocalVariableOperand(architecture.StackFrameRegister, String.Format("L_{0}", index), index, localVariable.Type);

                locals[index] = local;
            }

            return(local);
        }
Example #3
0
 /// <summary>
 /// Collects all local variables assignments into a list.
 /// </summary>
 /// <param name="locals">Holds all locals found by the stage.</param>
 /// <param name="block">The block.</param>
 private void CollectLocalVariables(List <StackOperand> locals, BasicBlock block)
 {
     for (Context ctx = new Context(InstructionSet, block); !ctx.EndOfInstruction; ctx.GotoNext())
     {
         // Does this instruction define a new stack variable?
         foreach (Operand op in ctx.Results)
         {
             // The instruction list may not be in SSA form, so we have to check existence again here unfortunately.
             // FIXME: Allow us to detect the state of blocks
             LocalVariableOperand lvop = op as LocalVariableOperand;
             if (lvop != null && !locals.Contains(lvop))
             {
                 locals.Add(lvop);
             }
         }
     }
 }