示例#1
0
 public void Remove(InstructionInBlock ins)
 {
     Reads.RemoveAll(i => i == ins);
     Writes.RemoveAll(i => i == ins);
     MovesFromOtherRegisters.RemoveAll(i => i == ins);
     CheckCastsAndNewInstance.RemoveAll(i => i == ins);
 }
示例#2
0
 public void Remove(InstructionInBlock ins)
 {
     Reads.RemoveAll(i => i == ins);
     Writes.RemoveAll(i => i == ins);
     MovesFromOtherRegisters.RemoveAll(i => i == ins);
     CheckCastsAndNewInstance.RemoveAll(i => i == ins);
 }
示例#3
0
            public void Add(InstructionInBlock ins, int registerIndex)
            {
                var isDest   = ins.IsDestinationRegister(registerIndex);
                var isSource = ins.IsSourceRegister(registerIndex);

                if (isDest)
                {
                    AddWrite(ins);
                }
                if (isSource)
                {
                    Reads.Add(ins);
                }
                ;

                if (ins.Instruction.Code == RCode.Check_cast || ins.Instruction.Code == RCode.New_instance)
                {
                    CheckCastsAndNewInstance.Add(ins);
                }

                if (!isDest && !isSource)
                {
                    Debug.Assert(false);
                }
            }
示例#4
0
        private static void CollectBasicUsages(IList <BasicBlock> blocks, Dictionary <Register, RegisterUsage> usages)
        {
            foreach (var block in blocks)
            {
                foreach (var ins in block.Instructions)
                {
                    var instructionInBlock = new InstructionInBlock(ins, block);

                    for (int i = 0; i < ins.Registers.Count; ++i)
                    {
                        var reg = ins.Registers[i];

                        RegisterUsage u;
                        if (!usages.TryGetValue(reg, out u))
                        {
                            u = new RegisterUsage(reg);
                            usages.Add(reg, u);
                        }

                        u.Blocks.Add(block);
                        u.Add(instructionInBlock, i);
                    }
                }
            }
        }
示例#5
0
        /// <summary>
        /// This method tests if 'target' can be reached from 'source' without passing through 'blocker'
        /// </summary>
        internal bool IsReachable(InstructionInBlock target, InstructionInBlock source, InstructionInBlock blocker)
        {
            if (target == blocker)
            {
                return(false);
            }
            if (target == source)
            {
                throw new ArgumentException("source and target must be different"); // or think about a proper meaning.
            }
            HashSet <BasicBlock> sourceReachables = null;

            // Check all three instructions inthe same block.
            if (source.Block == target.Block && source.Block == blocker.Block)
            {
                if (target.Instruction.Index >= source.Instruction.Index)
                {
                    return(source.Instruction.Index > blocker.Instruction.Index ||
                           blocker.Instruction.Index > target.Instruction.Index);
                }
                else
                {
                    if (blocker.Instruction.Index <= target.Instruction.Index ||
                        blocker.Instruction.Index > source.Instruction.Index)
                    {
                        return(false);
                    }

                    sourceReachables = GetReachableBlocks(source.Block);
                    return(sourceReachables.Contains(source.Block));
                }
            }
            // check source in same block as either target or blocker.
            if (source.Block == target.Block && source.Instruction.Index < target.Instruction.Index)
            {
                return(true);
            }
            if (source.Block == blocker.Block && source.Instruction.Index < blocker.Instruction.Index)
            {
                return(false);
            }

            sourceReachables = GetReachableBlocks(source.Block);
            // the easy checks...
            if (!sourceReachables.Contains(target.Block))
            {
                return(false);
            }
            if (!sourceReachables.Contains(blocker.Block))
            {
                return(true);
            }
            // slightly more complicated: both target and blocker are reachable from source.
            if (target.Block == blocker.Block)
            {
                return(target.Instruction.Index < blocker.Instruction.Index);
            }
            // work on a per-block basis.
            return(IsReachable(target.Block, source.Block, blocker.Block, new HashSet <BasicBlock>()));
        }
