// Register the target
RegisterTargetMachine<R600TargetMachine> X(TheAMDGPUTarget);
RegisterTargetMachine<GCNTargetMachine> Y(TheGCNTarget);
+
+ PassRegistry *PR = PassRegistry::getPassRegistry();
+ initializeSIFixSGPRLiveRangesPass(*PR);
}
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
: AMDGPUPassConfig(TM, PM) { }
bool addPreISel() override;
bool addInstSelector() override;
+ void addFastRegAlloc(FunctionPass *RegAllocPass) override;
+ void addOptimizedRegAlloc(FunctionPass *RegAllocPass) override;
void addPreRegAlloc() override;
void addPostRegAlloc() override;
void addPreSched2() override;
insertPass(&MachineSchedulerID, &RegisterCoalescerID);
}
addPass(createSIShrinkInstructionsPass(), false);
- addPass(createSIFixSGPRLiveRangesPass());
+}
+
+void GCNPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
+ addPass(&SIFixSGPRLiveRangesID);
+ TargetPassConfig::addFastRegAlloc(RegAllocPass);
+}
+
+void GCNPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
+ // We want to run this after LiveVariables is computed to avoid computing them
+ // twice.
+ insertPass(&LiveVariablesID, &SIFixSGPRLiveRangesID);
+ TargetPassConfig::addOptimizedRegAlloc(RegAllocPass);
}
void GCNPassConfig::addPostRegAlloc() {
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<LiveIntervals>();
+ AU.addRequired<LiveVariables>();
+ AU.addPreserved<LiveVariables>();
+
AU.addRequired<MachinePostDominatorTree>();
+ AU.addPreserved<MachinePostDominatorTree>();
AU.setPreservesCFG();
- //AU.addPreserved<SlotIndexes>(); // XXX - This might be OK
- AU.addPreserved<LiveIntervals>();
-
MachineFunctionPass::getAnalysisUsage(AU);
}
};
INITIALIZE_PASS_BEGIN(SIFixSGPRLiveRanges, DEBUG_TYPE,
"SI Fix SGPR Live Ranges", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
INITIALIZE_PASS_END(SIFixSGPRLiveRanges, DEBUG_TYPE,
bool MadeChange = false;
MachinePostDominatorTree *PDT = &getAnalysis<MachinePostDominatorTree>();
- std::vector<std::pair<unsigned, LiveRange *>> SGPRLiveRanges;
+ SmallVector<unsigned, 16> SGPRLiveRanges;
- LiveIntervals *LIS = &getAnalysis<LiveIntervals>();
- LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>();
+ LiveVariables *LV = &getAnalysis<LiveVariables>();
MachineBasicBlock *Entry = MF.begin();
// Use a depth first order so that in SSA, we encounter all defs before
for (MachineBasicBlock *MBB : depth_first(Entry)) {
for (const MachineInstr &MI : *MBB) {
for (const MachineOperand &MO : MI.defs()) {
- if (MO.isImplicit())
- continue;
+ // We should never see a live out def of a physical register, so we also
+ // do not need to worry about implicit_defs().
unsigned Def = MO.getReg();
if (TargetRegisterInfo::isVirtualRegister(Def)) {
if (TRI->isSGPRClass(MRI.getRegClass(Def))) {
// Only consider defs that are live outs. We don't care about def /
// use within the same block.
- LiveRange &LR = LIS->getInterval(Def);
- if (LIS->isLiveOutOfMBB(LR, MBB))
- SGPRLiveRanges.push_back(std::make_pair(Def, &LR));
+
+ // LiveVariables does not consider registers that are only used in a
+ // phi in a sucessor block as live out, unlike LiveIntervals.
+ //
+ // This is OK because SIFixSGPRCopies replaced any SGPR phis with
+ // VGPRs.
+ if (LV->isLiveOut(Def, *MBB))
+ SGPRLiveRanges.push_back(Def);
}
- } else if (TRI->isSGPRClass(TRI->getPhysRegClass(Def))) {
- SGPRLiveRanges.push_back(std::make_pair(Def, &LIS->getRegUnit(Def)));
}
}
}
*(++NCD->succ_begin()));
}
- for (std::pair<unsigned, LiveRange*> RegLR : SGPRLiveRanges) {
- unsigned Reg = RegLR.first;
- LiveRange *LR = RegLR.second;
-
+ for (unsigned Reg : SGPRLiveRanges) {
// FIXME: We could be smarter here. If the register is Live-In to one
// block, but the other doesn't have any SGPR defs, then there won't be a
// conflict. Also, if the branch condition is uniform then there will be
// no conflict.
- bool LiveInToA = LIS->isLiveInToMBB(*LR, SuccA);
- bool LiveInToB = LIS->isLiveInToMBB(*LR, SuccB);
+ bool LiveInToA = LV->isLiveIn(Reg, *SuccA);
+ bool LiveInToB = LV->isLiveIn(Reg, *SuccB);
if (!LiveInToA && !LiveInToB) {
DEBUG(dbgs() << PrintReg(Reg, TRI, 0)
// This interval is live in to one successor, but not the other, so
// we need to update its range so it is live in to both.
DEBUG(dbgs() << "Possible SGPR conflict detected for "
- << PrintReg(Reg, TRI, 0) << " in " << *LR
- << " BB#" << SuccA->getNumber() << ", BB#"
- << SuccB->getNumber()
+ << PrintReg(Reg, TRI, 0)
+ << " BB#" << SuccA->getNumber()
+ << ", BB#" << SuccB->getNumber()
<< " with NCD = BB#" << NCD->getNumber() << '\n');
assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
.addReg(Reg, RegState::Implicit);
MadeChange = true;
-
- SlotIndex SI = LIS->InsertMachineInstrInMaps(NCDSGPRUse);
- LIS->extendToIndices(*LR, SI.getRegSlot());
-
- if (LV) {
- // TODO: This won't work post-SSA
- LV->HandleVirtRegUse(Reg, NCD, NCDSGPRUse);
- }
+ LV->HandleVirtRegUse(Reg, NCD, NCDSGPRUse);
DEBUG(NCDSGPRUse->dump());
}