CodeGen: Use MachineInstr& in AntiDepBreaker API, NFC

Take parameters as MachineInstr& instead of MachineInstr* in
AntiDepBreaker API, since these are required to be non-null.  No
functionality change intended.  Looking toward PR26753.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@262145 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2016-02-27 19:33:37 +00:00
parent d7b3cd7a4e
commit a26cd9c5ba
6 changed files with 88 additions and 91 deletions

View File

@ -180,7 +180,7 @@ void AggressiveAntiDepBreaker::FinishBlock() {
State = nullptr; State = nullptr;
} }
void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, void AggressiveAntiDepBreaker::Observe(MachineInstr &MI, unsigned Count,
unsigned InsertPosIndex) { unsigned InsertPosIndex) {
assert(Count < InsertPosIndex && "Instruction index out of expected range!"); assert(Count < InsertPosIndex && "Instruction index out of expected range!");
@ -190,7 +190,7 @@ void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
ScanInstruction(MI, Count); ScanInstruction(MI, Count);
DEBUG(dbgs() << "Observe: "); DEBUG(dbgs() << "Observe: ");
DEBUG(MI->dump()); DEBUG(MI.dump());
DEBUG(dbgs() << "\tRegs:"); DEBUG(dbgs() << "\tRegs:");
std::vector<unsigned> &DefIndices = State->GetDefIndices(); std::vector<unsigned> &DefIndices = State->GetDefIndices();
@ -214,9 +214,8 @@ void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
DEBUG(dbgs() << '\n'); DEBUG(dbgs() << '\n');
} }
bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI, bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr &MI,
MachineOperand& MO) MachineOperand &MO) {
{
if (!MO.isReg() || !MO.isImplicit()) if (!MO.isReg() || !MO.isImplicit())
return false; return false;
@ -226,19 +225,19 @@ bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI,
MachineOperand *Op = nullptr; MachineOperand *Op = nullptr;
if (MO.isDef()) if (MO.isDef())
Op = MI->findRegisterUseOperand(Reg, true); Op = MI.findRegisterUseOperand(Reg, true);
else else
Op = MI->findRegisterDefOperand(Reg); Op = MI.findRegisterDefOperand(Reg);
return(Op && Op->isImplicit()); return(Op && Op->isImplicit());
} }
void AggressiveAntiDepBreaker::GetPassthruRegs(MachineInstr *MI, void AggressiveAntiDepBreaker::GetPassthruRegs(
std::set<unsigned>& PassthruRegs) { MachineInstr &MI, std::set<unsigned> &PassthruRegs) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg()) continue; if (!MO.isReg()) continue;
if ((MO.isDef() && MI->isRegTiedToUseOperand(i)) || if ((MO.isDef() && MI.isRegTiedToUseOperand(i)) ||
IsImplicitDefUse(MI, MO)) { IsImplicitDefUse(MI, MO)) {
const unsigned Reg = MO.getReg(); const unsigned Reg = MO.getReg();
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true); for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
@ -332,9 +331,8 @@ void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,
DEBUG(if (!header && footer) dbgs() << footer); DEBUG(if (!header && footer) dbgs() << footer);
} }
void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, void AggressiveAntiDepBreaker::PrescanInstruction(
unsigned Count, MachineInstr &MI, unsigned Count, std::set<unsigned> &PassthruRegs) {
std::set<unsigned>& PassthruRegs) {
std::vector<unsigned> &DefIndices = State->GetDefIndices(); std::vector<unsigned> &DefIndices = State->GetDefIndices();
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
RegRefs = State->GetRegRefs(); RegRefs = State->GetRegRefs();
@ -344,8 +342,8 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
// dead, or because only a subregister is live at the def. If we // dead, or because only a subregister is live at the def. If we
// don't do this the dead def will be incorrectly merged into the // don't do this the dead def will be incorrectly merged into the
// previous def. // previous def.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isDef()) continue; if (!MO.isReg() || !MO.isDef()) continue;
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (Reg == 0) continue; if (Reg == 0) continue;
@ -354,8 +352,8 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
} }
DEBUG(dbgs() << "\tDef Groups:"); DEBUG(dbgs() << "\tDef Groups:");
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isDef()) continue; if (!MO.isReg() || !MO.isDef()) continue;
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (Reg == 0) continue; if (Reg == 0) continue;
@ -367,8 +365,8 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
// defined in a call must not be changed (ABI). Inline assembly may // defined in a call must not be changed (ABI). Inline assembly may
// reference either system calls or the register directly. Skip it until we // reference either system calls or the register directly. Skip it until we
// can tell user specified registers from compiler-specified. // can tell user specified registers from compiler-specified.
if (MI->isCall() || MI->hasExtraDefRegAllocReq() || if (MI.isCall() || MI.hasExtraDefRegAllocReq() || TII->isPredicated(MI) ||
TII->isPredicated(*MI) || MI->isInlineAsm()) { MI.isInlineAsm()) {
DEBUG(if (State->GetGroup(Reg) != 0) dbgs() << "->g0(alloc-req)"); DEBUG(if (State->GetGroup(Reg) != 0) dbgs() << "->g0(alloc-req)");
State->UnionGroups(Reg, 0); State->UnionGroups(Reg, 0);
} }
@ -386,8 +384,8 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
// Note register reference... // Note register reference...
const TargetRegisterClass *RC = nullptr; const TargetRegisterClass *RC = nullptr;
if (i < MI->getDesc().getNumOperands()) if (i < MI.getDesc().getNumOperands())
RC = TII->getRegClass(MI->getDesc(), i, TRI, MF); RC = TII->getRegClass(MI.getDesc(), i, TRI, MF);
AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; AggressiveAntiDepState::RegisterReference RR = { &MO, RC };
RegRefs.insert(std::make_pair(Reg, RR)); RegRefs.insert(std::make_pair(Reg, RR));
} }
@ -396,13 +394,13 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
// Scan the register defs for this instruction and update // Scan the register defs for this instruction and update
// live-ranges. // live-ranges.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isDef()) continue; if (!MO.isReg() || !MO.isDef()) continue;
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (Reg == 0) continue; if (Reg == 0) continue;
// Ignore KILLs and passthru registers for liveness... // Ignore KILLs and passthru registers for liveness...
if (MI->isKill() || (PassthruRegs.count(Reg) != 0)) if (MI.isKill() || (PassthruRegs.count(Reg) != 0))
continue; continue;
// Update def for Reg and aliases. // Update def for Reg and aliases.
@ -421,7 +419,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
} }
} }
void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr &MI,
unsigned Count) { unsigned Count) {
DEBUG(dbgs() << "\tUse Groups:"); DEBUG(dbgs() << "\tUse Groups:");
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
@ -444,13 +442,13 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
// instruction which may not be executed. The second R6 def may or may not // instruction which may not be executed. The second R6 def may or may not
// re-define R6 so it's not safe to change it since the last R6 use cannot be // re-define R6 so it's not safe to change it since the last R6 use cannot be
// changed. // changed.
bool Special = MI->isCall() || MI->hasExtraSrcRegAllocReq() || bool Special = MI.isCall() || MI.hasExtraSrcRegAllocReq() ||
TII->isPredicated(*MI) || MI->isInlineAsm(); TII->isPredicated(MI) || MI.isInlineAsm();
// Scan the register uses for this instruction and update // Scan the register uses for this instruction and update
// live-ranges, groups and RegRefs. // live-ranges, groups and RegRefs.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isUse()) continue; if (!MO.isReg() || !MO.isUse()) continue;
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (Reg == 0) continue; if (Reg == 0) continue;
@ -470,8 +468,8 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
// Note register reference... // Note register reference...
const TargetRegisterClass *RC = nullptr; const TargetRegisterClass *RC = nullptr;
if (i < MI->getDesc().getNumOperands()) if (i < MI.getDesc().getNumOperands())
RC = TII->getRegClass(MI->getDesc(), i, TRI, MF); RC = TII->getRegClass(MI.getDesc(), i, TRI, MF);
AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; AggressiveAntiDepState::RegisterReference RR = { &MO, RC };
RegRefs.insert(std::make_pair(Reg, RR)); RegRefs.insert(std::make_pair(Reg, RR));
} }
@ -480,12 +478,12 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
// Form a group of all defs and uses of a KILL instruction to ensure // Form a group of all defs and uses of a KILL instruction to ensure
// that all registers are renamed as a group. // that all registers are renamed as a group.
if (MI->isKill()) { if (MI.isKill()) {
DEBUG(dbgs() << "\tKill Group:"); DEBUG(dbgs() << "\tKill Group:");
unsigned FirstReg = 0; unsigned FirstReg = 0;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg()) continue; if (!MO.isReg()) continue;
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (Reg == 0) continue; if (Reg == 0) continue;
@ -793,13 +791,13 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
unsigned Count = InsertPosIndex - 1; unsigned Count = InsertPosIndex - 1;
for (MachineBasicBlock::iterator I = End, E = Begin; for (MachineBasicBlock::iterator I = End, E = Begin;
I != E; --Count) { I != E; --Count) {
MachineInstr *MI = --I; MachineInstr &MI = *--I;
if (MI->isDebugValue()) if (MI.isDebugValue())
continue; continue;
DEBUG(dbgs() << "Anti: "); DEBUG(dbgs() << "Anti: ");
DEBUG(MI->dump()); DEBUG(MI.dump());
std::set<unsigned> PassthruRegs; std::set<unsigned> PassthruRegs;
GetPassthruRegs(MI, PassthruRegs); GetPassthruRegs(MI, PassthruRegs);
@ -810,13 +808,13 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
// The dependence edges that represent anti- and output- // The dependence edges that represent anti- and output-
// dependencies that are candidates for breaking. // dependencies that are candidates for breaking.
std::vector<const SDep *> Edges; std::vector<const SDep *> Edges;
const SUnit *PathSU = MISUnitMap[MI]; const SUnit *PathSU = MISUnitMap[&MI];
AntiDepEdges(PathSU, Edges); AntiDepEdges(PathSU, Edges);
// If MI is not on the critical path, then we don't rename // If MI is not on the critical path, then we don't rename
// registers in the CriticalPathSet. // registers in the CriticalPathSet.
BitVector *ExcludeRegs = nullptr; BitVector *ExcludeRegs = nullptr;
if (MI == CriticalPathMI) { if (&MI == CriticalPathMI) {
CriticalPathSU = CriticalPathStep(CriticalPathSU); CriticalPathSU = CriticalPathStep(CriticalPathSU);
CriticalPathMI = (CriticalPathSU) ? CriticalPathSU->getInstr() : nullptr; CriticalPathMI = (CriticalPathSU) ? CriticalPathSU->getInstr() : nullptr;
} else if (CriticalPathSet.any()) { } else if (CriticalPathSet.any()) {
@ -825,7 +823,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
// Ignore KILL instructions (they form a group in ScanInstruction // Ignore KILL instructions (they form a group in ScanInstruction
// but don't cause any anti-dependence breaking themselves) // but don't cause any anti-dependence breaking themselves)
if (!MI->isKill()) { if (!MI.isKill()) {
// Attempt to break each anti-dependency... // Attempt to break each anti-dependency...
for (unsigned i = 0, e = Edges.size(); i != e; ++i) { for (unsigned i = 0, e = Edges.size(); i != e; ++i) {
const SDep *Edge = Edges[i]; const SDep *Edge = Edges[i];
@ -855,7 +853,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
continue; continue;
} else { } else {
// No anti-dep breaking for implicit deps // No anti-dep breaking for implicit deps
MachineOperand *AntiDepOp = MI->findRegisterDefOperand(AntiDepReg); MachineOperand *AntiDepOp = MI.findRegisterDefOperand(AntiDepReg);
assert(AntiDepOp && "Can't find index for defined register operand"); assert(AntiDepOp && "Can't find index for defined register operand");
if (!AntiDepOp || AntiDepOp->isImplicit()) { if (!AntiDepOp || AntiDepOp->isImplicit()) {
DEBUG(dbgs() << " (implicit)\n"); DEBUG(dbgs() << " (implicit)\n");
@ -939,7 +937,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
for (DbgValueVector::iterator DVI = DbgValues.begin(), for (DbgValueVector::iterator DVI = DbgValues.begin(),
DVE = DbgValues.end(); DVI != DVE; ++DVI) DVE = DbgValues.end(); DVI != DVE; ++DVI)
if (DVI->second == Q.second.Operand->getParent()) if (DVI->second == Q.second.Operand->getParent())
UpdateDbgValue(DVI->first, AntiDepReg, NewReg); UpdateDbgValue(*DVI->first, AntiDepReg, NewReg);
} }
// We just went back in time and modified history; the // We just went back in time and modified history; the

View File

@ -144,7 +144,7 @@ class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepState {
/// Update liveness information to account for the current /// Update liveness information to account for the current
/// instruction, which will not be scheduled. /// instruction, which will not be scheduled.
/// ///
void Observe(MachineInstr *MI, unsigned Count, void Observe(MachineInstr &MI, unsigned Count,
unsigned InsertPosIndex) override; unsigned InsertPosIndex) override;
/// Finish anti-dep breaking for a basic block. /// Finish anti-dep breaking for a basic block.
@ -156,19 +156,19 @@ class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepState {
/// Return true if MO represents a register /// Return true if MO represents a register
/// that is both implicitly used and defined in MI /// that is both implicitly used and defined in MI
bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO); bool IsImplicitDefUse(MachineInstr &MI, MachineOperand &MO);
/// If MI implicitly def/uses a register, then /// If MI implicitly def/uses a register, then
/// return that register and all subregisters. /// return that register and all subregisters.
void GetPassthruRegs(MachineInstr *MI, std::set<unsigned>& PassthruRegs); void GetPassthruRegs(MachineInstr &MI, std::set<unsigned> &PassthruRegs);
void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag, void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag,
const char *header = nullptr, const char *header = nullptr,
const char *footer = nullptr); const char *footer = nullptr);
void PrescanInstruction(MachineInstr *MI, unsigned Count, void PrescanInstruction(MachineInstr &MI, unsigned Count,
std::set<unsigned>& PassthruRegs); std::set<unsigned> &PassthruRegs);
void ScanInstruction(MachineInstr *MI, unsigned Count); void ScanInstruction(MachineInstr &MI, unsigned Count);
BitVector GetRenameRegisters(unsigned Reg); BitVector GetRenameRegisters(unsigned Reg);
bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex, bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex,
RenameOrderType& RenameOrder, RenameOrderType& RenameOrder,

View File

@ -47,19 +47,18 @@ public:
/// Update liveness information to account for the current /// Update liveness information to account for the current
/// instruction, which will not be scheduled. /// instruction, which will not be scheduled.
virtual void Observe(MachineInstr *MI, unsigned Count, virtual void Observe(MachineInstr &MI, unsigned Count,
unsigned InsertPosIndex) =0; unsigned InsertPosIndex) = 0;
/// Finish anti-dep breaking for a basic block. /// Finish anti-dep breaking for a basic block.
virtual void FinishBlock() =0; virtual void FinishBlock() =0;
/// Update DBG_VALUE if dependency breaker is updating /// Update DBG_VALUE if dependency breaker is updating
/// other machine instruction to use NewReg. /// other machine instruction to use NewReg.
void UpdateDbgValue(MachineInstr *MI, unsigned OldReg, unsigned NewReg) { void UpdateDbgValue(MachineInstr &MI, unsigned OldReg, unsigned NewReg) {
assert(MI && "Expected valid instruction"); assert(MI.isDebugValue() && "MI is not DBG_VALUE!");
assert (MI->isDebugValue() && "MI is not DBG_VALUE!"); if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg() == OldReg)
if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg() == OldReg) MI.getOperand(0).setReg(NewReg);
MI->getOperand(0).setReg(NewReg);
} }
}; };

View File

@ -87,7 +87,7 @@ void CriticalAntiDepBreaker::FinishBlock() {
KeepRegs.reset(); KeepRegs.reset();
} }
void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, void CriticalAntiDepBreaker::Observe(MachineInstr &MI, unsigned Count,
unsigned InsertPosIndex) { unsigned InsertPosIndex) {
// Kill instructions can define registers but are really nops, and there might // Kill instructions can define registers but are really nops, and there might
// be a real definition earlier that needs to be paired with uses dominated by // be a real definition earlier that needs to be paired with uses dominated by
@ -96,7 +96,7 @@ void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
// FIXME: It may be possible to remove the isKill() restriction once PR18663 // FIXME: It may be possible to remove the isKill() restriction once PR18663
// has been properly fixed. There can be value in processing kills as seen in // has been properly fixed. There can be value in processing kills as seen in
// the AggressiveAntiDepBreaker class. // the AggressiveAntiDepBreaker class.
if (MI->isDebugValue() || MI->isKill()) if (MI.isDebugValue() || MI.isKill())
return; return;
assert(Count < InsertPosIndex && "Instruction index out of expected range!"); assert(Count < InsertPosIndex && "Instruction index out of expected range!");
@ -146,7 +146,7 @@ static const SDep *CriticalPathStep(const SUnit *SU) {
return Next; return Next;
} }
void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) { void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr &MI) {
// It's not safe to change register allocation for source operands of // It's not safe to change register allocation for source operands of
// instructions that have special allocation requirements. Also assume all // instructions that have special allocation requirements. Also assume all
// registers used in a call must not be changed (ABI). // registers used in a call must not be changed (ABI).
@ -164,19 +164,19 @@ void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) {
// re-define R6 so it's not safe to change it since the last R6 use cannot be // re-define R6 so it's not safe to change it since the last R6 use cannot be
// changed. // changed.
bool Special = bool Special =
MI->isCall() || MI->hasExtraSrcRegAllocReq() || TII->isPredicated(*MI); MI.isCall() || MI.hasExtraSrcRegAllocReq() || TII->isPredicated(MI);
// Scan the register operands for this instruction and update // Scan the register operands for this instruction and update
// Classes and RegRefs. // Classes and RegRefs.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg()) continue; if (!MO.isReg()) continue;
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (Reg == 0) continue; if (Reg == 0) continue;
const TargetRegisterClass *NewRC = nullptr; const TargetRegisterClass *NewRC = nullptr;
if (i < MI->getDesc().getNumOperands()) if (i < MI.getDesc().getNumOperands())
NewRC = TII->getRegClass(MI->getDesc(), i, TRI, MF); NewRC = TII->getRegClass(MI.getDesc(), i, TRI, MF);
// For now, only allow the register to be changed if its register // For now, only allow the register to be changed if its register
// class is consistent across all uses. // class is consistent across all uses.
@ -211,7 +211,7 @@ void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) {
// of a register? In the above 'xor' example, the uses of %eax are undef, so // of a register? In the above 'xor' example, the uses of %eax are undef, so
// earlier instructions could still replace %eax even though the 'xor' // earlier instructions could still replace %eax even though the 'xor'
// itself can't be changed. // itself can't be changed.
if (MI->isRegTiedToUseOperand(i) && if (MI.isRegTiedToUseOperand(i) &&
Classes[Reg] == reinterpret_cast<TargetRegisterClass *>(-1)) { Classes[Reg] == reinterpret_cast<TargetRegisterClass *>(-1)) {
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true); for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs) { SubRegs.isValid(); ++SubRegs) {
@ -233,18 +233,17 @@ void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) {
} }
} }
void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, void CriticalAntiDepBreaker::ScanInstruction(MachineInstr &MI, unsigned Count) {
unsigned Count) {
// Update liveness. // Update liveness.
// Proceeding upwards, registers that are defed but not used in this // Proceeding upwards, registers that are defed but not used in this
// instruction are now dead. // instruction are now dead.
assert(!MI->isKill() && "Attempting to scan a kill instruction"); assert(!MI.isKill() && "Attempting to scan a kill instruction");
if (!TII->isPredicated(*MI)) { if (!TII->isPredicated(MI)) {
// Predicated defs are modeled as read + write, i.e. similar to two // Predicated defs are modeled as read + write, i.e. similar to two
// address updates. // address updates.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (MO.isRegMask()) if (MO.isRegMask())
for (unsigned i = 0, e = TRI->getNumRegs(); i != e; ++i) for (unsigned i = 0, e = TRI->getNumRegs(); i != e; ++i)
@ -265,7 +264,8 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI,
if (KeepRegs.test(Reg)) continue; if (KeepRegs.test(Reg)) continue;
// Ignore two-addr defs. // Ignore two-addr defs.
if (MI->isRegTiedToUseOperand(i)) continue; if (MI.isRegTiedToUseOperand(i))
continue;
// For the reg itself and all subregs: update the def to current; // For the reg itself and all subregs: update the def to current;
// reset the kill state, any restrictions, and references. // reset the kill state, any restrictions, and references.
@ -282,16 +282,16 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI,
Classes[*SR] = reinterpret_cast<TargetRegisterClass *>(-1); Classes[*SR] = reinterpret_cast<TargetRegisterClass *>(-1);
} }
} }
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg()) continue; if (!MO.isReg()) continue;
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (Reg == 0) continue; if (Reg == 0) continue;
if (!MO.isUse()) continue; if (!MO.isUse()) continue;
const TargetRegisterClass *NewRC = nullptr; const TargetRegisterClass *NewRC = nullptr;
if (i < MI->getDesc().getNumOperands()) if (i < MI.getDesc().getNumOperands())
NewRC = TII->getRegClass(MI->getDesc(), i, TRI, MF); NewRC = TII->getRegClass(MI.getDesc(), i, TRI, MF);
// For now, only allow the register to be changed if its register // For now, only allow the register to be changed if its register
// class is consistent across all uses. // class is consistent across all uses.
@ -509,7 +509,7 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
unsigned Broken = 0; unsigned Broken = 0;
unsigned Count = InsertPosIndex - 1; unsigned Count = InsertPosIndex - 1;
for (MachineBasicBlock::iterator I = End, E = Begin; I != E; --Count) { for (MachineBasicBlock::iterator I = End, E = Begin; I != E; --Count) {
MachineInstr *MI = --I; MachineInstr &MI = *--I;
// Kill instructions can define registers but are really nops, and there // Kill instructions can define registers but are really nops, and there
// might be a real definition earlier that needs to be paired with uses // might be a real definition earlier that needs to be paired with uses
// dominated by this kill. // dominated by this kill.
@ -517,7 +517,7 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
// FIXME: It may be possible to remove the isKill() restriction once PR18663 // FIXME: It may be possible to remove the isKill() restriction once PR18663
// has been properly fixed. There can be value in processing kills as seen // has been properly fixed. There can be value in processing kills as seen
// in the AggressiveAntiDepBreaker class. // in the AggressiveAntiDepBreaker class.
if (MI->isDebugValue() || MI->isKill()) if (MI.isDebugValue() || MI.isKill())
continue; continue;
// Check if this instruction has a dependence on the critical path that // Check if this instruction has a dependence on the critical path that
@ -534,7 +534,7 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
// edge per instruction. Note that we'd have to be able to break all of // edge per instruction. Note that we'd have to be able to break all of
// the anti-dependencies in an instruction in order to be effective. // the anti-dependencies in an instruction in order to be effective.
unsigned AntiDepReg = 0; unsigned AntiDepReg = 0;
if (MI == CriticalPathMI) { if (&MI == CriticalPathMI) {
if (const SDep *Edge = CriticalPathStep(CriticalPathSU)) { if (const SDep *Edge = CriticalPathStep(CriticalPathSU)) {
const SUnit *NextSU = Edge->getSUnit(); const SUnit *NextSU = Edge->getSUnit();
@ -584,7 +584,7 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
// If MI's defs have a special allocation requirement, don't allow // If MI's defs have a special allocation requirement, don't allow
// any def registers to be changed. Also assume all registers // any def registers to be changed. Also assume all registers
// defined in a call must not be changed (ABI). // defined in a call must not be changed (ABI).
if (MI->isCall() || MI->hasExtraDefRegAllocReq() || TII->isPredicated(*MI)) if (MI.isCall() || MI.hasExtraDefRegAllocReq() || TII->isPredicated(MI))
// If this instruction's defs have special allocation requirement, don't // If this instruction's defs have special allocation requirement, don't
// break this anti-dependency. // break this anti-dependency.
AntiDepReg = 0; AntiDepReg = 0;
@ -593,8 +593,8 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
// is invalid. If the instruction defines other registers, // is invalid. If the instruction defines other registers,
// save a list of them so that we don't pick a new register // save a list of them so that we don't pick a new register
// that overlaps any of them. // that overlaps any of them.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i); MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg()) continue; if (!MO.isReg()) continue;
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (Reg == 0) continue; if (Reg == 0) continue;
@ -646,7 +646,7 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
for (DbgValueVector::iterator DVI = DbgValues.begin(), for (DbgValueVector::iterator DVI = DbgValues.begin(),
DVE = DbgValues.end(); DVI != DVE; ++DVI) DVE = DbgValues.end(); DVI != DVE; ++DVI)
if (DVI->second == Q->second->getParent()) if (DVI->second == Q->second->getParent())
UpdateDbgValue(DVI->first, AntiDepReg, NewReg); UpdateDbgValue(*DVI->first, AntiDepReg, NewReg);
} }
// We just went back in time and modified history; the // We just went back in time and modified history; the

View File

@ -84,15 +84,15 @@ class LLVM_LIBRARY_VISIBILITY CriticalAntiDepBreaker : public AntiDepBreaker {
/// Update liveness information to account for the current /// Update liveness information to account for the current
/// instruction, which will not be scheduled. /// instruction, which will not be scheduled.
void Observe(MachineInstr *MI, unsigned Count, void Observe(MachineInstr &MI, unsigned Count,
unsigned InsertPosIndex) override; unsigned InsertPosIndex) override;
/// Finish anti-dep breaking for a basic block. /// Finish anti-dep breaking for a basic block.
void FinishBlock() override; void FinishBlock() override;
private: private:
void PrescanInstruction(MachineInstr *MI); void PrescanInstruction(MachineInstr &MI);
void ScanInstruction(MachineInstr *MI, unsigned Count); void ScanInstruction(MachineInstr &MI, unsigned Count);
bool isNewRegClobberedByRefs(RegRefIter RegRefBegin, bool isNewRegClobberedByRefs(RegRefIter RegRefBegin,
RegRefIter RegRefEnd, RegRefIter RegRefEnd,
unsigned NewReg); unsigned NewReg);

View File

@ -169,7 +169,7 @@ namespace {
/// Observe - Update liveness information to account for the current /// Observe - Update liveness information to account for the current
/// instruction, which will not be scheduled. /// instruction, which will not be scheduled.
/// ///
void Observe(MachineInstr *MI, unsigned Count); void Observe(MachineInstr &MI, unsigned Count);
/// finishBlock - Clean up register live-range state. /// finishBlock - Clean up register live-range state.
/// ///
@ -335,7 +335,7 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
Scheduler.EmitSchedule(); Scheduler.EmitSchedule();
Current = MI; Current = MI;
CurrentCount = Count; CurrentCount = Count;
Scheduler.Observe(MI, CurrentCount); Scheduler.Observe(*MI, CurrentCount);
} }
I = MI; I = MI;
if (MI->isBundle()) if (MI->isBundle())
@ -414,7 +414,7 @@ void SchedulePostRATDList::schedule() {
/// Observe - Update liveness information to account for the current /// Observe - Update liveness information to account for the current
/// instruction, which will not be scheduled. /// instruction, which will not be scheduled.
/// ///
void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { void SchedulePostRATDList::Observe(MachineInstr &MI, unsigned Count) {
if (AntiDepBreak) if (AntiDepBreak)
AntiDepBreak->Observe(MI, Count, EndIndex); AntiDepBreak->Observe(MI, Count, EndIndex);
} }