/// <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; }
/// <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; }