private void CollectObjectAssignmentsAndUses()
        {
            foreach (var block in BasicBlocks)
            {
                for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next)
                {
                    if (node.IsEmpty)
                    {
                        continue;
                    }

                    if (node.ResultCount == 0 && node.OperandCount == 0)
                    {
                        continue;
                    }

                    var visitor = new OperandVisitor(node);

                    foreach (var input in visitor.Input)
                    {
                        if (input.Type.IsReferenceType || input.Type.IsManagedPointer)
                        {
                            if (input.IsRegister)
                            {
                                registerRangeData[input.Register.Index].UseList.Add(node.Offset);
                            }
                            else if (input.IsStackLocal)
                            {
                                stackLocalRangeData[stack[input]].UseList.Add(node.Offset);
                            }
                        }
                        else
                        {
                            if (input.IsRegister)
                            {
                                registerRangeData[input.Register.Index].KillList.Add(node.Offset);
                            }
                            else if (input.IsStackLocal)
                            {
                                stackLocalRangeData[stack[input]].KillList.Add(node.Offset);
                            }
                        }
                    }

                    foreach (var output in visitor.Output)
                    {
                        if (output.Type.IsReferenceType || output.Type.IsManagedPointer)
                        {
                            if (output.IsRegister)
                            {
                                registerRangeData[output.Register.Index].GenList.Add(node.Offset);
                            }
                            else if (output.IsStackLocal)
                            {
                                stackLocalRangeData[stack[output]].GenList.Add(node.Offset);
                            }
                        }
                    }
                }
            }
        }
        private void BuildLiveIntervals()
        {
            var intervalTrace = new CompilerTrace(trace, "BuildLiveIntervals");

            for (int b = basicBlocks.Count - 1; b >= 0; b--)
            {
                var block = extendedBlocks[b];

                for (int r = 0; r < registerCount; r++)
                {
                    if (!block.LiveOut.Get(r))
                        continue;

                    var register = virtualRegisters[r];

                    if (b + 1 != basicBlocks.Count && extendedBlocks[b + 1].LiveIn.Get(r))
                    {
                        if (intervalTrace.Active) intervalTrace.Log("Add (LiveOut) " + register.ToString() + " : " + block.Start + " to " + extendedBlocks[b + 1].Start);
                        if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                        register.AddLiveInterval(block.Start, extendedBlocks[b + 1].Start);
                        if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                    }
                    else
                    {
                        if (intervalTrace.Active) intervalTrace.Log("Add (!LiveOut) " + register.ToString() + " : " + block.Interval.Start + " to " + block.Interval.End);
                        if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                        register.AddLiveInterval(block.Interval);
                        if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                    }
                }

                Context context = new Context(instructionSet, block.BasicBlock, block.BasicBlock.EndIndex);

                while (!context.IsBlockStartInstruction)
                {
                    if (!context.IsEmpty)
                    {
                        SlotIndex slotIndex = new SlotIndex(context);

                        OperandVisitor visitor = new OperandVisitor(context);

                        if (context.Instruction.FlowControl == FlowControl.Call)
                        {
                            SlotIndex nextSlotIndex = slotIndex.Next;

                            for (int s = 0; s < physicalRegisterCount; s++)
                            {
                                var register = virtualRegisters[s];
                                if (intervalTrace.Active) intervalTrace.Log("Add (Call) " + register.ToString() + " : " + slotIndex + " to " + nextSlotIndex);
                                if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                                register.AddLiveInterval(slotIndex, nextSlotIndex);
                                if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                            }

                            callSlots.Add(slotIndex);
                        }

                        foreach (var result in visitor.Output)
                        {
                            var register = virtualRegisters[GetIndex(result)];

                            if (register.IsReserved)
                                continue;

                            var first = register.FirstRange;

                            if (!register.IsPhysicalRegister)
                            {
                                register.AddDefPosition(slotIndex);
                            }

                            if (first != null)
                            {
                                if (intervalTrace.Active) intervalTrace.Log("Replace First " + register.ToString() + " : " + slotIndex + " to " + first.End);
                                if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                                register.FirstRange = new LiveInterval(register, slotIndex, first.End);
                                if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                            }
                            else
                            {
                                // This is necesary to handled a result that is never used!
                                // Common with instructions which more than one result
                                if (intervalTrace.Active) intervalTrace.Log("Add (Unused) " + register.ToString() + " : " + slotIndex + " to " + slotIndex.Next);
                                if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                                register.AddLiveInterval(slotIndex, slotIndex.Next);
                                if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                            }
                        }

                        foreach (var result in visitor.Input)
                        {
                            var register = virtualRegisters[GetIndex(result)];

                            if (register.IsReserved)
                                continue;

                            if (!register.IsPhysicalRegister)
                            {
                                register.AddUsePosition(slotIndex);
                            }

                            if (intervalTrace.Active) intervalTrace.Log("Add (normal) " + register.ToString() + " : " + block.Start + " to " + slotIndex.Next);
                            if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                            register.AddLiveInterval(block.Start, slotIndex.Next);
                            if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                        }
                    }

                    context.GotoPrevious();
                }
            }
        }
        private void ComputeLocalLiveSets()
        {
            var liveSetTrace = new CompilerTrace(trace, "ComputeLocalLiveSets");

            foreach (var block in extendedBlocks)
            {
                if (liveSetTrace.Active)
                    liveSetTrace.Log("Block # " + block.BasicBlock.Sequence.ToString());

                BitArray liveGen = new BitArray(registerCount, false);
                BitArray liveKill = new BitArray(registerCount, false);

                liveGen.Set(stackFrameRegister.Index, true);
                liveGen.Set(stackPointerRegister.Index, true);

                if (programCounter != null)
                    liveGen.Set(programCounter.Index, true);

                for (Context context = new Context(instructionSet, block.BasicBlock); !context.IsBlockEndInstruction; context.GotoNext())
                {
                    if (context.IsEmpty)
                        continue;

                    if (liveSetTrace.Active)
                        liveSetTrace.Log(context.ToString());

                    OperandVisitor visitor = new OperandVisitor(context);

                    foreach (var ops in visitor.Input)
                    {
                        if (liveSetTrace.Active)
                            liveSetTrace.Log("INPUT:  " + ops.ToString());

                        int index = GetIndex(ops);
                        if (!liveKill.Get(index))
                        {
                            liveGen.Set(index, true);

                            if (liveSetTrace.Active)
                                liveSetTrace.Log("GEN:  " + index.ToString() + " " + ops.ToString());
                        }
                    }

                    if (context.Instruction.FlowControl == FlowControl.Call)
                    {
                        for (int s = 0; s < physicalRegisterCount; s++)
                        {
                            liveKill.Set(s, true);
                        }

                        if (liveSetTrace.Active)
                            liveSetTrace.Log("KILL ALL PHYSICAL");
                    }

                    foreach (var ops in visitor.Output)
                    {
                        if (liveSetTrace.Active)
                            liveSetTrace.Log("OUTPUT: " + ops.ToString());

                        int index = GetIndex(ops);
                        liveKill.Set(index, true);

                        if (liveSetTrace.Active)
                            liveSetTrace.Log("KILL: " + index.ToString() + " " + ops.ToString());
                    }
                }

                block.LiveGen = liveGen;
                block.LiveKill = liveKill;
                block.LiveKillNot = ((BitArray)liveKill.Clone()).Not();

                if (liveSetTrace.Active)
                {
                    liveSetTrace.Log("GEN:     " + ToString(block.LiveGen));
                    liveSetTrace.Log("KILL:    " + ToString(block.LiveKill));
                    liveSetTrace.Log("KILLNOT: " + ToString(block.LiveKillNot));
                    liveSetTrace.Log(string.Empty);
                }
            }
        }
        private void CollectObjectAssignmentsAndUses()
        {
            foreach (var block in BasicBlocks)
            {
                for (var node = block.First.Next; !node.IsBlockEndInstruction; node = node.Next)
                {
                    if (node.IsEmpty)
                        continue;

                    if (node.ResultCount == 0 && node.OperandCount == 0)
                        continue;

                    var visitor = new OperandVisitor(node);

                    foreach (var input in visitor.Input)
                    {
                        if (input.Type.IsReferenceType || input.Type.IsManagedPointer)
                        {
                            if (input.IsCPURegister)
                                registerRangeData[input.Register.Index].UseList.Add(node.Offset);
                            else if (input.IsStackLocal)
                                stackLocalRangeData[stack[input]].UseList.Add(node.Offset);
                        }
                        else
                        {
                            if (input.IsCPURegister)
                                registerRangeData[input.Register.Index].KillList.Add(node.Offset);
                            else if (input.IsStackLocal)
                                stackLocalRangeData[stack[input]].KillList.Add(node.Offset);
                        }
                    }

                    foreach (var output in visitor.Output)
                    {
                        if (output.Type.IsReferenceType || output.Type.IsManagedPointer)
                        {
                            if (output.IsCPURegister)
                                registerRangeData[output.Register.Index].GenList.Add(node.Offset);
                            else if (output.IsStackLocal)
                                stackLocalRangeData[stack[output]].GenList.Add(node.Offset);
                        }
                    }
                }
            }
        }