//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "spiller"
+#define DEBUG_TYPE "regalloc"
#include "Spiller.h"
#include "LiveRangeEdit.h"
#include "SplitKit.h"
#include "VirtRegMap.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/LiveStackAnalysis.h"
+#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+static cl::opt<bool>
+VerifySpills("verify-spills", cl::desc("Verify after each spill/split"));
+
+static cl::opt<bool>
+ExtraSpillerSplits("extra-spiller-splits",
+ cl::desc("Enable additional splitting during splitting"));
+
namespace {
class InlineSpiller : public Spiller {
MachineFunctionPass &pass_;
MachineFunction &mf_;
LiveIntervals &lis_;
+ LiveStacks &lss_;
+ MachineDominatorTree &mdt_;
MachineLoopInfo &loops_;
VirtRegMap &vrm_;
MachineFrameInfo &mfi_;
: pass_(pass),
mf_(mf),
lis_(pass.getAnalysis<LiveIntervals>()),
+ lss_(pass.getAnalysis<LiveStacks>()),
+ mdt_(pass.getAnalysis<MachineDominatorTree>()),
loops_(pass.getAnalysis<MachineLoopInfo>()),
vrm_(vrm),
mfi_(*mf.getFrameInfo()),
Spiller *createInlineSpiller(MachineFunctionPass &pass,
MachineFunction &mf,
VirtRegMap &vrm) {
+ if (VerifySpills)
+ mf.verify(&pass);
return new InlineSpiller(pass, mf, vrm);
}
}
splitAnalysis_.analyze(&edit_->getParent());
// Try splitting around loops.
- if (const MachineLoop *loop = splitAnalysis_.getBestSplitLoop()) {
- SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)
- .splitAroundLoop(loop);
- return true;
+ if (ExtraSpillerSplits) {
+ const MachineLoop *loop = splitAnalysis_.getBestSplitLoop();
+ if (loop) {
+ SplitEditor(splitAnalysis_, lis_, vrm_, mdt_, *edit_)
+ .splitAroundLoop(loop);
+ return true;
+ }
}
// Try splitting into single block intervals.
SplitAnalysis::BlockPtrSet blocks;
if (splitAnalysis_.getMultiUseBlocks(blocks)) {
- SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)
+ SplitEditor(splitAnalysis_, lis_, vrm_, mdt_, *edit_)
.splitSingleBlocks(blocks);
return true;
}
// Try splitting inside a basic block.
- if (const MachineBasicBlock *MBB = splitAnalysis_.getBlockForInsideSplit()) {
- SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)
- .splitInsideBlock(MBB);
- return true;
+ if (ExtraSpillerSplits) {
+ const MachineBasicBlock *MBB = splitAnalysis_.getBlockForInsideSplit();
+ if (MBB){
+ SplitEditor(splitAnalysis_, lis_, vrm_, mdt_, *edit_)
+ .splitInsideBlock(MBB);
+ return true;
+ }
}
return false;
SmallVectorImpl<LiveInterval*> &spillIs) {
LiveRangeEdit edit(*li, newIntervals, spillIs);
spill(edit);
+ if (VerifySpills)
+ mf_.verify(&pass_);
}
void InlineSpiller::spill(LiveRangeEdit &edit) {
edit_ = &edit;
- DEBUG(dbgs() << "Inline spilling " << edit.getParent() << "\n");
+ assert(!edit.getParent().isStackSlot() && "Trying to spill a stack slot.");
+ DEBUG(dbgs() << "Inline spilling "
+ << mri_.getRegClass(edit.getReg())->getName()
+ << ':' << edit.getParent() << "\n");
assert(edit.getParent().isSpillable() &&
"Attempting to spill already spilled value.");
- assert(!edit.getParent().isStackSlot() && "Trying to spill a stack slot.");
if (split())
return;
return;
rc_ = mri_.getRegClass(edit.getReg());
- stackSlot_ = edit.assignStackSlot(vrm_);
+ stackSlot_ = vrm_.assignVirt2StackSlot(edit_->getReg());
+
+ // Update LiveStacks now that we are committed to spilling.
+ LiveInterval &stacklvr = lss_.getOrCreateInterval(stackSlot_, rc_);
+ assert(stacklvr.empty() && "Just created stack slot not empty");
+ stacklvr.getNextValue(SlotIndex(), 0, lss_.getVNInfoAllocator());
+ stacklvr.MergeRangesInAsValue(edit_->getParent(), stacklvr.getValNumInfo(0));
// Iterate over instructions using register.
for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(edit.getReg());