diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 7564c1da89a..889bca3011d 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -123,9 +123,13 @@ class RAGreedy : public MachineFunctionPass, /// Cached per-block interference maps InterferenceCache IntfCache; - /// All basic blocks where the current register is live. + /// All basic blocks where the current register has uses. SmallVector SplitConstraints; + /// All basic blocks where the current register is live-through and + /// interference free. + SmallVector TransparentBlocks; + /// Global live range splitting candidate info. struct GlobalSplitCandidate { unsigned PhysReg; @@ -475,6 +479,7 @@ bool RAGreedy::addSplitConstraints(unsigned PhysReg, float &Cost) { const unsigned GroupSize = 8; SpillPlacement::BlockConstraint BCS[GroupSize]; unsigned B = 0; + TransparentBlocks.clear(); ArrayRef ThroughBlocks = SA->getThroughBlocks(); for (unsigned i = 0; i != ThroughBlocks.size(); ++i) { @@ -483,23 +488,23 @@ bool RAGreedy::addSplitConstraints(unsigned PhysReg, float &Cost) { BCS[B].Number = Number; Intf.moveToBlock(Number); - if (Intf.hasInterference()) { - // Interference for the live-in value. - if (Intf.first() <= Indexes->getMBBStartIdx(Number)) - BCS[B].Entry = SpillPlacement::MustSpill; - else - BCS[B].Entry = SpillPlacement::PrefSpill; - - // Interference for the live-out value. - if (Intf.last() >= SA->getLastSplitPoint(Number)) - BCS[B].Exit = SpillPlacement::MustSpill; - else - BCS[B].Exit = SpillPlacement::PrefSpill; - } else { - // No interference, transparent block. - BCS[B].Entry = BCS[B].Exit = SpillPlacement::DontCare; + if (!Intf.hasInterference()) { + TransparentBlocks.push_back(Number); + continue; } + // Interference for the live-in value. + if (Intf.first() <= Indexes->getMBBStartIdx(Number)) + BCS[B].Entry = SpillPlacement::MustSpill; + else + BCS[B].Entry = SpillPlacement::PrefSpill; + + // Interference for the live-out value. + if (Intf.last() >= SA->getLastSplitPoint(Number)) + BCS[B].Exit = SpillPlacement::MustSpill; + else + BCS[B].Exit = SpillPlacement::PrefSpill; + if (++B == GroupSize) { ArrayRef Array(BCS, B); SpillPlacer->addConstraints(Array); @@ -512,7 +517,12 @@ bool RAGreedy::addSplitConstraints(unsigned PhysReg, float &Cost) { ArrayRef Array(BCS, B); SpillPlacer->addConstraints(Array); - return SpillPlacer->getPositiveNodes() != 0; + if (SpillPlacer->getPositiveNodes() == 0) + return false; + + // There is still some positive bias. Add all the links. + SpillPlacer->addLinks(TransparentBlocks); + return true; } diff --git a/lib/CodeGen/SpillPlacement.cpp b/lib/CodeGen/SpillPlacement.cpp index 0ccb93f871d..ac7a19267c5 100644 --- a/lib/CodeGen/SpillPlacement.cpp +++ b/lib/CodeGen/SpillPlacement.cpp @@ -213,23 +213,6 @@ void SpillPlacement::addConstraints(ArrayRef LiveBlocks) { for (ArrayRef::iterator I = LiveBlocks.begin(), E = LiveBlocks.end(); I != E; ++I) { float Freq = getBlockFrequency(I->Number); - - // Is this a transparent block? Link ingoing and outgoing bundles. - if (I->Entry == DontCare && I->Exit == DontCare) { - unsigned ib = bundles->getBundle(I->Number, 0); - unsigned ob = bundles->getBundle(I->Number, 1); - - // Ignore self-loops. - if (ib == ob) - continue; - activate(ib); - activate(ob); - nodes[ib].addLink(ob, Freq, 1); - nodes[ob].addLink(ib, Freq, 0); - continue; - } - - // This block is not transparent, but it can still add bias. const float Bias[] = { 0, // DontCare, 1, // PrefReg, @@ -253,6 +236,24 @@ void SpillPlacement::addConstraints(ArrayRef LiveBlocks) { } } +void SpillPlacement::addLinks(ArrayRef Links) { + for (ArrayRef::iterator I = Links.begin(), E = Links.end(); I != E; + ++I) { + unsigned Number = *I; + unsigned ib = bundles->getBundle(Number, 0); + unsigned ob = bundles->getBundle(Number, 1); + + // Ignore self-loops. + if (ib == ob) + continue; + activate(ib); + activate(ob); + float Freq = getBlockFrequency(Number); + nodes[ib].addLink(ob, Freq, 1); + nodes[ob].addLink(ib, Freq, 0); + } +} + /// iterate - Repeatedly update the Hopfield nodes until stability or the /// maximum number of iterations is reached. /// @param Linked - Numbers of linked nodes that need updating. diff --git a/lib/CodeGen/SpillPlacement.h b/lib/CodeGen/SpillPlacement.h index a67785ddf9b..46e64e6fcbf 100644 --- a/lib/CodeGen/SpillPlacement.h +++ b/lib/CodeGen/SpillPlacement.h @@ -89,11 +89,12 @@ public: /// addConstraints - Add constraints and biases. This method may be called /// more than once to accumulate constraints. /// @param LiveBlocks Constraints for blocks that have the variable live in or - /// live out. DontCare/DontCare means the variable is live - /// through the block. DontCare/X means the variable is live - /// out, but not live in. + /// live out. void addConstraints(ArrayRef LiveBlocks); + /// addLinks - Add transparent blocks with the given numbers. + void addLinks(ArrayRef Links); + /// getPositiveNodes - Return the total number of graph nodes with a positive /// bias after adding constraints. unsigned getPositiveNodes() const { return PositiveNodes; }