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); }
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); } }
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); } } } }
/// <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>())); }
private void AddWrite(InstructionInBlock ins) { Writes.Add(ins); if (ins.Instruction.Code.IsMove()) { MovesFromOtherRegisters.Add(ins); } }
public void ConvertToNop(InstructionInBlock ins) { // update registers usages. foreach (var r in ins.Instruction.Registers) { _usages[r].Remove(ins); } ins.Instruction.ConvertToNop(); }
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); }
private void AddWrite(InstructionInBlock ins) { Writes.Add(ins); if (ins.Instruction.Code.IsMove()) MovesFromOtherRegisters.Add(ins); }
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); } } } }
/// <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>()); }