Skip to content

Commit fa49021

Browse files
committed
Revert "[CodeGen][ARM] Enable Swing Module Scheduling for ARM"
This reverts commit 28d09bb while I investigate a buildbot failure.
1 parent ab17ed0 commit fa49021

File tree

13 files changed

+19
-629
lines changed

13 files changed

+19
-629
lines changed

llvm/include/llvm/CodeGen/MachinePipeliner.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ class MachinePipeliner : public MachineFunctionPass {
8484
SmallVector<MachineOperand, 4> BrCond;
8585
MachineInstr *LoopInductionVar = nullptr;
8686
MachineInstr *LoopCompare = nullptr;
87-
std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopPipelinerInfo =
88-
nullptr;
8987
};
9088
LoopInfo LI;
9189

@@ -121,7 +119,6 @@ class SwingSchedulerDAG : public ScheduleDAGInstrs {
121119
LiveIntervals &LIS;
122120
const RegisterClassInfo &RegClassInfo;
123121
unsigned II_setByPragma = 0;
124-
TargetInstrInfo::PipelinerLoopInfo *LoopPipelinerInfo = nullptr;
125122

126123
/// A toplogical ordering of the SUnits, which is needed for changing
127124
/// dependences and iterating over the SUnits.
@@ -199,11 +196,9 @@ class SwingSchedulerDAG : public ScheduleDAGInstrs {
199196

200197
public:
201198
SwingSchedulerDAG(MachinePipeliner &P, MachineLoop &L, LiveIntervals &lis,
202-
const RegisterClassInfo &rci, unsigned II,
203-
TargetInstrInfo::PipelinerLoopInfo *PLI)
199+
const RegisterClassInfo &rci, unsigned II)
204200
: ScheduleDAGInstrs(*P.MF, P.MLI, false), Pass(P), Loop(L), LIS(lis),
205-
RegClassInfo(rci), II_setByPragma(II), LoopPipelinerInfo(PLI),
206-
Topo(SUnits, &ExitSU) {
201+
RegClassInfo(rci), II_setByPragma(II), Topo(SUnits, &ExitSU) {
207202
P.MF->getSubtarget().getSMSMutations(Mutations);
208203
if (SwpEnableCopyToPhi)
209204
Mutations.push_back(std::make_unique<CopyToPhiMutation>());
@@ -594,13 +589,6 @@ class SMSchedule {
594589
return ScheduledInstrs[cycle];
595590
}
596591

597-
SmallSet<SUnit *, 8>
598-
computeUnpipelineableNodes(SwingSchedulerDAG *SSD,
599-
TargetInstrInfo::PipelinerLoopInfo *PLI);
600-
601-
bool
602-
normalizeNonPipelinedInstructions(SwingSchedulerDAG *SSD,
603-
TargetInstrInfo::PipelinerLoopInfo *PLI);
604592
bool isValidSchedule(SwingSchedulerDAG *SSD);
605593
void finalizeSchedule(SwingSchedulerDAG *SSD);
606594
void orderDependence(SwingSchedulerDAG *SSD, SUnit *SU,

llvm/include/llvm/CodeGen/ModuloSchedule.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ class ModuloScheduleExpander {
191191
void generateProlog(unsigned LastStage, MachineBasicBlock *KernelBB,
192192
ValueMapTy *VRMap, MBBVectorTy &PrologBBs);
193193
void generateEpilog(unsigned LastStage, MachineBasicBlock *KernelBB,
194-
MachineBasicBlock *OrigBB, ValueMapTy *VRMap,
195-
MBBVectorTy &EpilogBBs, MBBVectorTy &PrologBBs);
194+
ValueMapTy *VRMap, MBBVectorTy &EpilogBBs,
195+
MBBVectorTy &PrologBBs);
196196
void generateExistingPhis(MachineBasicBlock *NewBB, MachineBasicBlock *BB1,
197197
MachineBasicBlock *BB2, MachineBasicBlock *KernelBB,
198198
ValueMapTy *VRMap, InstrMapTy &InstrMap,

llvm/lib/CodeGen/MachinePipeliner.cpp

Lines changed: 8 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -255,15 +255,13 @@ bool MachinePipeliner::scheduleLoop(MachineLoop &L) {
255255
<< "Failed to pipeline loop";
256256
});
257257

258-
LI.LoopPipelinerInfo.reset();
259258
return Changed;
260259
}
261260

262261
++NumTrytoPipeline;
263262

264263
Changed = swingModuloScheduler(L);
265264

266-
LI.LoopPipelinerInfo.reset();
267265
return Changed;
268266
}
269267

@@ -356,8 +354,7 @@ bool MachinePipeliner::canPipelineLoop(MachineLoop &L) {
356354

357355
LI.LoopInductionVar = nullptr;
358356
LI.LoopCompare = nullptr;
359-
LI.LoopPipelinerInfo = TII->analyzeLoopForPipelining(L.getTopBlock());
360-
if (!LI.LoopPipelinerInfo) {
357+
if (!TII->analyzeLoopForPipelining(L.getTopBlock())) {
361358
LLVM_DEBUG(dbgs() << "Unable to analyzeLoop, can NOT pipeline Loop\n");
362359
NumFailLoop++;
363360
ORE->emit([&]() {
@@ -422,7 +419,7 @@ bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
422419
assert(L.getBlocks().size() == 1 && "SMS works on single blocks only.");
423420

424421
SwingSchedulerDAG SMS(*this, L, getAnalysis<LiveIntervals>(), RegClassInfo,
425-
II_setByPragma, LI.LoopPipelinerInfo.get());
422+
II_setByPragma);
426423

427424
MachineBasicBlock *MBB = L.getHeader();
428425
// The kernel should not include any terminator instructions. These
@@ -1425,7 +1422,7 @@ void SwingSchedulerDAG::CopyToPhiMutation::apply(ScheduleDAGInstrs *DAG) {
14251422
/// We ignore the back-edge recurrence in order to avoid unbounded recursion
14261423
/// in the calculation of the ASAP, ALAP, etc functions.
14271424
static bool ignoreDependence(const SDep &D, bool isPred) {
1428-
if (D.isArtificial() || D.getSUnit()->isBoundaryNode())
1425+
if (D.isArtificial())
14291426
return true;
14301427
return D.getKind() == SDep::Anti && isPred;
14311428
}
@@ -1474,8 +1471,6 @@ void SwingSchedulerDAG::computeNodeFunctions(NodeSetType &NodeSets) {
14741471
SUnit *SU = &SUnits[I];
14751472
for (const SDep &S : SU->Succs) {
14761473
SUnit *succ = S.getSUnit();
1477-
if (succ->isBoundaryNode())
1478-
continue;
14791474
if (S.getLatency() == 0)
14801475
zeroLatencyHeight =
14811476
std::max(zeroLatencyHeight, getZeroLatencyHeight(succ) + 1);
@@ -1793,8 +1788,7 @@ void SwingSchedulerDAG::addConnectedNodes(SUnit *SU, NodeSet &NewSet,
17931788
NodesAdded.insert(SU);
17941789
for (auto &SI : SU->Succs) {
17951790
SUnit *Successor = SI.getSUnit();
1796-
if (!SI.isArtificial() && !Successor->isBoundaryNode() &&
1797-
NodesAdded.count(Successor) == 0)
1791+
if (!SI.isArtificial() && NodesAdded.count(Successor) == 0)
17981792
addConnectedNodes(Successor, NewSet, NodesAdded);
17991793
}
18001794
for (auto &PI : SU->Preds) {
@@ -2086,11 +2080,6 @@ bool SwingSchedulerDAG::schedulePipeline(SMSchedule &Schedule) {
20862080
});
20872081
} while (++NI != NE && scheduleFound);
20882082

2089-
// If a schedule is found, ensure non-pipelined instructions are in stage 0
2090-
if (scheduleFound)
2091-
scheduleFound =
2092-
Schedule.normalizeNonPipelinedInstructions(this, LoopPipelinerInfo);
2093-
20942083
// If a schedule is found, check if it is a valid schedule too.
20952084
if (scheduleFound)
20962085
scheduleFound = Schedule.isValidSchedule(this);
@@ -2274,7 +2263,7 @@ MachineInstr *SwingSchedulerDAG::findDefInLoop(Register Reg) {
22742263
bool SwingSchedulerDAG::isLoopCarriedDep(SUnit *Source, const SDep &Dep,
22752264
bool isSucc) {
22762265
if ((Dep.getKind() != SDep::Order && Dep.getKind() != SDep::Output) ||
2277-
Dep.isArtificial() || Dep.getSUnit()->isBoundaryNode())
2266+
Dep.isArtificial())
22782267
return false;
22792268

22802269
if (!SwpPruneLoopCarried)
@@ -2441,7 +2430,7 @@ int SMSchedule::latestCycleInChain(const SDep &Dep) {
24412430
while (!Worklist.empty()) {
24422431
const SDep &Cur = Worklist.pop_back_val();
24432432
SUnit *SuccSU = Cur.getSUnit();
2444-
if (Visited.count(SuccSU) || SuccSU->isBoundaryNode())
2433+
if (Visited.count(SuccSU))
24452434
continue;
24462435
std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SuccSU);
24472436
if (it == InstrToCycle.end())
@@ -2708,91 +2697,21 @@ bool SMSchedule::isLoopCarriedDefOfUse(SwingSchedulerDAG *SSD,
27082697
return false;
27092698
}
27102699

2711-
/// Determine transitive dependences of unpipelineable instructions
2712-
SmallSet<SUnit *, 8> SMSchedule::computeUnpipelineableNodes(
2713-
SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI) {
2714-
SmallSet<SUnit *, 8> DoNotPipeline;
2715-
SmallVector<SUnit *, 8> Worklist;
2716-
2717-
for (auto &SU : SSD->SUnits)
2718-
if (SU.isInstr() && PLI->shouldIgnoreForPipelining(SU.getInstr()))
2719-
Worklist.push_back(&SU);
2720-
2721-
while (!Worklist.empty()) {
2722-
auto SU = Worklist.pop_back_val();
2723-
if (DoNotPipeline.count(SU))
2724-
continue;
2725-
LLVM_DEBUG(dbgs() << "Do not pipeline SU(" << SU->NodeNum << ")\n");
2726-
DoNotPipeline.insert(SU);
2727-
for (auto &Dep : SU->Preds)
2728-
Worklist.push_back(Dep.getSUnit());
2729-
if (SU->getInstr()->isPHI())
2730-
for (auto &Dep : SU->Succs)
2731-
if (Dep.getKind() == SDep::Anti)
2732-
Worklist.push_back(Dep.getSUnit());
2733-
}
2734-
return DoNotPipeline;
2735-
}
2736-
2737-
// Determine all instructions upon which any unpipelineable instruction depends
2738-
// and ensure that they are in stage 0. If unable to do so, return false.
2739-
bool SMSchedule::normalizeNonPipelinedInstructions(
2740-
SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI) {
2741-
SmallSet<SUnit *, 8> DNP = computeUnpipelineableNodes(SSD, PLI);
2742-
2743-
int NewLastCycle = INT_MIN;
2744-
for (SUnit &SU : SSD->SUnits) {
2745-
if (!SU.isInstr())
2746-
continue;
2747-
if (!DNP.contains(&SU) || stageScheduled(&SU) == 0) {
2748-
NewLastCycle = std::max(NewLastCycle, InstrToCycle[&SU]);
2749-
continue;
2750-
}
2751-
2752-
// Put the non-pipelined instruction as early as possible in the schedule
2753-
int NewCycle = getFirstCycle();
2754-
for (auto &Dep : SU.Preds)
2755-
NewCycle = std::max(InstrToCycle[Dep.getSUnit()], NewCycle);
2756-
2757-
int OldCycle = InstrToCycle[&SU];
2758-
if (OldCycle != NewCycle) {
2759-
InstrToCycle[&SU] = NewCycle;
2760-
auto &OldS = getInstructions(OldCycle);
2761-
OldS.erase(std::remove(OldS.begin(), OldS.end(), &SU), OldS.end());
2762-
getInstructions(NewCycle).emplace_back(&SU);
2763-
LLVM_DEBUG(dbgs() << "SU(" << SU.NodeNum
2764-
<< ") is not pipelined; moving from cycle " << OldCycle
2765-
<< " to " << NewCycle << " Instr:" << *SU.getInstr());
2766-
}
2767-
NewLastCycle = std::max(NewLastCycle, NewCycle);
2768-
}
2769-
LastCycle = NewLastCycle;
2770-
return true;
2771-
}
2772-
27732700
// Check if the generated schedule is valid. This function checks if
27742701
// an instruction that uses a physical register is scheduled in a
27752702
// different stage than the definition. The pipeliner does not handle
27762703
// physical register values that may cross a basic block boundary.
2777-
// Furthermore, if a physical def/use pair is assigned to the same
2778-
// cycle, orderDependence does not guarantee def/use ordering, so that
2779-
// case should be considered invalid. (The test checks for both
2780-
// earlier and same-cycle use to be more robust.)
27812704
bool SMSchedule::isValidSchedule(SwingSchedulerDAG *SSD) {
27822705
for (SUnit &SU : SSD->SUnits) {
27832706
if (!SU.hasPhysRegDefs)
27842707
continue;
27852708
int StageDef = stageScheduled(&SU);
2786-
int CycleDef = InstrToCycle[&SU];
27872709
assert(StageDef != -1 && "Instruction should have been scheduled.");
27882710
for (auto &SI : SU.Succs)
2789-
if (SI.isAssignedRegDep() && !SI.getSUnit()->isBoundaryNode())
2790-
if (Register::isPhysicalRegister(SI.getReg())) {
2711+
if (SI.isAssignedRegDep())
2712+
if (Register::isPhysicalRegister(SI.getReg()))
27912713
if (stageScheduled(SI.getSUnit()) != StageDef)
27922714
return false;
2793-
if (InstrToCycle[SI.getSUnit()] <= CycleDef)
2794-
return false;
2795-
}
27962715
}
27972716
return true;
27982717
}

llvm/lib/CodeGen/ModuloSchedule.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ void ModuloScheduleExpander::generatePipelinedLoop() {
158158

159159
SmallVector<MachineBasicBlock *, 4> EpilogBBs;
160160
// Generate the epilog instructions to complete the pipeline.
161-
generateEpilog(MaxStageCount, KernelBB, BB, VRMap, EpilogBBs, PrologBBs);
161+
generateEpilog(MaxStageCount, KernelBB, VRMap, EpilogBBs, PrologBBs);
162162

163163
// We need this step because the register allocation doesn't handle some
164164
// situations well, so we insert copies to help out.
@@ -240,9 +240,11 @@ void ModuloScheduleExpander::generateProlog(unsigned LastStage,
240240
/// Generate the pipeline epilog code. The epilog code finishes the iterations
241241
/// that were started in either the prolog or the kernel. We create a basic
242242
/// block for each stage that needs to complete.
243-
void ModuloScheduleExpander::generateEpilog(
244-
unsigned LastStage, MachineBasicBlock *KernelBB, MachineBasicBlock *OrigBB,
245-
ValueMapTy *VRMap, MBBVectorTy &EpilogBBs, MBBVectorTy &PrologBBs) {
243+
void ModuloScheduleExpander::generateEpilog(unsigned LastStage,
244+
MachineBasicBlock *KernelBB,
245+
ValueMapTy *VRMap,
246+
MBBVectorTy &EpilogBBs,
247+
MBBVectorTy &PrologBBs) {
246248
// We need to change the branch from the kernel to the first epilog block, so
247249
// this call to analyze branch uses the kernel rather than the original BB.
248250
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
@@ -312,12 +314,7 @@ void ModuloScheduleExpander::generateEpilog(
312314
// Create a branch to the new epilog from the kernel.
313315
// Remove the original branch and add a new branch to the epilog.
314316
TII->removeBranch(*KernelBB);
315-
assert((OrigBB == TBB || OrigBB == FBB) &&
316-
"Unable to determine looping branch direction");
317-
if (OrigBB != TBB)
318-
TII->insertBranch(*KernelBB, EpilogStart, KernelBB, Cond, DebugLoc());
319-
else
320-
TII->insertBranch(*KernelBB, KernelBB, EpilogStart, Cond, DebugLoc());
317+
TII->insertBranch(*KernelBB, KernelBB, EpilogStart, Cond, DebugLoc());
321318
// Add a branch to the loop exit.
322319
if (EpilogBBs.size() > 0) {
323320
MachineBasicBlock *LastEpilogBB = EpilogBBs.back();

llvm/lib/Target/ARM/ARM.td

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,10 +494,6 @@ def FeatureNoNegativeImmediates
494494
def FeatureUseMISched: SubtargetFeature<"use-misched", "UseMISched", "true",
495495
"Use the MachineScheduler">;
496496

497-
// Use the MachinePipeliner for instruction scheduling for the subtarget.
498-
def FeatureUseMIPipeliner: SubtargetFeature<"use-mipipeliner", "UseMIPipeliner", "true",
499-
"Use the MachinePipeliner">;
500-
501497
// False if scheduling should happen again after register allocation.
502498
def FeatureNoPostRASched : SubtargetFeature<"disable-postra-scheduler",
503499
"DisablePostRAScheduler", "true",
@@ -1399,7 +1395,6 @@ def : ProcessorModel<"cortex-m4", CortexM4Model, [ARMv7em,
13991395
def : ProcessorModel<"cortex-m7", CortexM7Model, [ARMv7em,
14001396
ProcM7,
14011397
FeatureFPARMv8_D16,
1402-
FeatureUseMIPipeliner,
14031398
FeatureUseMISched]>;
14041399

14051400
def : ProcNoItin<"cortex-m23", [ARMv8mBaseline,

llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -6721,78 +6721,3 @@ unsigned llvm::getBLXpredOpcode(const MachineFunction &MF) {
67216721
return (MF.getSubtarget<ARMSubtarget>().hardenSlsBlr()) ? ARM::BLX_pred_noip
67226722
: ARM::BLX_pred;
67236723
}
6724-
6725-
namespace {
6726-
class ARMPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
6727-
MachineInstr *Loop, *EndLoop, *LoopCount;
6728-
MachineFunction *MF;
6729-
const TargetInstrInfo *TII;
6730-
6731-
// Meanings of the various stuff with loop types:
6732-
// t2Bcc:
6733-
// Loop = null -- there is no setup.
6734-
// EndLoop = branch at end of original BB that will become a kernel
6735-
// LoopCount = CC setter live into branch
6736-
public:
6737-
ARMPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop,
6738-
MachineInstr *LoopCount)
6739-
: Loop(Loop), EndLoop(EndLoop), LoopCount(LoopCount),
6740-
MF(EndLoop->getParent()->getParent()),
6741-
TII(MF->getSubtarget().getInstrInfo()) {}
6742-
6743-
bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
6744-
// Only ignore the terminator.
6745-
return MI == EndLoop || MI == LoopCount;
6746-
}
6747-
6748-
Optional<bool> createTripCountGreaterCondition(
6749-
int TC, MachineBasicBlock &MBB,
6750-
SmallVectorImpl<MachineOperand> &Cond) override {
6751-
6752-
if (isCondBranchOpcode(EndLoop->getOpcode())) {
6753-
Cond.push_back(EndLoop->getOperand(1));
6754-
Cond.push_back(EndLoop->getOperand(2));
6755-
if (EndLoop->getOperand(0).getMBB() == EndLoop->getParent()) {
6756-
TII->reverseBranchCondition(Cond);
6757-
}
6758-
return {};
6759-
} else
6760-
llvm_unreachable("Unknown EndLoop");
6761-
}
6762-
6763-
void setPreheader(MachineBasicBlock *NewPreheader) override {}
6764-
6765-
void adjustTripCount(int TripCountAdjust) override {}
6766-
6767-
void disposed() override {}
6768-
};
6769-
} // namespace
6770-
6771-
std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
6772-
ARMBaseInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {
6773-
MachineBasicBlock::iterator I = LoopBB->getFirstTerminator();
6774-
MachineBasicBlock *Preheader = *LoopBB->pred_begin();
6775-
if (Preheader == LoopBB)
6776-
Preheader = *std::next(LoopBB->pred_begin());
6777-
6778-
if (I != LoopBB->end() && I->getOpcode() == ARM::t2Bcc) {
6779-
// If the branch is a Bcc, then the CPSR should be set somewhere within the
6780-
// block. We need to determine the reaching definition of CPSR so that
6781-
// it can be marked as non-pipelineable, allowing the pipeliner to force
6782-
// it into stage 0 or give up if it cannot or will not do so.
6783-
MachineInstr *CCSetter = nullptr;
6784-
for (auto &L : LoopBB->instrs()) {
6785-
if (L.isCall())
6786-
return nullptr;
6787-
if (isCPSRDefined(L))
6788-
CCSetter = &L;
6789-
}
6790-
if (CCSetter)
6791-
return std::make_unique<ARMPipelinerLoopInfo>(nullptr, &*I, CCSetter);
6792-
else
6793-
return nullptr; // Unable to find the CC setter, so unable to guarantee
6794-
// that pipeline will work
6795-
}
6796-
6797-
return nullptr;
6798-
}

llvm/lib/Target/ARM/ARMBaseInstrInfo.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,11 +372,6 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo {
372372
MI->getOpcode() == ARM::t2WhileLoopStartTP;
373373
}
374374

375-
/// Analyze loop L, which must be a single-basic-block loop, and if the
376-
/// conditions can be understood enough produce a PipelinerLoopInfo object.
377-
std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
378-
analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;
379-
380375
private:
381376
/// Returns an unused general-purpose register which can be used for
382377
/// constructing an outlined call if one exists. Returns 0 otherwise.

0 commit comments

Comments
 (0)