/// <summary> /// Get list of dead definitions at the point right before a specified instruction. /// </summary> /// <param name="BasicBlock">Basic block.</param> /// <param name="Index">Index of target instruction.</param> /// <param name="DeadDefinitionList">Optional. List of dead definitions at the end of the basic block.</param> /// <returns>List of dead definitions before instruction with specified <paramref name="Index"/>.</returns> public static LocationList BeforeInstruction(BasicBlock BasicBlock, int Index, LocationList DeadDefinitionList) { if (Index < 0) { throw new ArgumentOutOfRangeException("Index"); } if (DeadDefinitionList == null) { DeadDefinitionList = new LocationList(); } else { DeadDefinitionList = new LocationList(DeadDefinitionList); } for (int i = BasicBlock.Instructions.Count - 1; i >= Index; i--) { Instruction Instruction = BasicBlock.Instructions[i]; LocationUsage LocationUsage = LocationUsage.ForInstruction(Instruction); foreach (Location Location in LocationUsage.DefinedLocations) { if (Location.LocationType == LocationType.CilStack || Location.LocationType == LocationType.LocalVariable || Location.LocationType == LocationType.Argument) { DeadDefinitionList.Add(Location); } } foreach (Location Location in LocationUsage.UsedLocations) { if (Location.LocationType == LocationType.CilStack || Location.LocationType == LocationType.LocalVariable || Location.LocationType == LocationType.Argument) { DeadDefinitionList.Remove(Location); } } } return(DeadDefinitionList); }
private static bool ForBlock(BasicBlock BasicBlock, ref List <Location> DeadDefinitionList) { if (DeadDefinitionList == null) { DeadDefinitionList = new List <Location>(); } bool InstructionsDeleted = false; for (int i = BasicBlock.Instructions.Count - 1; i >= 0; i--) { Instruction Instruction = BasicBlock.Instructions[i]; bool IsDeadAssignment = false; if (Instruction.InstructionType == InstructionType.Assignment && Instruction.Result != null && Instruction.Result.NodeType == NodeType.Location) { Location Location = ((LocationNode)Instruction.Result).Location; // Work around default equality check for stack locations. We only // care about the stack index, not the data type here... if (Location.LocationType == LocationType.CilStack) { foreach (Location Other in DeadDefinitionList) { if (Other.LocationType == LocationType.CilStack && ((StackLocation)Other).Index == ((StackLocation)Location).Index) { IsDeadAssignment = true; break; } } } else if (DeadDefinitionList.Contains(Location)) { IsDeadAssignment = true; } } // TODO: check for side effects... if (IsDeadAssignment && HasSideEffects(Instruction.Argument)) { Instruction.Result = null; } else if (IsDeadAssignment) { BasicBlock.Instructions.RemoveAt(i); InstructionsDeleted = true; continue; } LocationUsage LocationUsage = LocationUsage.ForInstruction(Instruction); foreach (Location Location in LocationUsage.DefinedLocations) { if (!DeadDefinitionList.Contains(Location)) { DeadDefinitionList.Add(Location); } } foreach (Location Location in LocationUsage.UsedLocations) { DeadDefinitionList.Remove(Location); } } return(InstructionsDeleted); }