1193323Sed//===-- llvm/CodeGen/Spiller.cpp -  Spiller -------------------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed
10193323Sed#define DEBUG_TYPE "spiller"
11193323Sed
12193323Sed#include "Spiller.h"
13193323Sed#include "llvm/CodeGen/LiveIntervalAnalysis.h"
14234353Sdim#include "llvm/CodeGen/LiveRangeEdit.h"
15218893Sdim#include "llvm/CodeGen/LiveStackAnalysis.h"
16198090Srdivacky#include "llvm/CodeGen/MachineFrameInfo.h"
17193323Sed#include "llvm/CodeGen/MachineFunction.h"
18210299Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
19212904Sdim#include "llvm/CodeGen/MachineLoopInfo.h"
20193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h"
21249423Sdim#include "llvm/CodeGen/VirtRegMap.h"
22199511Srdivacky#include "llvm/Support/CommandLine.h"
23193323Sed#include "llvm/Support/Debug.h"
24210299Sed#include "llvm/Support/ErrorHandling.h"
25198090Srdivacky#include "llvm/Support/raw_ostream.h"
26249423Sdim#include "llvm/Target/TargetInstrInfo.h"
27249423Sdim#include "llvm/Target/TargetMachine.h"
28193323Sed
29193323Sedusing namespace llvm;
30193323Sed
31199511Srdivackynamespace {
32234353Sdim  enum SpillerName { trivial, inline_ };
33199511Srdivacky}
34199511Srdivacky
35199511Srdivackystatic cl::opt<SpillerName>
36199511SrdivackyspillerOpt("spiller",
37199511Srdivacky           cl::desc("Spiller to use: (default: standard)"),
38199511Srdivacky           cl::Prefix,
39200581Srdivacky           cl::values(clEnumVal(trivial,   "trivial spiller"),
40210299Sed                      clEnumValN(inline_,  "inline", "inline spiller"),
41199511Srdivacky                      clEnumValEnd),
42234353Sdim           cl::init(trivial));
43199511Srdivacky
44200581Srdivacky// Spiller virtual destructor implementation.
45193323SedSpiller::~Spiller() {}
46193323Sed
47193323Sednamespace {
48193323Sed
49193323Sed/// Utility class for spillers.
50193323Sedclass SpillerBase : public Spiller {
51193323Sedprotected:
52212904Sdim  MachineFunctionPass *pass;
53193323Sed  MachineFunction *mf;
54212904Sdim  VirtRegMap *vrm;
55193323Sed  LiveIntervals *lis;
56193323Sed  MachineFrameInfo *mfi;
57193323Sed  MachineRegisterInfo *mri;
58193323Sed  const TargetInstrInfo *tii;
59208599Srdivacky  const TargetRegisterInfo *tri;
60210299Sed
61210299Sed  /// Construct a spiller base.
62212904Sdim  SpillerBase(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm)
63212904Sdim    : pass(&pass), mf(&mf), vrm(&vrm)
64193323Sed  {
65212904Sdim    lis = &pass.getAnalysis<LiveIntervals>();
66212904Sdim    mfi = mf.getFrameInfo();
67212904Sdim    mri = &mf.getRegInfo();
68212904Sdim    tii = mf.getTarget().getInstrInfo();
69212904Sdim    tri = mf.getTarget().getRegisterInfo();
70193323Sed  }
71193323Sed
72193323Sed  /// Add spill ranges for every use/def of the live interval, inserting loads
73199511Srdivacky  /// immediately before each use, and stores after each def. No folding or
74199511Srdivacky  /// remat is attempted.
75234353Sdim  void trivialSpillEverywhere(LiveRangeEdit& LRE) {
76234353Sdim    LiveInterval* li = &LRE.getParent();
77234353Sdim
78202375Srdivacky    DEBUG(dbgs() << "Spilling everywhere " << *li << "\n");
79193323Sed
80263508Sdim    assert(li->weight != llvm::huge_valf &&
81193323Sed           "Attempting to spill already spilled value.");
82193323Sed
83218893Sdim    assert(!TargetRegisterInfo::isStackSlot(li->reg) &&
84193323Sed           "Trying to spill a stack slot.");
85193323Sed
86202375Srdivacky    DEBUG(dbgs() << "Trivial spill everywhere of reg" << li->reg << "\n");
87195098Sed
88193323Sed    const TargetRegisterClass *trc = mri->getRegClass(li->reg);
89193323Sed    unsigned ss = vrm->assignVirt2StackSlot(li->reg);
90193323Sed
91199511Srdivacky    // Iterate over reg uses/defs.
92193323Sed    for (MachineRegisterInfo::reg_iterator
93193323Sed         regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) {
94193323Sed
95199511Srdivacky      // Grab the use/def instr.
96193323Sed      MachineInstr *mi = &*regItr;
97195098Sed
98202375Srdivacky      DEBUG(dbgs() << "  Processing " << *mi);
99195098Sed
100199511Srdivacky      // Step regItr to the next use/def instr.
101193323Sed      do {
102193323Sed        ++regItr;
103193323Sed      } while (regItr != mri->reg_end() && (&*regItr == mi));
104210299Sed
105199511Srdivacky      // Collect uses & defs for this instr.
106193323Sed      SmallVector<unsigned, 2> indices;
107193323Sed      bool hasUse = false;
108193323Sed      bool hasDef = false;
109193323Sed      for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
110193323Sed        MachineOperand &op = mi->getOperand(i);
111193323Sed        if (!op.isReg() || op.getReg() != li->reg)
112193323Sed          continue;
113193323Sed        hasUse |= mi->getOperand(i).isUse();
114193323Sed        hasDef |= mi->getOperand(i).isDef();
115193323Sed        indices.push_back(i);
116193323Sed      }
117193323Sed
118263508Sdim      // Create a new virtual register for the load and/or store.
119263508Sdim      unsigned NewVReg = LRE.create();
120210299Sed
121199511Srdivacky      // Update the reg operands & kill flags.
122193323Sed      for (unsigned i = 0; i < indices.size(); ++i) {
123199511Srdivacky        unsigned mopIdx = indices[i];
124199511Srdivacky        MachineOperand &mop = mi->getOperand(mopIdx);
125263508Sdim        mop.setReg(NewVReg);
126199511Srdivacky        if (mop.isUse() && !mi->isRegTiedToDefOperand(mopIdx)) {
127199511Srdivacky          mop.setIsKill(true);
128193323Sed        }
129193323Sed      }
130193323Sed      assert(hasUse || hasDef);
131193323Sed
132199511Srdivacky      // Insert reload if necessary.
133199511Srdivacky      MachineBasicBlock::iterator miItr(mi);
134193323Sed      if (hasUse) {
135263508Sdim        MachineInstrSpan MIS(miItr);
136263508Sdim
137263508Sdim        tii->loadRegFromStackSlot(*mi->getParent(), miItr, NewVReg, ss, trc,
138208599Srdivacky                                  tri);
139263508Sdim        lis->InsertMachineInstrRangeInMaps(MIS.begin(), miItr);
140193323Sed      }
141193323Sed
142199511Srdivacky      // Insert store if necessary.
143193323Sed      if (hasDef) {
144263508Sdim        MachineInstrSpan MIS(miItr);
145263508Sdim
146263508Sdim        tii->storeRegToStackSlot(*mi->getParent(), llvm::next(miItr), NewVReg,
147208599Srdivacky                                 true, ss, trc, tri);
148263508Sdim        lis->InsertMachineInstrRangeInMaps(llvm::next(miItr), MIS.end());
149193323Sed      }
150193323Sed    }
151193323Sed  }
152193323Sed};
153193323Sed
154207618Srdivacky} // end anonymous namespace
155193323Sed
156207618Srdivackynamespace {
157207618Srdivacky
158193323Sed/// Spills any live range using the spill-everywhere method with no attempt at
159193323Sed/// folding.
160193323Sedclass TrivialSpiller : public SpillerBase {
161193323Sedpublic:
162194612Sed
163212904Sdim  TrivialSpiller(MachineFunctionPass &pass, MachineFunction &mf,
164212904Sdim                 VirtRegMap &vrm)
165212904Sdim    : SpillerBase(pass, mf, vrm) {}
166193323Sed
167221345Sdim  void spill(LiveRangeEdit &LRE) {
168199511Srdivacky    // Ignore spillIs - we don't use it.
169234353Sdim    trivialSpillEverywhere(LRE);
170193323Sed  }
171199511Srdivacky};
172194612Sed
173207618Srdivacky} // end anonymous namespace
174207618Srdivacky
175234353Sdimvoid Spiller::anchor() { }
176207618Srdivacky
177212904Sdimllvm::Spiller* llvm::createSpiller(MachineFunctionPass &pass,
178212904Sdim                                   MachineFunction &mf,
179212904Sdim                                   VirtRegMap &vrm) {
180199511Srdivacky  switch (spillerOpt) {
181212904Sdim  case trivial: return new TrivialSpiller(pass, mf, vrm);
182212904Sdim  case inline_: return createInlineSpiller(pass, mf, vrm);
183199511Srdivacky  }
184234353Sdim  llvm_unreachable("Invalid spiller optimization");
185193323Sed}
186