From 15121ca0d18e6a0f6a16f8a696f4efc3782dc965 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen <stoklund@2pi.dk> Date: Fri, 10 Aug 2012 03:23:27 +0000 Subject: [PATCH] Update edge weights correctly in replaceSuccessor(). When replacing Old with New, it can happen that New is already a successor. Add the old and new edge weights instead of creating a duplicate edge. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161653 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineBasicBlock.cpp | 42 ++++++++++++++++++++++++------- test/CodeGen/X86/br-fold.ll | 2 +- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 151b4021681..fd4cb5fab0b 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -478,18 +478,42 @@ MachineBasicBlock::removeSuccessor(succ_iterator I) { void MachineBasicBlock::replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New) { - uint32_t weight = 0; - succ_iterator SI = std::find(Successors.begin(), Successors.end(), Old); + if (Old == New) + return; - // If Weight list is empty it means we don't use it (disabled optimization). - if (!Weights.empty()) { - weight_iterator WI = getWeightIterator(SI); - weight = *WI; + succ_iterator E = succ_end(); + succ_iterator NewI = E; + succ_iterator OldI = E; + for (succ_iterator I = succ_begin(); I != E; ++I) { + if (*I == Old) { + OldI = I; + if (NewI != E) + break; + } + if (*I == New) { + NewI = I; + if (OldI != E) + break; + } + } + assert(OldI != E && "Old is not a successor of this block"); + Old->removePredecessor(this); + + // If New isn't already a successor, let it take Old's place. + if (NewI == E) { + New->addPredecessor(this); + *OldI = New; + return; } - // Update the successor information. - removeSuccessor(SI); - addSuccessor(New, weight); + // New is already a successor. + // Update its weight instead of adding a duplicate edge. + if (!Weights.empty()) { + weight_iterator OldWI = getWeightIterator(OldI); + *getWeightIterator(NewI) += *OldWI; + Weights.erase(OldWI); + } + Successors.erase(OldI); } void MachineBasicBlock::addPredecessor(MachineBasicBlock *pred) { diff --git a/test/CodeGen/X86/br-fold.ll b/test/CodeGen/X86/br-fold.ll index 2c371949380..52234630116 100644 --- a/test/CodeGen/X86/br-fold.ll +++ b/test/CodeGen/X86/br-fold.ll @@ -1,7 +1,7 @@ ; RUN: llc -march=x86-64 < %s | FileCheck %s ; CHECK: orq -; CHECK-NEXT: LBB0_1 +; CHECK-NEXT: %bb8.i329 @_ZN11xercesc_2_513SchemaSymbols21fgURI_SCHEMAFORSCHEMAE = external constant [33 x i16], align 32 ; <[33 x i16]*> [#uses=1] @_ZN11xercesc_2_56XMLUni16fgNotationStringE = external constant [9 x i16], align 16 ; <[9 x i16]*> [#uses=1]