SplitKit.cpp revision abff28087fd6be8150ff0e69def7de7312b2f76b
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//===---------- SplitKit.cpp - Toolkit for splitting live ranges ----------===//
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//                     The LLVM Compiler Infrastructure
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This file is distributed under the University of Illinois Open Source
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// License. See LICENSE.TXT for details.
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//===----------------------------------------------------------------------===//
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This file contains the SplitAnalysis class as well as mutator functions for
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// live range splitting.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//===----------------------------------------------------------------------===//
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DEBUG_TYPE "splitter"
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "SplitKit.h"
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "llvm/CodeGen/LiveIntervalAnalysis.h"
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "llvm/CodeGen/MachineFunctionPass.h"
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "llvm/CodeGen/MachineLoopInfo.h"
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "llvm/CodeGen/MachineRegisterInfo.h"
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "llvm/Support/Debug.h"
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "llvm/Support/raw_ostream.h"
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace llvm;
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//===----------------------------------------------------------------------===//
283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//                                 Split Analysis
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//===----------------------------------------------------------------------===//
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSplitAnalysis::SplitAnalysis(const MachineFunction *mf,
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             const LiveIntervals *lis,
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             const MachineLoopInfo *mli)
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  : mf_(*mf),
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lis_(*lis),
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    loops_(*mli),
37bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch    curli_(0) {}
389fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SplitAnalysis::clear() {
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  usingInstrs_.clear();
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  usingBlocks_.clear();
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  usingLoops_.clear();
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/// analyzeUses - Count instructions, basic blocks, and loops using curli.
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SplitAnalysis::analyzeUses() {
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const MachineRegisterInfo &MRI = mf_.getRegInfo();
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (MachineRegisterInfo::reg_iterator I = MRI.reg_begin(curli_->reg);
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       MachineInstr *MI = I.skipInstruction();) {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (MI->isDebugValue() || !usingInstrs_.insert(MI))
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      continue;
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    MachineBasicBlock *MBB = MI->getParent();
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (usingBlocks_[MBB]++)
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      continue;
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (MachineLoop *Loop = loops_.getLoopFor(MBB))
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      usingLoops_.insert(Loop);
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DEBUG(dbgs() << "Counted "
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               << usingInstrs_.size() << " instrs, "
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               << usingBlocks_.size() << " blocks, "
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               << usingLoops_.size()  << " loops in "
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               << *curli_ << "\n");
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSplitAnalysis::LoopPeripheralUse
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSplitAnalysis::analyzeLoopPeripheralUse(const MachineLoop *Loop) {
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Peripheral blocks.
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SmallVector<MachineBasicBlock*, 16> Peri;
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Loop->getExitBlocks(Peri);
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (MachineBasicBlock *PredBB = Loop->getLoopPredecessor())
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Peri.push_back(PredBB);
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  array_pod_sort(Peri.begin(), Peri.end());
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Peri.erase(std::unique(Peri.begin(), Peri.end()), Peri.end());
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoopPeripheralUse use = ContainedInLoop;
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (BlockCountMap::iterator I = usingBlocks_.begin(), E = usingBlocks_.end();
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       I != E; ++I) {
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const MachineBasicBlock *MBB = I->first;
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Is this a peripheral block?
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (use < MultiPeripheral &&
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        std::binary_search(Peri.begin(), Peri.end(), MBB)) {
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (I->second > 1) use = MultiPeripheral;
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      else               use = SinglePeripheral;
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      continue;
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Is it a loop block?
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (Loop->contains(MBB))
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      continue;
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // It must be an unrelated block.
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return OutsideLoop;
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return use;
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SplitAnalysis::analyze(const LiveInterval *li) {
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  clear();
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  curli_ = li;
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  analyzeUses();
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1009fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst MachineLoop *SplitAnalysis::getBestSplitLoop() {
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoopPtrSet Loops, SecondLoops;
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Find first-class and second class candidate loops.
1059fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // We prefer to split around loops where curli is used outside the periphery.
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (LoopPtrSet::const_iterator I = usingLoops_.begin(),
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       E = usingLoops_.end(); I != E; ++I)
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    switch(analyzeLoopPeripheralUse(*I)) {
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case OutsideLoop:
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Loops.insert(*I);
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case MultiPeripheral:
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      SecondLoops.insert(*I);
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default:
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      continue;
117bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch    }
118bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
119bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // If there are no first class loops available, look at second class loops.
120bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  if (Loops.empty())
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Loops = SecondLoops;
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (Loops.empty())
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return 0;
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Pick the earliest loop.
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // FIXME: Are there other heuristics to consider?
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // - avoid breaking critical edges.
129bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // - avoid impossible loops.
130bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  const MachineLoop *Best = 0;
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SlotIndex BestIdx;
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (LoopPtrSet::const_iterator I = Loops.begin(), E = Loops.end(); I != E;
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       ++I) {
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    SlotIndex Idx = lis_.getMBBStartIdx((*I)->getHeader());
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!Best || Idx < BestIdx)
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Best = *I, BestIdx = Idx;
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
138bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  return Best;
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
140bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//===----------------------------------------------------------------------===//
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//                               Loop Splitting
143bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch//===----------------------------------------------------------------------===//
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
145bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochbool llvm::splitAroundLoop(SplitAnalysis &sa, const MachineLoop *loop) {
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return false;
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block