/// <summary>
        /// Spills the register.
        /// </summary>
        /// <param name="active">The active.</param>
        /// <param name="current">The current.</param>
        /// <returns></returns>
        private Register SpillRegister(List <LiveRange> active, LiveRange current)
        {
            foreach (LiveRange lr in active)
            {
                // Does it make sense to spill this register?
                if (lr.Reg.IsValidSigType(current.Op.Type))
                {
                    // Yes, spill it back to its operand
                    RegisterOperand rop = new RegisterOperand(lr.Op.Type, lr.Reg);

                    //					MoveInstruction mi = CreateMoveInstruction(lr.Op, rop);		// FIXME PG - hack to allow compile
                    //					current.Block.Instructions.Insert(current.Start++, mi);		// FIXME PG - hack to allow compile

                    // Load the new value
                    //					mi = CreateMoveInstruction(rop, current.Op);				// FIXME PG - hack to allow compile
                    //					current.Block.Instructions.Insert(current.Start++, mi);		// FIXME PG - hack to allow compile

                    // Remove this live range from the active list
                    active.Remove(lr);

                    lr.Start = PickNextUse(lr.Op, current.Start, lr.End);
                    if (lr.Start != -1)
                    {
                        ReinsertSpilledRange(lr);
                    }

                    return(lr.Reg);
                }
            }

            throw new InvalidOperationException(@"Failed to spill a register.");
        }
        /// <summary>
        /// Assigns the registers.
        /// </summary>
        private void AssignRegisters()
        {
            List <LiveRange> active = new List <LiveRange>();

            _registers = FillRegisterList();

            for (int i = 0; i < _liveRanges.Count; i++)
            {
                LiveRange lr = _liveRanges[i];
                ExpireOldRanges(lr.Start, active);

                Register reg = AllocateRegister(lr.Op);
                if (reg == null)
                {
                    reg = SpillRegister(active, lr);
                }

                Debug.Assert(reg != null, @"Failed to allocate a register type.");
                RegisterOperand rop = new RegisterOperand(lr.Op.Type, reg);
                ReplaceOperand(lr, rop);;
                lr.Reg = reg;

                int insIdx = active.FindIndex(delegate(LiveRange match)
                {
                    return((lr.End - match.End) > 0);
                });

                active.Insert(insIdx + 1, lr);
            }
        }
        /// <summary>
        /// Replaces the operand.
        /// </summary>
        /// <param name="lr">The lr.</param>
        /// <param name="replacement">The replacement.</param>
        private void ReplaceOperand(LiveRange lr, RegisterOperand replacement)
        {
            int opIdx;

            // Iterate all definition sites first
            foreach (int index in lr.Op.Definitions.ToArray())
            {
                Context def = new Context(InstructionSet, index);
                if (def.Offset == lr.Start)
                {
                    opIdx = 0;
                    foreach (Operand r in def.Results)
                    {
                        // Is this the operand?
                        if (object.ReferenceEquals(r, lr.Op))
                        {
                            def.SetResult(opIdx, replacement);
                        }

                        opIdx++;
                    }

                    break;
                }
            }

            // Iterate all use sites
            foreach (int index in lr.Op.Uses.ToArray())
            {
                Context instr = new Context(InstructionSet, index);

                if (instr.Offset <= lr.Start)
                {
                    // A use on instr.Offset == lr.Start is one from a previous definition!!
                }
                else if (instr.Offset <= lr.End)
                {
                    opIdx = 0;
                    foreach (Operand r in instr.Operands)
                    {
                        // Is this the operand?
                        if (object.ReferenceEquals(r, lr.Op))
                        {
                            instr.SetOperand(opIdx, replacement);
                        }

                        opIdx++;
                    }
                }
                else
                {
                    break;
                }
            }
        }
        /// <summary>
        /// Reinserts the spilled range.
        /// </summary>
        /// <param name="lr">The lr.</param>
        private void ReinsertSpilledRange(LiveRange lr)
        {
            int index = 0;

            foreach (LiveRange item in _liveRanges)
            {
                if (item.Start > lr.Start)
                {
                    _liveRanges.Insert(index, lr);
                    break;
                }

                index++;
            }
        }
        /// <summary>
        /// Expires the old ranges.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="active">The active.</param>
        private void ExpireOldRanges(int position, List <LiveRange> active)
        {
            for (int i = 0; i < active.Count; i++)
            {
                LiveRange lr = active[i];
                if (lr.End > position)
                {
                    break;
                }

                _registers.Add(lr.Reg);
                active.RemoveAt(i);
                i--;
            }
        }
