diff options
Diffstat (limited to 'lib/CodeGen/SpillPlacement.cpp')
| -rw-r--r-- | lib/CodeGen/SpillPlacement.cpp | 47 | 
1 files changed, 34 insertions, 13 deletions
diff --git a/lib/CodeGen/SpillPlacement.cpp b/lib/CodeGen/SpillPlacement.cpp index 10a93b7fa4db..24e94d11f888 100644 --- a/lib/CodeGen/SpillPlacement.cpp +++ b/lib/CodeGen/SpillPlacement.cpp @@ -27,7 +27,6 @@  //  //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "spillplacement"  #include "SpillPlacement.h"  #include "llvm/ADT/BitVector.h"  #include "llvm/CodeGen/EdgeBundles.h" @@ -41,6 +40,8 @@  using namespace llvm; +#define DEBUG_TYPE "spillplacement" +  char SpillPlacement::ID = 0;  INITIALIZE_PASS_BEGIN(SpillPlacement, "spill-code-placement",                        "Spill Code Placement Analysis", true, true) @@ -59,9 +60,26 @@ void SpillPlacement::getAnalysisUsage(AnalysisUsage &AU) const {    MachineFunctionPass::getAnalysisUsage(AU);  } +namespace { +static BlockFrequency Threshold; +} +  /// Decision threshold. A node gets the output value 0 if the weighted sum of  /// its inputs falls in the open interval (-Threshold;Threshold). -static const BlockFrequency Threshold = 2; +static BlockFrequency getThreshold() { return Threshold; } + +/// \brief Set the threshold for a given entry frequency. +/// +/// Set the threshold relative to \c Entry.  Since the threshold is used as a +/// bound on the open interval (-Threshold;Threshold), 1 is the minimum +/// threshold. +static void setThreshold(const BlockFrequency &Entry) { +  // Apparently 2 is a good threshold when Entry==2^14, but we need to scale +  // it.  Divide by 2^13, rounding as appropriate. +  uint64_t Freq = Entry.getFrequency(); +  uint64_t Scaled = (Freq >> 13) + bool(Freq & (1 << 12)); +  Threshold = std::max(UINT64_C(1), Scaled); +}  /// Node - Each edge bundle corresponds to a Hopfield node.  /// @@ -110,7 +128,7 @@ struct SpillPlacement::Node {    // the CFG.    void clear() {      BiasN = BiasP = Value = 0; -    SumLinkWeights = Threshold; +    SumLinkWeights = getThreshold();      Links.clear();    } @@ -168,9 +186,9 @@ struct SpillPlacement::Node {      //  2. It helps tame rounding errors when the links nominally sum to 0.      //      bool Before = preferReg(); -    if (SumN >= SumP + Threshold) +    if (SumN >= SumP + getThreshold())        Value = -1; -    else if (SumP >= SumN + Threshold) +    else if (SumP >= SumN + getThreshold())        Value = 1;      else        Value = 0; @@ -188,10 +206,11 @@ bool SpillPlacement::runOnMachineFunction(MachineFunction &mf) {    // Compute total ingoing and outgoing block frequencies for all bundles.    BlockFrequencies.resize(mf.getNumBlockIDs()); -  MachineBlockFrequencyInfo &MBFI = getAnalysis<MachineBlockFrequencyInfo>(); +  MBFI = &getAnalysis<MachineBlockFrequencyInfo>(); +  setThreshold(MBFI->getEntryFreq());    for (MachineFunction::iterator I = mf.begin(), E = mf.end(); I != E; ++I) {      unsigned Num = I->getNumber(); -    BlockFrequencies[Num] = MBFI.getBlockFreq(I); +    BlockFrequencies[Num] = MBFI->getBlockFreq(I);    }    // We never change the function. @@ -200,7 +219,7 @@ bool SpillPlacement::runOnMachineFunction(MachineFunction &mf) {  void SpillPlacement::releaseMemory() {    delete[] nodes; -  nodes = 0; +  nodes = nullptr;  }  /// activate - mark node n as active if it wasn't already. @@ -221,7 +240,7 @@ void SpillPlacement::activate(unsigned n) {    // Hopfield network.    if (bundles->getBlocks(n).size() > 100) {      nodes[n].BiasP = 0; -    nodes[n].BiasN = (BlockFrequency::getEntryFrequency() / 16); +    nodes[n].BiasN = (MBFI->getEntryFreq() / 16);    }  } @@ -323,10 +342,12 @@ void SpillPlacement::iterate() {    // affect the entire network in a single iteration. That means very fast    // convergence, usually in a single iteration.    for (unsigned iteration = 0; iteration != 10; ++iteration) { -    // Scan backwards, skipping the last node which was just updated. +    // Scan backwards, skipping the last node when iteration is not zero. When +    // iteration is not zero, the last node was just updated.      bool Changed = false;      for (SmallVectorImpl<unsigned>::const_reverse_iterator I = -           llvm::next(Linked.rbegin()), E = Linked.rend(); I != E; ++I) { +           iteration == 0 ? Linked.rbegin() : std::next(Linked.rbegin()), +           E = Linked.rend(); I != E; ++I) {        unsigned n = *I;        if (nodes[n].update(nodes)) {          Changed = true; @@ -340,7 +361,7 @@ void SpillPlacement::iterate() {      // Scan forwards, skipping the first node which was just updated.      Changed = false;      for (SmallVectorImpl<unsigned>::const_iterator I = -           llvm::next(Linked.begin()), E = Linked.end(); I != E; ++I) { +           std::next(Linked.begin()), E = Linked.end(); I != E; ++I) {        unsigned n = *I;        if (nodes[n].update(nodes)) {          Changed = true; @@ -373,6 +394,6 @@ SpillPlacement::finish() {        ActiveNodes->reset(n);        Perfect = false;      } -  ActiveNodes = 0; +  ActiveNodes = nullptr;    return Perfect;  }  | 
