DomainValue *Next;
/// Twiddleable instructions using or defining these registers.
- SmallVector<MachineInstr*, 8> Instrs;
+ SmallVector<MachineInstr *, 8> Instrs;
DomainValue() { clear(); }
}
/// 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 {
/// 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
///
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;
};
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);
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.
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;
/// 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);
class ExecutionDomainFix : public MachineFunctionPass {
SpecificBumpPtrAllocator<DomainValue> Allocator;
- SmallVector<DomainValue*,16> Avail;
+ SmallVector<DomainValue *, 16> Avail;
const TargetRegisterClass *const RC;
MachineFunction *MF;
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();
/// 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);
/// 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 *);
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 {
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
}
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");
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.
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.
}
// 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())
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(
}
// 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())
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;
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);
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");
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;
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;
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;
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);
}
// 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);
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)
// 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);
}
// 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);
}
// 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);
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,
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) {
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++;
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();
break;
}
}
- if (!anyregs) return false;
+ if (!anyregs)
+ return false;
RDA = &getAnalysis<ReachingDefAnalysis>();
// 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);
}
processBasicBlock(TraversedMBB);
}
- for (LiveRegsDVInfo OutLiveRegs: MBBOutRegsInfos) {
+ for (LiveRegsDVInfo OutLiveRegs : MBBOutRegsInfos) {
for (DomainValue *OutLiveReg : OutLiveRegs) {
if (OutLiveReg)
release(OutLiveReg);
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]) {