summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorJames Molloy <jmolloy@google.com>2019-09-21 08:19:41 +0000
committerJames Molloy <jmolloy@google.com>2019-09-21 08:19:41 +0000
commit8a74eca398a012a9b3b18b10c2b5aedef203d04b (patch)
treebac9fe17136c243bc191c5d0771329dd14fae0a7 /llvm/lib/CodeGen
parentc90fda6abe84127a99a8fe4341b6ed7c8abee47e (diff)
downloadbcm5719-llvm-8a74eca398a012a9b3b18b10c2b5aedef203d04b.tar.gz
bcm5719-llvm-8a74eca398a012a9b3b18b10c2b5aedef203d04b.zip
[MachinePipeliner] Improve the TargetInstrInfo API analyzeLoop/reduceLoopCount
Recommit: fix asan errors. The way MachinePipeliner uses these target hooks is stateful - we reduce trip count by one per call to reduceLoopCount. It's a little overfit for hardware loops, where we don't have to worry about stitching a loop induction variable across prologs and epilogs (the induction variable is implicit). This patch introduces a new API: /// Analyze loop L, which must be a single-basic-block loop, and if the /// conditions can be understood enough produce a PipelinerLoopInfo object. virtual std::unique_ptr<PipelinerLoopInfo> analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const; The return value is expected to be an implementation of the abstract class: /// Object returned by analyzeLoopForPipelining. Allows software pipelining /// implementations to query attributes of the loop being pipelined. class PipelinerLoopInfo { public: virtual ~PipelinerLoopInfo(); /// Return true if the given instruction should not be pipelined and should /// be ignored. An example could be a loop comparison, or induction variable /// update with no users being pipelined. virtual bool shouldIgnoreForPipelining(const MachineInstr *MI) const = 0; /// Create a condition to determine if the trip count of the loop is greater /// than TC. /// /// If the trip count is statically known to be greater than TC, return /// true. If the trip count is statically known to be not greater than TC, /// return false. Otherwise return nullopt and fill out Cond with the test /// condition. virtual Optional<bool> createTripCountGreaterCondition(int TC, MachineBasicBlock &MBB, SmallVectorImpl<MachineOperand> &Cond) = 0; /// Modify the loop such that the trip count is /// OriginalTC + TripCountAdjust. virtual void adjustTripCount(int TripCountAdjust) = 0; /// Called when the loop's preheader has been modified to NewPreheader. virtual void setPreheader(MachineBasicBlock *NewPreheader) = 0; /// Called when the loop is being removed. virtual void disposed() = 0; }; The Pipeliner (ModuloSchedule.cpp) can use this object to modify the loop while allowing the target to hold its own state across all calls. This API, in particular the disjunction of creating a trip count check condition and adjusting the loop, improves the code quality in ModuloSchedule.cpp. llvm-svn: 372463
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/MachinePipeliner.cpp2
-rw-r--r--llvm/lib/CodeGen/ModuloSchedule.cpp40
-rw-r--r--llvm/lib/CodeGen/TargetInstrInfo.cpp2
3 files changed, 20 insertions, 24 deletions
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index fc16ebf66f5..b3d97c61fda 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -326,7 +326,7 @@ bool MachinePipeliner::canPipelineLoop(MachineLoop &L) {
LI.LoopInductionVar = nullptr;
LI.LoopCompare = nullptr;
- if (TII->analyzeLoop(L, LI.LoopInductionVar, LI.LoopCompare)) {
+ if (!TII->analyzeLoopForPipelining(L.getTopBlock())) {
LLVM_DEBUG(
dbgs() << "Unable to analyzeLoop, can NOT pipeline current Loop\n");
NumFailLoop++;
diff --git a/llvm/lib/CodeGen/ModuloSchedule.cpp b/llvm/lib/CodeGen/ModuloSchedule.cpp
index 8bea4037f54..aa5e86e97d1 100644
--- a/llvm/lib/CodeGen/ModuloSchedule.cpp
+++ b/llvm/lib/CodeGen/ModuloSchedule.cpp
@@ -105,6 +105,9 @@ void ModuloScheduleExpander::expand() {
}
void ModuloScheduleExpander::generatePipelinedLoop() {
+ LoopInfo = TII->analyzeLoopForPipelining(BB);
+ assert(LoopInfo && "Must be able to analyze loop!");
+
// Create a new basic block for the kernel and add it to the CFG.
MachineBasicBlock *KernelBB = MF.CreateMachineBasicBlock(BB->getBasicBlock());
@@ -847,10 +850,6 @@ void ModuloScheduleExpander::addBranches(MachineBasicBlock &PreheaderBB,
MBBVectorTy &EpilogBBs,
ValueMapTy *VRMap) {
assert(PrologBBs.size() == EpilogBBs.size() && "Prolog/Epilog mismatch");
- MachineInstr *IndVar;
- MachineInstr *Cmp;
- if (TII->analyzeLoop(*Schedule.getLoop(), IndVar, Cmp))
- llvm_unreachable("Must be able to analyze loop!");
MachineBasicBlock *LastPro = KernelBB;
MachineBasicBlock *LastEpi = KernelBB;
@@ -858,32 +857,20 @@ void ModuloScheduleExpander::addBranches(MachineBasicBlock &PreheaderBB,
// to the first prolog and the last epilog blocks.
SmallVector<MachineInstr *, 4> PrevInsts;
unsigned MaxIter = PrologBBs.size() - 1;
- unsigned LC = UINT_MAX;
- unsigned LCMin = UINT_MAX;
for (unsigned i = 0, j = MaxIter; i <= MaxIter; ++i, --j) {
// Add branches to the prolog that go to the corresponding
// epilog, and the fall-thru prolog/kernel block.
MachineBasicBlock *Prolog = PrologBBs[j];
MachineBasicBlock *Epilog = EpilogBBs[i];
- // We've executed one iteration, so decrement the loop count and check for
- // the loop end.
- SmallVector<MachineOperand, 4> Cond;
- // Check if the LOOP0 has already been removed. If so, then there is no need
- // to reduce the trip count.
- if (LC != 0)
- LC = TII->reduceLoopCount(*Prolog, PreheaderBB, IndVar, *Cmp, Cond,
- PrevInsts, j, MaxIter);
-
- // Record the value of the first trip count, which is used to determine if
- // branches and blocks can be removed for constant trip counts.
- if (LCMin == UINT_MAX)
- LCMin = LC;
+ SmallVector<MachineOperand, 4> Cond;
+ Optional<bool> StaticallyGreater =
+ LoopInfo->createTripCountGreaterCondition(j + 1, *Prolog, Cond);
unsigned numAdded = 0;
- if (Register::isVirtualRegister(LC)) {
+ if (!StaticallyGreater.hasValue()) {
Prolog->addSuccessor(Epilog);
numAdded = TII->insertBranch(*Prolog, Epilog, LastPro, Cond, DebugLoc());
- } else if (j >= LCMin) {
+ } else if (*StaticallyGreater == false) {
Prolog->addSuccessor(Epilog);
Prolog->removeSuccessor(LastPro);
LastEpi->removeSuccessor(Epilog);
@@ -894,10 +881,12 @@ void ModuloScheduleExpander::addBranches(MachineBasicBlock &PreheaderBB,
LastEpi->clear();
LastEpi->eraseFromParent();
}
+ if (LastPro == KernelBB) {
+ LoopInfo->disposed();
+ NewKernel = nullptr;
+ }
LastPro->clear();
LastPro->eraseFromParent();
- if (LastPro == KernelBB)
- NewKernel = nullptr;
} else {
numAdded = TII->insertBranch(*Prolog, LastPro, nullptr, Cond, DebugLoc());
removePhis(Epilog, Prolog);
@@ -909,6 +898,11 @@ void ModuloScheduleExpander::addBranches(MachineBasicBlock &PreheaderBB,
I != E && numAdded > 0; ++I, --numAdded)
updateInstruction(&*I, false, j, 0, VRMap);
}
+
+ if (NewKernel) {
+ LoopInfo->setPreheader(PrologBBs[MaxIter]);
+ LoopInfo->adjustTripCount(-(MaxIter + 1));
+ }
}
/// Return true if we can compute the amount the instruction changes
diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp
index 0406649345b..11872e13e4f 100644
--- a/llvm/lib/CodeGen/TargetInstrInfo.cpp
+++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp
@@ -1257,3 +1257,5 @@ bool TargetInstrInfo::getInsertSubregInputs(
InsertedReg.SubIdx = (unsigned)MOSubIdx.getImm();
return true;
}
+
+TargetInstrInfo::PipelinerLoopInfo::~PipelinerLoopInfo() {}
OpenPOWER on IntegriCloud