ExecutionDepsFix refactoring:

- clang-format

This is the one of multiple patches that fix bugzilla https://bugs.llvm.org/show_bug.cgi?id=33869
Most of the patches are intended at refactoring the existent code.

Additional relevant reviews:
https://reviews.llvm.org/D40330
https://reviews.llvm.org/D40332
https://reviews.llvm.org/D40333
https://reviews.llvm.org/D40334

Differential Revision: https://reviews.llvm.org/D40331

Change-Id: I131b126af13bc743bc5d69d83699e52b9b720979
llvm-svn: 323093
This commit is contained in:
Marina Yatsina 2018-01-22 10:06:18 +00:00
parent 601fd0ed78
commit 4a883f1d3e
2 changed files with 105 additions and 95 deletions

View File

@ -66,7 +66,7 @@ struct DomainValue {
DomainValue *Next;
/// Twiddleable instructions using or defining these registers.
SmallVector<MachineInstr*, 8> Instrs;
SmallVector<MachineInstr *, 8> Instrs;
DomainValue() { clear(); }
@ -83,14 +83,10 @@ struct DomainValue {
}
/// Mark domain as available.
void addDomain(unsigned domain) {
AvailableDomains |= 1u << domain;
}
void addDomain(unsigned domain) { AvailableDomains |= 1u << domain; }
// Restrict to a single domain available.
void setSingleDomain(unsigned domain) {
AvailableDomains = 1u << domain;
}
void setSingleDomain(unsigned domain) { AvailableDomains = 1u << domain; }
/// Return bitmask of domains that are available and in mask.
unsigned getCommonDomains(unsigned mask) const {
@ -112,20 +108,20 @@ struct DomainValue {
/// This class provides the basic blocks traversal order used by passes like
/// ReachingDefAnalysis and ExecutionDomainFix.
/// It identifies basic blocks that are part of loops and should to be visited twice
/// and returns efficient traversal order for all the blocks.
/// It identifies basic blocks that are part of loops and should to be visited
/// twice and returns efficient traversal order for all the blocks.
///
/// We want to visit every instruction in every basic block in order to update
/// it's execution domain or collect clearance information. However, for the
/// clearance calculation, we need to know clearances from all predecessors
/// (including any backedges), therfore we need to visit some blocks twice.
/// (including any backedges), therfore we need to visit some blocks twice.
/// As an example, consider the following loop.
///
///
///
///
/// PH -> A -> B (xmm<Undef> -> xmm<Def>) -> C -> D -> EXIT
/// ^ |
/// +----------------------------------+
///
///
/// The iteration order this pass will return is as follows:
/// Optimized: PH A B C A' B' C' D
///
@ -172,10 +168,10 @@ public:
struct TraversedMBBInfo {
/// The basic block.
MachineBasicBlock *MBB = nullptr;
/// True if this is the first time we process the basic block.
bool PrimaryPass = true;
/// True if the block that is ready for its final round of processing.
bool IsDone = true;
@ -185,7 +181,7 @@ public:
};
LoopTraversal() {}
/// \brief Identifies basic blocks that are part of loops and should to be
/// \brief Identifies basic blocks that are part of loops and should to be
/// visited twise and returns efficient traversal order for all the blocks.
typedef SmallVector<TraversedMBBInfo, 4> TraversalOrder;
TraversalOrder traverse(MachineFunction &MF);
@ -193,7 +189,6 @@ public:
private:
/// Returens true if the block is ready for its final round of processing.
bool isBlockDone(MachineBasicBlock *MBB);
};
/// This class provides the reaching def analysis.
@ -204,9 +199,9 @@ private:
const TargetRegisterInfo *TRI;
unsigned NumRegUnits;
/// Instruction that defined each register, relative to the beginning of the
/// current basic block. When a LiveRegsDefInfo is used to represent a live-out
/// register, this value is relative to the end of the basic block, so it
/// will be a negative number.
/// current basic block. When a LiveRegsDefInfo is used to represent a
/// live-out register, this value is relative to the end of the basic block,
/// so it will be a negative number.
using LiveRegsDefInfo = std::vector<int>;
LiveRegsDefInfo LiveRegs;
@ -258,7 +253,7 @@ public:
/// Provides the instruction id of the closest reaching def instruction of
/// PhysReg that reaches MI, relative to the begining of MI's basic block.
int getReachingDef(MachineInstr *MI, int PhysReg);
/// Provides the clearance - the number of instructions since the closest
/// reaching def instuction of PhysReg that reaches MI.
int getClearance(MachineInstr *MI, MCPhysReg PhysReg);
@ -280,7 +275,7 @@ private:
class ExecutionDomainFix : public MachineFunctionPass {
SpecificBumpPtrAllocator<DomainValue> Allocator;
SmallVector<DomainValue*,16> Avail;
SmallVector<DomainValue *, 16> Avail;
const TargetRegisterClass *const RC;
MachineFunction *MF;
@ -302,7 +297,7 @@ class ExecutionDomainFix : public MachineFunctionPass {
public:
ExecutionDomainFix(char &PassID, const TargetRegisterClass &RC)
: MachineFunctionPass(PassID), RC(&RC), NumRegs(RC.getNumRegs()) {}
: MachineFunctionPass(PassID), RC(&RC), NumRegs(RC.getNumRegs()) {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
@ -328,21 +323,22 @@ private:
/// Add reference to DV.
DomainValue *retain(DomainValue *DV) {
if (DV) ++DV->Refs;
if (DV)
++DV->Refs;
return DV;
}
/// Release a reference to DV. When the last reference is released,
/// collapse if needed.
void release(DomainValue*);
void release(DomainValue *);
/// Follow the chain of dead DomainValues until a live DomainValue is reached.
/// Update the referenced pointer when necessary.
DomainValue *resolve(DomainValue*&);
DomainValue *resolve(DomainValue *&);
/// Set LiveRegs[rx] = dv, updating reference counts.
void setLiveReg(int rx, DomainValue *DV);
/// Kill register rx, recycle or collapse any DomainValue.
void kill(int rx);
@ -352,19 +348,19 @@ private:
/// Collapse open DomainValue into given domain. If there are multiple
/// registers using dv, they each get a unique collapsed DomainValue.
void collapse(DomainValue *dv, unsigned domain);
/// All instructions and registers in B are moved to A, and B is released.
bool merge(DomainValue *A, DomainValue *B);
/// Set up LiveRegs by merging predecessor live-out values.
void enterBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
/// Update live-out values.
void leaveBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
/// Process he given basic block.
void processBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
/// Visit given insturcion.
bool visitInstr(MachineInstr *);
@ -373,11 +369,11 @@ private:
void processDefs(MachineInstr *, bool Kill);
/// A soft instruction can be changed to work in other domains given by mask.
void visitSoftInstr(MachineInstr*, unsigned mask);
void visitSoftInstr(MachineInstr *, unsigned mask);
/// A hard instruction only works in one domain. All input registers will be
/// forced into that domain.
void visitHardInstr(MachineInstr*, unsigned domain);
void visitHardInstr(MachineInstr *, unsigned domain);
};
class BreakFalseDeps : public MachineFunctionPass {
@ -431,18 +427,18 @@ private:
bool pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
unsigned Pref);
/// \brief Return true to if it makes sense to break dependence on a partial def
/// or undef use.
bool shouldBreakDependence(MachineInstr*, unsigned OpIdx, unsigned Pref);
/// \brief Return true to if it makes sense to break dependence on a partial
/// def or undef use.
bool shouldBreakDependence(MachineInstr *, unsigned OpIdx, unsigned Pref);
/// \brief Break false dependencies on undefined register reads.
/// Walk the block backward computing precise liveness. This is expensive, so we
/// only do it on demand. Note that the occurrence of undefined register reads
/// that should be broken is very rare, but when they occur we may have many in
/// a single block.
void processUndefReads(MachineBasicBlock*);
/// Walk the block backward computing precise liveness. This is expensive, so
/// we only do it on demand. Note that the occurrence of undefined register
/// reads that should be broken is very rare, but when they occur we may have
/// many in a single block.
void processUndefReads(MachineBasicBlock *);
};
} // end namepsace llvm
} // namespace llvm
#endif // LLVM_CODEGEN_EXECUTIONDEPSFIX_H

View File

@ -35,9 +35,8 @@ ExecutionDomainFix::regIndices(unsigned Reg) const {
}
DomainValue *ExecutionDomainFix::alloc(int domain) {
DomainValue *dv = Avail.empty() ?
new(Allocator.Allocate()) DomainValue :
Avail.pop_back_val();
DomainValue *dv = Avail.empty() ? new (Allocator.Allocate()) DomainValue
: Avail.pop_back_val();
if (domain >= 0)
dv->addDomain(domain);
assert(dv->Refs == 0 && "Reference count wasn't cleared");
@ -69,7 +68,8 @@ DomainValue *ExecutionDomainFix::resolve(DomainValue *&DVRef) {
return DV;
// DV has a chain. Find the end.
do DV = DV->Next;
do
DV = DV->Next;
while (DV->Next);
// Update DVRef to point to DV.
@ -166,7 +166,8 @@ void ReachingDefAnalysis::enterBasicBlock(
MachineBasicBlock *MBB = TraversedMBB.MBB;
int MBBNumber = MBB->getNumber();
assert(MBBNumber < MBBReachingDefs.size() && "Unexpected basic block number.");
assert(MBBNumber < MBBReachingDefs.size() &&
"Unexpected basic block number.");
MBBReachingDefs[MBBNumber].resize(NumRegUnits);
// Reset instruction counter in each basic block.
@ -193,10 +194,10 @@ void ReachingDefAnalysis::enterBasicBlock(
}
// Try to coalesce live-out registers from predecessors.
for (MachineBasicBlock* pred : MBB->predecessors()) {
for (MachineBasicBlock *pred : MBB->predecessors()) {
assert(pred->getNumber() < MBBOutRegsInfos.size() &&
"Should have pre-allocated MBBInfos for all MBBs");
const LiveRegsDefInfo& Incoming = MBBOutRegsInfos[pred->getNumber()];
const LiveRegsDefInfo &Incoming = MBBOutRegsInfos[pred->getNumber()];
// Incoming is null if this is a backedge from a BB
// we haven't processed yet
if (Incoming.empty())
@ -205,14 +206,14 @@ void ReachingDefAnalysis::enterBasicBlock(
for (unsigned Unit = 0; Unit != NumRegUnits; ++Unit) {
// Use the most recent predecessor def for each register.
LiveRegs[Unit] = std::max(LiveRegs[Unit], Incoming[Unit]);
if ((LiveRegs[Unit] != ReachingDedDefaultVal))
if ((LiveRegs[Unit] != ReachingDedDefaultVal))
MBBReachingDefs[MBBNumber][Unit].push_back(LiveRegs[Unit]);
}
}
DEBUG(
dbgs() << printMBBReference(*MBB)
<< (!TraversedMBB.IsDone ? ": incomplete\n" : ": all preds known\n"));
DEBUG(dbgs() << printMBBReference(*MBB)
<< (!TraversedMBB.IsDone ? ": incomplete\n"
: ": all preds known\n"));
}
void ExecutionDomainFix::enterBasicBlock(
@ -232,10 +233,10 @@ void ExecutionDomainFix::enterBasicBlock(
}
// Try to coalesce live-out registers from predecessors.
for (MachineBasicBlock* pred : MBB->predecessors()) {
for (MachineBasicBlock *pred : MBB->predecessors()) {
assert(pred->getNumber() < MBBOutRegsInfos.size() &&
"Should have pre-allocated MBBInfos for all MBBs");
LiveRegsDVInfo& Incoming = MBBOutRegsInfos[pred->getNumber()];
"Should have pre-allocated MBBInfos for all MBBs");
LiveRegsDVInfo &Incoming = MBBOutRegsInfos[pred->getNumber()];
// Incoming is null if this is a backedge from a BB
// we haven't processed yet
if (Incoming.empty())
@ -266,16 +267,17 @@ void ExecutionDomainFix::enterBasicBlock(
force(rx, pdv->getFirstDomain());
}
}
DEBUG(
dbgs() << printMBBReference(*MBB)
<< (!TraversedMBB.IsDone ? ": incomplete\n" : ": all preds known\n"));
DEBUG(dbgs() << printMBBReference(*MBB)
<< (!TraversedMBB.IsDone ? ": incomplete\n"
: ": all preds known\n"));
}
void ReachingDefAnalysis::leaveBasicBlock(
const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
assert(!LiveRegs.empty() && "Must enter basic block first.");
int MBBNumber = TraversedMBB.MBB->getNumber();
assert(MBBNumber < MBBOutRegsInfos.size() && "Unexpected basic block number.");
assert(MBBNumber < MBBOutRegsInfos.size() &&
"Unexpected basic block number.");
// Save register clearances at end of MBB - used by enterBasicBlock().
MBBOutRegsInfos[MBBNumber] = LiveRegs;
@ -292,7 +294,8 @@ void ExecutionDomainFix::leaveBasicBlock(
const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
assert(!LiveRegs.empty() && "Must enter basic block first.");
int MBBNumber = TraversedMBB.MBB->getNumber();
assert(MBBNumber < MBBOutRegsInfos.size() && "Unexpected basic block number.");
assert(MBBNumber < MBBOutRegsInfos.size() &&
"Unexpected basic block number.");
// Save register clearances at end of MBB - used by enterBasicBlock().
for (DomainValue *OldLiveReg : MBBOutRegsInfos[MBBNumber]) {
release(OldLiveReg);
@ -314,8 +317,8 @@ bool ExecutionDomainFix::visitInstr(MachineInstr *MI) {
return !DomP.first;
}
bool BreakFalseDeps::pickBestRegisterForUndef(MachineInstr *MI,
unsigned OpIdx, unsigned Pref) {
bool BreakFalseDeps::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
unsigned Pref) {
MachineOperand &MO = MI->getOperand(OpIdx);
assert(MO.isUndef() && "Expected undef machine operand");
@ -388,8 +391,8 @@ void ExecutionDomainFix::processDefs(MachineInstr *MI, bool Kill) {
assert(!MI->isDebugValue() && "Won't process debug values");
const MCInstrDesc &MCID = MI->getDesc();
for (unsigned i = 0,
e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
i != e; ++i) {
e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg())
continue;
@ -410,11 +413,12 @@ void ReachingDefAnalysis::processDefs(MachineInstr *MI) {
assert(!MI->isDebugValue() && "Won't process debug values");
int MBBNumber = MI->getParent()->getNumber();
assert(MBBNumber < MBBReachingDefs.size() && "Unexpected basic block number.");
assert(MBBNumber < MBBReachingDefs.size() &&
"Unexpected basic block number.");
const MCInstrDesc &MCID = MI->getDesc();
for (unsigned i = 0,
e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
i != e; ++i) {
e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.getReg())
continue;
@ -451,8 +455,8 @@ void BreakFalseDeps::processDefs(MachineInstr *MI) {
const MCInstrDesc &MCID = MI->getDesc();
for (unsigned i = 0,
e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
i != e; ++i) {
e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs();
i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.getReg())
continue;
@ -499,9 +503,11 @@ void BreakFalseDeps::processUndefReads(MachineBasicBlock *MBB) {
void ExecutionDomainFix::visitHardInstr(MachineInstr *mi, unsigned domain) {
// Collapse all uses.
for (unsigned i = mi->getDesc().getNumDefs(),
e = mi->getDesc().getNumOperands(); i != e; ++i) {
e = mi->getDesc().getNumOperands();
i != e; ++i) {
MachineOperand &mo = mi->getOperand(i);
if (!mo.isReg()) continue;
if (!mo.isReg())
continue;
for (int rx : regIndices(mo.getReg())) {
force(rx, domain);
}
@ -510,7 +516,8 @@ void ExecutionDomainFix::visitHardInstr(MachineInstr *mi, unsigned domain) {
// Kill all defs and force them.
for (unsigned i = 0, e = mi->getDesc().getNumDefs(); i != e; ++i) {
MachineOperand &mo = mi->getOperand(i);
if (!mo.isReg()) continue;
if (!mo.isReg())
continue;
for (int rx : regIndices(mo.getReg())) {
kill(rx);
force(rx, domain);
@ -527,9 +534,11 @@ void ExecutionDomainFix::visitSoftInstr(MachineInstr *mi, unsigned mask) {
SmallVector<int, 4> used;
if (!LiveRegs.empty())
for (unsigned i = mi->getDesc().getNumDefs(),
e = mi->getDesc().getNumOperands(); i != e; ++i) {
e = mi->getDesc().getNumOperands();
i != e; ++i) {
MachineOperand &mo = mi->getOperand(i);
if (!mo.isReg()) continue;
if (!mo.isReg())
continue;
for (int rx : regIndices(mo.getReg())) {
DomainValue *dv = LiveRegs[rx];
if (dv == nullptr)
@ -541,7 +550,8 @@ void ExecutionDomainFix::visitSoftInstr(MachineInstr *mi, unsigned mask) {
// Restrict available domains to the ones in common with the operand.
// If there are no common domains, we must pay the cross-domain
// penalty for this operand.
if (common) available = common;
if (common)
available = common;
} else if (common)
// Open DomainValue is compatible, save it for merging.
used.push_back(rx);
@ -573,11 +583,11 @@ void ExecutionDomainFix::visitSoftInstr(MachineInstr *mi, unsigned mask) {
}
// Sorted insertion.
// Enables giving priority to the latest domains during merging.
auto I = std::upper_bound(Regs.begin(), Regs.end(), rx,
[&](int LHS, const int RHS) {
return RDA->getReachingDef(mi, RC->getRegister(LHS)) <
RDA->getReachingDef(mi, RC->getRegister(RHS));
});
auto I = std::upper_bound(
Regs.begin(), Regs.end(), rx, [&](int LHS, const int RHS) {
return RDA->getReachingDef(mi, RC->getRegister(LHS)) <
RDA->getReachingDef(mi, RC->getRegister(RHS));
});
Regs.insert(I, rx);
}
@ -618,7 +628,8 @@ void ExecutionDomainFix::visitSoftInstr(MachineInstr *mi, unsigned mask) {
// Finally set all defs and non-collapsed uses to dv. We must iterate through
// all the operators, including imp-def ones.
for (MachineOperand &mo : mi->operands()) {
if (!mo.isReg()) continue;
if (!mo.isReg())
continue;
for (int rx : regIndices(mo.getReg())) {
if (!LiveRegs[rx] || (mo.isDef() && LiveRegs[rx] != dv)) {
kill(rx);
@ -656,7 +667,7 @@ void ReachingDefAnalysis::processBasicBlock(
leaveBasicBlock(TraversedMBB);
}
void BreakFalseDeps::processBasicBlock(MachineBasicBlock* MBB) {
void BreakFalseDeps::processBasicBlock(MachineBasicBlock *MBB) {
UndefReads.clear();
// If this block is not done, it makes little sense to make any decisions
// based on clearance information. We need to make a second pass anyway,
@ -673,17 +684,17 @@ bool LoopTraversal::isBlockDone(MachineBasicBlock *MBB) {
int MBBNumber = MBB->getNumber();
assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number.");
return MBBInfos[MBBNumber].PrimaryCompleted &&
MBBInfos[MBBNumber].IncomingCompleted == MBBInfos[MBBNumber].PrimaryIncoming &&
MBBInfos[MBBNumber].IncomingCompleted ==
MBBInfos[MBBNumber].PrimaryIncoming &&
MBBInfos[MBBNumber].IncomingProcessed == MBB->pred_size();
}
LoopTraversal::TraversalOrder
LoopTraversal::traverse(MachineFunction &MF) {
LoopTraversal::TraversalOrder LoopTraversal::traverse(MachineFunction &MF) {
// Initialize the MMBInfos
MBBInfos.assign(MF.getNumBlockIDs(), MBBInfo());
MachineBasicBlock *Entry = &*MF.begin();
ReversePostOrderTraversal<MachineBasicBlock*> RPOT(Entry);
ReversePostOrderTraversal<MachineBasicBlock *> RPOT(Entry);
SmallVector<MachineBasicBlock *, 4> Workqueue;
SmallVector<TraversedMBBInfo, 4> MBBTraversalOrder;
for (MachineBasicBlock *MBB : RPOT) {
@ -702,7 +713,8 @@ LoopTraversal::traverse(MachineFunction &MF) {
MBBTraversalOrder.push_back(TraversedMBBInfo(ActiveMBB, Primary, Done));
for (MachineBasicBlock *Succ : ActiveMBB->successors()) {
int SuccNumber = Succ->getNumber();
assert(SuccNumber < MBBInfos.size() && "Unexpected basic block number.");
assert(SuccNumber < MBBInfos.size() &&
"Unexpected basic block number.");
if (!isBlockDone(Succ)) {
if (Primary)
MBBInfos[SuccNumber].IncomingProcessed++;
@ -722,8 +734,8 @@ LoopTraversal::traverse(MachineFunction &MF) {
for (MachineBasicBlock *MBB : RPOT) {
if (!isBlockDone(MBB))
MBBTraversalOrder.push_back(TraversedMBBInfo(MBB, false, true));
// Don't update successors here. We'll get to them anyway through this
// loop.
// Don't update successors here. We'll get to them anyway through this
// loop.
}
MBBInfos.clear();
@ -753,7 +765,8 @@ bool ExecutionDomainFix::runOnMachineFunction(MachineFunction &mf) {
break;
}
}
if (!anyregs) return false;
if (!anyregs)
return false;
RDA = &getAnalysis<ReachingDefAnalysis>();
@ -763,8 +776,8 @@ bool ExecutionDomainFix::runOnMachineFunction(MachineFunction &mf) {
// therefore the LiveRegs array.
AliasMap.resize(TRI->getNumRegs());
for (unsigned i = 0, e = RC->getNumRegs(); i != e; ++i)
for (MCRegAliasIterator AI(RC->getRegister(i), TRI, true);
AI.isValid(); ++AI)
for (MCRegAliasIterator AI(RC->getRegister(i), TRI, true); AI.isValid();
++AI)
AliasMap[*AI].push_back(i);
}
@ -778,7 +791,7 @@ bool ExecutionDomainFix::runOnMachineFunction(MachineFunction &mf) {
processBasicBlock(TraversedMBB);
}
for (LiveRegsDVInfo OutLiveRegs: MBBOutRegsInfos) {
for (LiveRegsDVInfo OutLiveRegs : MBBOutRegsInfos) {
for (DomainValue *OutLiveReg : OutLiveRegs) {
if (OutLiveReg)
release(OutLiveReg);
@ -856,7 +869,8 @@ int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, int PhysReg) {
int InstId = InstIds[MI];
int DefRes = ReachingDedDefaultVal;
int MBBNumber = MI->getParent()->getNumber();
assert(MBBNumber < MBBReachingDefs.size() && "Unexpected basic block number.");
assert(MBBNumber < MBBReachingDefs.size() &&
"Unexpected basic block number.");
int LatestDef = ReachingDedDefaultVal;
for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) {
for (int Def : MBBReachingDefs[MBBNumber][*Unit]) {