From cea2f596f98b79fafaded1c36c98aa3fa04d5147 Mon Sep 17 00:00:00 2001 From: Santiago Aboy Solanes Date: Thu, 8 Feb 2024 10:42:21 +0000 Subject: Improve IsDeadAndRemovable Investigating DCE I noticed that it was the 3rd most time consuming optimization phase (Inliner, GVN, DCE) on local pprof profiles. Inside RemoveDeadInstructions we ask IsDeadAndRemovable for every instruction and Phi. We can speed it up by: * Swap the order of IsDead and IsRemovable for earlier breaks with e.g. LoadClass. LoadClass instructions are used by ClinitCheck instructions (until very late in the graph). These instructions are never going to be removed in DCE. * Phi instructions always pass the IsRemovable check so we can skip it. Swapping the order improves RemoveDeadInstructions by ~20%, which is DCE's most time consuming method. Overall, DCE improves by ~5% and in my local trace now is the 4th most time consuming optimization (LSE is now 3rd). The Phi optimization didn't show up in my pprof profile. It may improve apps with many Phi instructions. Test: Locally compile and take a look at pprof profiles Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: I59932a8d8d627fc71628e2255582f35282dd0b4e --- compiler/optimizing/nodes.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'compiler/optimizing/nodes.h') diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 367f45f3a4..bf4a66dfc3 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2448,18 +2448,26 @@ class HInstruction : public ArenaObject { bool IsRemovable() const { return !DoesAnyWrite() && - !CanThrow() && + // TODO(solanes): Merge calls from IsSuspendCheck to IsControlFlow into one that doesn't + // do virtual dispatching. !IsSuspendCheck() && - !IsControlFlow() && !IsNop() && !IsParameterValue() && // If we added an explicit barrier then we should keep it. !IsMemoryBarrier() && - !IsConstructorFence(); + !IsConstructorFence() && + !IsControlFlow() && + !CanThrow(); } bool IsDeadAndRemovable() const { - return IsRemovable() && !HasUses(); + return !HasUses() && IsRemovable(); + } + + bool IsPhiDeadAndRemovable() const { + DCHECK(IsPhi()); + DCHECK(IsRemovable()) << " phis are always removable"; + return !HasUses(); } // Does this instruction dominate `other_instruction`? -- cgit v1.2.3-59-g8ed1b