/// <summary>
        /// Allocates a free register From the given register set.
        /// </summary>
        /// <param name="regs">The regs.</param>
        /// <param name="op">The res.</param>
        /// <returns>The allocated RegisterOperand or null, if no register is free.</returns>
        private RegisterOperand AllocateRegister(Register[] regs, Operand op)
        {
            foreach (Register reg in regs) {
                // Is the register in use?
                if (_activeOperands[reg.Index] == null) {
                    // No, use it...
                    _activeOperands[reg.Index] = op;
                    return new RegisterOperand(op.Type, reg);
                }
            }

            return null;
        }
Beispiel #2
0
 /// <summary>
 /// Initializes an instance of <see cref="LocalVariableOperand"/>.
 /// </summary>
 /// <param name="register">Holds the stack frame register.</param>
 /// <param name="name">The name of the variable.</param>
 /// <param name="index">Holds the variable index.</param>
 /// <param name="type">The type of the variable.</param>
 // HACK: Redo this with Architecture support!
 public LocalVariableOperand(Register register, string name, int index, SigType type)
     : base(type, register, -index)
 {
     _name = name;
 }
        /// <summary>
        /// Spills a register from the given register set.
        /// </summary>
        /// <param name="ctx">The context.</param>
        /// <param name="type">The signature type of the resulting operand.</param>
        /// <param name="regs">The instruction compatible subset of the register set.</param>
        /// <returns>A register From the given set.</returns>
        private RegisterOperand SpillRegister(Context ctx, SigType type, Register[] regs)
        {
            // FIXME: Find the oldest reg from the set. Always use the oldest one.

            KeyValuePair<Register, Context>[] lastUses = new KeyValuePair<Register, Context>[regs.Length];

            int i = 0;
            foreach (Register reg in regs)
                lastUses[i++] = new KeyValuePair<Register, Context>(reg, _activeOpLastUse[reg.Index]);

            // Sort the last uses from oldest -> newest
            Array.Sort<KeyValuePair<Register, Context>>(lastUses, delegate(KeyValuePair<Register, Context> a, KeyValuePair<Register, Context> b)
            {
                return b.Value.Offset - a.Value.Offset;
            });

            // Spill the oldest entry (first index)
            KeyValuePair<Register, Context> lastUse = lastUses[0];
            Operand dest = _activeOperands[lastUse.Key.Index];
            RegisterOperand src = new RegisterOperand(dest.Type, lastUse.Key);
            SpillRegister(lastUse.Value, dest, src);

            return new RegisterOperand(type, lastUse.Key);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="LiveRange"/> class.
 /// </summary>
 /// <param name="block">The block.</param>
 /// <param name="op">The op.</param>
 /// <param name="start">The start.</param>
 /// <param name="end">The end.</param>
 public LiveRange(BasicBlock block, Operand op, int start, int end)
 {
     this.Block = block;
     this.Op = op;
     this.Reg = null;
     this.Start = start;
     this.End = end;
 }