summaryrefslogtreecommitdiffstats
path: root/llvm/include/llvm/CodeGen/ExecutionDomainFix.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/CodeGen/ExecutionDomainFix.h')
-rw-r--r--llvm/include/llvm/CodeGen/ExecutionDomainFix.h245
1 files changed, 7 insertions, 238 deletions
diff --git a/llvm/include/llvm/CodeGen/ExecutionDomainFix.h b/llvm/include/llvm/CodeGen/ExecutionDomainFix.h
index 51f9ce280da..338c214dd07 100644
--- a/llvm/include/llvm/CodeGen/ExecutionDomainFix.h
+++ b/llvm/include/llvm/CodeGen/ExecutionDomainFix.h
@@ -1,4 +1,4 @@
-//==--- llvm/CodeGen/ExecutionDepsFix.h - Execution Domain Fix -*- C++ -*---==//
+//==-- llvm/CodeGen/ExecutionDomainFix.h - Execution Domain Fix -*- C++ -*--==//
//
// The LLVM Compiler Infrastructure
//
@@ -20,15 +20,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_EXECUTIONDEPSFIX_H
-#define LLVM_CODEGEN_EXECUTIONDEPSFIX_H
+#ifndef LLVM_CODEGEN_EXECUTIONDOMAINFIX_H
+#define LLVM_CODEGEN_EXECUTIONDOMAINFIX_H
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/LoopTraversal.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/CodeGen/ReachingDefAnalysis.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
namespace llvm {
@@ -106,173 +105,6 @@ 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.
-///
-/// 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.
-/// 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
-///
-/// The basic block order is constructed as follows:
-/// Once we finish processing some block, we update the counters in MBBInfos
-/// and re-process any successors that are now 'done'.
-/// We call a block that is ready for its final round of processing `done`
-/// (isBlockDone), e.g. when all predecessor information is known.
-///
-/// Note that a naive traversal order would be to do two complete passes over
-/// all basic blocks/instructions, the first for recording clearances, the
-/// second for updating clearance based on backedges.
-/// However, for functions without backedges, or functions with a lot of
-/// straight-line code, and a small loop, that would be a lot of unnecessary
-/// work (since only the BBs that are part of the loop require two passes).
-///
-/// E.g., the naive iteration order for the above exmple is as follows:
-/// Naive: PH A B C D A' B' C' D'
-///
-/// In the optimized approach we avoid processing D twice, because we
-/// can entirely process the predecessors before getting to D.
-class LoopTraversal {
-private:
- struct MBBInfo {
- /// Whether we have gotten to this block in primary processing yet.
- bool PrimaryCompleted = false;
-
- /// The number of predecessors for which primary processing has completed
- unsigned IncomingProcessed = 0;
-
- /// The value of `IncomingProcessed` at the start of primary processing
- unsigned PrimaryIncoming = 0;
-
- /// The number of predecessors for which all processing steps are done.
- unsigned IncomingCompleted = 0;
-
- MBBInfo() = default;
- };
- using MBBInfoMap = SmallVector<MBBInfo, 4>;
- /// Helps keep track if we proccessed this block and all its predecessors.
- MBBInfoMap MBBInfos;
-
-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;
-
- TraversedMBBInfo(MachineBasicBlock *BB = nullptr, bool Primary = true,
- bool Done = true)
- : MBB(BB), PrimaryPass(Primary), IsDone(Done) {}
- };
- LoopTraversal() {}
-
- /// \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.
-class ReachingDefAnalysis : public MachineFunctionPass {
-private:
- MachineFunction *MF;
- const TargetInstrInfo *TII;
- 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.
- using LiveRegsDefInfo = std::vector<int>;
- LiveRegsDefInfo LiveRegs;
-
- /// Keeps clearance information for all registers. Note that this
- /// is different from the usual definition notion of liveness. The CPU
- /// doesn't care whether or not we consider a register killed.
- using OutRegsInfoMap = SmallVector<LiveRegsDefInfo, 4>;
- OutRegsInfoMap MBBOutRegsInfos;
-
- /// Current instruction number.
- /// The first instruction in each basic block is 0.
- int CurInstr;
-
- /// Maps instructions to their instruction Ids, relative to the begining of
- /// their basic blocks.
- DenseMap<MachineInstr *, int> InstIds;
-
- /// All reaching defs of a given RegUnit for a given MBB.
- using MBBRegUnitDefs = SmallVector<int, 1>;
- /// All reaching defs of all reg units for a given MBB
- using MBBDefsInfo = std::vector<MBBRegUnitDefs>;
- /// All reaching defs of all reg units for a all MBBs
- using MBBReachingDefsInfo = SmallVector<MBBDefsInfo, 4>;
- MBBReachingDefsInfo MBBReachingDefs;
-
- /// Default values are 'nothing happened a long time ago'.
- const int ReachingDedDefaultVal = -(1 << 20);
-
-public:
- static char ID; // Pass identification, replacement for typeid
-
- ReachingDefAnalysis() : MachineFunctionPass(ID) {
- initializeReachingDefAnalysisPass(*PassRegistry::getPassRegistry());
- }
- void releaseMemory() override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- MachineFunctionProperties getRequiredProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::NoVRegs);
- }
-
- /// 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);
-
-private:
- /// 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);
-
- /// Update def-ages for registers defined by MI.
- /// Also break dependencies on partial defs and undef uses.
- void processDefs(MachineInstr *);
-};
-
class ExecutionDomainFix : public MachineFunctionPass {
SpecificBumpPtrAllocator<DomainValue> Allocator;
SmallVector<DomainValue *, 16> Avail;
@@ -376,69 +208,6 @@ private:
void visitHardInstr(MachineInstr *, unsigned domain);
};
-class BreakFalseDeps : public MachineFunctionPass {
-private:
- MachineFunction *MF;
- const TargetInstrInfo *TII;
- const TargetRegisterInfo *TRI;
- RegisterClassInfo RegClassInfo;
-
- /// List of undefined register reads in this block in forward order.
- std::vector<std::pair<MachineInstr *, unsigned>> UndefReads;
-
- /// Storage for register unit liveness.
- LivePhysRegs LiveRegSet;
-
- ReachingDefAnalysis *RDA;
-
-public:
- static char ID; // Pass identification, replacement for typeid
-
- BreakFalseDeps() : MachineFunctionPass(ID) {
- initializeBreakFalseDepsPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired<ReachingDefAnalysis>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- MachineFunctionProperties getRequiredProperties() const override {
- return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::NoVRegs);
- }
-
-private:
- /// Process he given basic block.
- void processBasicBlock(MachineBasicBlock *MBB);
-
- /// Update def-ages for registers defined by MI.
- /// Also break dependencies on partial defs and undef uses.
- void processDefs(MachineInstr *MI);
-
- /// \brief Helps avoid false dependencies on undef registers by updating the
- /// machine instructions' undef operand to use a register that the instruction
- /// is truly dependent on, or use a register with clearance higher than Pref.
- /// Returns true if it was able to find a true dependency, thus not requiring
- /// a dependency breaking instruction regardless of clearance.
- 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 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 *);
-};
-
} // namespace llvm
-#endif // LLVM_CODEGEN_EXECUTIONDEPSFIX_H
+#endif // LLVM_CODEGEN_EXECUTIONDOMAINFIX_H
OpenPOWER on IntegriCloud