示例#6
0
 private void AddWrite(InstructionInBlock ins)
 {
     Writes.Add(ins);
     if (ins.Instruction.Code.IsMove())
     {
         MovesFromOtherRegisters.Add(ins);
     }
 }
示例#7
0
 public void ConvertToNop(InstructionInBlock ins)
 {
     // update registers usages.
     foreach (var r in ins.Instruction.Registers)
     {
         _usages[r].Remove(ins);
     }
     ins.Instruction.ConvertToNop();
 }
示例#8
0
            public void Add(InstructionInBlock ins, int registerIndex)
            {
                var isDest = ins.IsDestinationRegister(registerIndex);
                var isSource = ins.IsSourceRegister(registerIndex);

                if (isDest)   AddWrite(ins);
                if (isSource) Reads.Add(ins); ;

                if(ins.Instruction.Code == RCode.Check_cast || ins.Instruction.Code == RCode.New_instance)
                    CheckCastsAndNewInstance.Add(ins);
                
                if(!isDest && !isSource)
                    Debug.Assert(false);
            }
示例#9
0
 private void AddWrite(InstructionInBlock ins)
 {
     Writes.Add(ins);
     if (ins.Instruction.Code.IsMove())
         MovesFromOtherRegisters.Add(ins);
 }
示例#10
0
 public void ConvertToNop(InstructionInBlock ins)
 {
     // update registers usages.
     foreach (var r in ins.Instruction.Registers)
     {
         _usages[r].Remove(ins);
     }
     ins.Instruction.ConvertToNop();
 }
示例#11
0
        private static void CollectBasicUsages(IList<BasicBlock> blocks, Dictionary<Register, RegisterUsage> usages)
        {
            foreach (var block in blocks)
            {
                foreach (var ins in block.Instructions)
                {
                    var instructionInBlock = new InstructionInBlock(ins, block);

                    for (int i = 0; i < ins.Registers.Count; ++i)
                    {
                        var reg = ins.Registers[i];

                        RegisterUsage u;
                        if (!usages.TryGetValue(reg, out u))
                        {
                            u = new RegisterUsage(reg);
                            usages.Add(reg, u);
                        }

                        u.Blocks.Add(block);
                        u.Add(instructionInBlock, i);
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        /// This method tests if 'target' can be reached from 'source' without passing through 'blocker'
        /// </summary>
        internal bool IsReachable(InstructionInBlock target, InstructionInBlock source, InstructionInBlock blocker)
        {
            if (target == blocker)
                return false;
            if (target == source)
                throw new ArgumentException("source and target must be different"); // or think about a proper meaning.

            HashSet<BasicBlock> sourceReachables = null;

            // Check all three instructions inthe same block.
            if (source.Block == target.Block && source.Block == blocker.Block)
            {
                if (target.Instruction.Index >= source.Instruction.Index)
                {
                    return source.Instruction.Index > blocker.Instruction.Index 
                        || blocker.Instruction.Index > target.Instruction.Index;
                }
                else
                {
                    if(blocker.Instruction.Index <= target.Instruction.Index
                    || blocker.Instruction.Index > source.Instruction.Index)
                        return false;

                    sourceReachables = GetReachableBlocks(source.Block);
                    return sourceReachables.Contains(source.Block);
                }
            }
            // check source in same block as either target or blocker.
            if (source.Block == target.Block && source.Instruction.Index < target.Instruction.Index)
                return true;
            if (source.Block == blocker.Block && source.Instruction.Index < blocker.Instruction.Index)
                return false;

            sourceReachables = GetReachableBlocks(source.Block);
            // the easy checks...
            if (!sourceReachables.Contains(target.Block))
                return false;
            if (!sourceReachables.Contains(blocker.Block))
                return true;
            // slightly more complicated: both target and blocker are reachable from source.
            if (target.Block == blocker.Block)
                return target.Instruction.Index < blocker.Instruction.Index;
            // work on a per-block basis.
            return IsReachable(target.Block, source.Block, blocker.Block, new HashSet<BasicBlock>());
        }