From 1afda74860d0bb421c104258a8533b1f4f77caa3 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 17 Aug 2023 10:45:23 +0300 Subject: [PATCH 1/2] Improve linker performance by avoiding IndexOf --- .../UnreachableBlocksOptimizer.cs | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs b/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs index e25eaf0b9b8e41..cd7213efa82b66 100644 --- a/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs +++ b/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs @@ -92,21 +92,39 @@ static bool IsMethodSupported (MethodDefinition method) return true; } - static bool HasJumpIntoTargetRange (Collection instructions, int firstInstr, int lastInstr, Func? mapping = null) + static bool HasJumpIntoTargetRange (Collection instructions, int firstInstr, int lastInstr, Func? mapping = null) { foreach (var instr in instructions) { switch (instr.OpCode.FlowControl) { case FlowControl.Branch: case FlowControl.Cond_Branch: if (instr.Operand is Instruction target) { - int index = mapping == null ? instructions.IndexOf (target) : mapping (target); - if (index >= firstInstr && index <= lastInstr) - return true; + if (mapping != null && mapping (target) is int index) { + if (index >= firstInstr && index <= lastInstr) { + return true; + } + } + else { + for (int i = firstInstr; i <= lastInstr; i++) { + if (instructions[i] == target) { + return true; + } + } + } } else { foreach (var rtarget in (Instruction[]) instr.Operand) { - int index = mapping == null ? instructions.IndexOf (rtarget) : mapping (rtarget); - if (index >= firstInstr && index <= lastInstr) - return true; + if (mapping != null && mapping (target) is int index) { + if (index >= firstInstr && index <= lastInstr) { + return true; + } + } + else { + for (int i = firstInstr; i <= lastInstr; i++) { + if (instructions[i] == target) { + return true; + } + } + } } } @@ -1175,6 +1193,15 @@ int GetInstructionIndex (Instruction instruction) return idx; } + int? TryGetInstructionIndex (Instruction instruction) + { + Debug.Assert (mapping != null); + if (mapping.TryGetValue (instruction, out int idx)) + return idx; + + return null; + } + bool GetOperandsConstantValues (int index, out object? left, out object? right) { Debug.Assert (FoldedInstructions != null); @@ -1213,7 +1240,7 @@ static bool IsPairedStlocLdloc (Instruction first, Instruction second) bool IsJumpTargetRange (int firstInstr, int lastInstr) { Debug.Assert (FoldedInstructions != null); - return HasJumpIntoTargetRange (FoldedInstructions, firstInstr, lastInstr, GetInstructionIndex); + return HasJumpIntoTargetRange (FoldedInstructions, firstInstr, lastInstr, TryGetInstructionIndex); } } From 7de45edcb37cf533d80825fd150df7158647d31e Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 17 Aug 2023 11:07:08 +0300 Subject: [PATCH 2/2] Fix typos --- .../src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs b/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs index cd7213efa82b66..d9fd14c5c9a5ee 100644 --- a/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs +++ b/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs @@ -113,14 +113,14 @@ static bool HasJumpIntoTargetRange (Collection instructions, int fi } } else { foreach (var rtarget in (Instruction[]) instr.Operand) { - if (mapping != null && mapping (target) is int index) { + if (mapping != null && mapping (rtarget) is int index) { if (index >= firstInstr && index <= lastInstr) { return true; } } else { for (int i = firstInstr; i <= lastInstr; i++) { - if (instructions[i] == target) { + if (instructions[i] == rtarget) { return true; } }