Exemplo n.º 6
0
        public void LiveRangeTest()
        {
            var basicBlocks = CreateBasicBlockInstructionSet();

            GreedyRegisterAllocator.NumberInstructions(basicBlocks);

            var liveRange = new LiveRange(
                new SlotIndex(basicBlocks[0].First),
                new SlotIndex(basicBlocks[0].Last),
                new List <SlotIndex>(),
                new List <SlotIndex>()
                );

            Assert.True(liveRange.IsEmpty);

            //liveRange.SplitAt(basicBlocks.)
        }
Exemplo n.º 7
0
        /// <summary>
        /// Spills the register.
        /// </summary>
        /// <param name="active">The active.</param>
        /// <param name="current">The current.</param>
        /// <returns></returns>
        private Register SpillRegister(List<LiveRange> active, LiveRange current)
        {
            foreach (LiveRange lr in active)
            {
                // Does it make sense to spill this register?
                if (lr.Reg.IsValidSigType(current.Op.Type))
                {
                    // Yes, spill it back to its operand
                    RegisterOperand rop = new RegisterOperand(lr.Op.Type, lr.Reg);

                    //					MoveInstruction mi = CreateMoveInstruction(lr.Op, rop);		// FIXME PG - hack to allow compile
                    //					current.Block.Instructions.Insert(current.Start++, mi);		// FIXME PG - hack to allow compile

                    // Load the new value
                    //					mi = CreateMoveInstruction(rop, current.Op);				// FIXME PG - hack to allow compile
                    //					current.Block.Instructions.Insert(current.Start++, mi);		// FIXME PG - hack to allow compile

                    // Remove this live range from the active list
                    active.Remove(lr);

                    lr.Start = PickNextUse(lr.Op, current.Start, lr.End);
                    if (lr.Start != -1)
                        ReinsertSpilledRange(lr);

                    return lr.Reg;
                }
            }

            throw new InvalidOperationException(@"Failed to spill a register.");
        }
Exemplo n.º 8
0
        /// <summary>
        /// Replaces the operand.
        /// </summary>
        /// <param name="lr">The lr.</param>
        /// <param name="replacement">The replacement.</param>
        private void ReplaceOperand(LiveRange lr, RegisterOperand replacement)
        {
            int opIdx;

            // Iterate all definition sites first
            foreach (int index in lr.Op.Definitions.ToArray())
            {
                Context def = new Context(instructionSet, index);
                if (def.Offset == lr.Start)
                {
                    opIdx = 0;
                    foreach (Operand r in def.Results)
                    {
                        // Is this the operand?
                        if (object.ReferenceEquals(r, lr.Op))
                            def.SetResult(opIdx, replacement);

                        opIdx++;
                    }

                    break;
                }
            }

            // Iterate all use sites
            foreach (int index in lr.Op.Uses.ToArray())
            {
                Context instr = new Context(instructionSet, index);

                if (instr.Offset <= lr.Start)
                {
                    // A use on instr.Offset == lr.Start is one from a previous definition!!
                }
                else if (instr.Offset <= lr.End)
                {
                    opIdx = 0;
                    foreach (Operand r in instr.Operands)
                    {
                        // Is this the operand?
                        if (object.ReferenceEquals(r, lr.Op))
                            instr.SetOperand(opIdx, replacement);

                        opIdx++;
                    }
                }
                else
                {
                    break;
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Reinserts the spilled range.
        /// </summary>
        /// <param name="lr">The lr.</param>
        private void ReinsertSpilledRange(LiveRange lr)
        {
            int index = 0;
            foreach (LiveRange item in _liveRanges)
            {
                if (item.Start > lr.Start)
                {
                    _liveRanges.Insert(index, lr);
                    break;
                }

                index++;
            }
        }
Exemplo n.º 10
0
 public void AddRange(LiveRange liveRange)
 {
     liveRanges.Add(liveRange);
 }