53#define DEBUG_TYPE "global_sched"
57STATISTIC(HexagonNumPullUps,
"Number of instructions pull-ups");
58STATISTIC(HexagonNumDualJumps,
"Number of dual jumps formed");
61 cl::desc(
"Disable Hexagon pull-up pass"));
65 cl::desc(
"Enable speculation during Hexagon pull-up pass"));
69 cl::desc(
"Enable same BB pull during Hexagon pull-up pass"));
73 cl::desc(
"Allow speculative loads during Hexagon pull-up pass"));
77 cl::desc(
"Allow compare-branch loads during Hexagon pull-up pass"));
81 cl::desc(
"Allow unlikely path pull up"));
85 cl::desc(
"Perform dual jump formation during pull up"));
89 cl::desc(
"Perform dual jump formation during pull up"));
93 cl::desc(
"Peel a reg copy out of a BBloop"));
97 cl::desc(
"Do not destroy existing compounds during pull up"));
101 cl::desc(
"Do not destroy existing duplexes during pull up"));
111 cl::desc(
"Enable opt. exposed by pull-up e.g., remove redundant jumps"));
115 cl::desc(
"Speculate non-predicable instructions in parent BB"));
120 cl::desc(
"Disable Hexagon check bundles pass"));
124 cl::desc(
"Hexagon check bundles and warn on size"));
128 cl::desc(
"Force noop hazards in scheduler"));
131 cl::desc(
"Allow only one single floating point instruction in a packet"));
134 cl::desc(
"Allow only one complex instruction in a packet"));
142class HexagonGlobalSchedulerImpl;
147 HexagonGlobalScheduler() : MachineFunctionPass(ID) {
151 void getAnalysisUsage(AnalysisUsage &AU)
const override {
155 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
156 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
161 StringRef getPassName()
const override {
return "Hexagon Global Scheduler"; }
165char HexagonGlobalScheduler::ID = 0;
168class PullUpCandidate {
173 std::vector<MachineInstr *> Backtrack;
177 CandidateLocation = MII;
183 std::vector<MachineInstr *> &backtrack,
bool DependentOp,
185 : CandidateLocation(MII), HomeBundle(HomeBundle),
186 DependentOp(DependentOp), BenefitCost(
Cost) {
188 Backtrack = backtrack;
193 std::vector<MachineInstr *> &backtrack,
bool &dependentOp) {
194 MII = CandidateLocation;
195 WorkPoint = HomeBundle;
196 backtrack = Backtrack;
197 dependentOp = DependentOp;
200 signed getCost() {
return BenefitCost; }
202 MachineInstr *getCandidate() {
return &*CandidateLocation; }
205 dbgs() <<
"Cost(" << BenefitCost;
206 dbgs() <<
") Dependent(" << DependentOp;
207 dbgs() <<
") backtrack size(" << Backtrack.size() <<
")\t";
208 CandidateLocation->dump();
213struct PullUpCandidateSorter {
214 PullUpCandidateSorter() {}
215 bool operator()(PullUpCandidate *
LHS, PullUpCandidate *
RHS) {
216 return LHS->getCost() >
RHS->getCost();
224 friend class HexagonGlobalSchedulerImpl;
233 const HexagonInstrInfo *QII;
236 PullUpState(
const HexagonInstrInfo *QII) : HomeLocation(NULL), QII(QII) {}
238 ~PullUpState() { reset(); }
242 std::vector<MachineInstr *> &backtrack,
243 bool DependentOp,
signed Cost) {
245 PullUpCandidate *PUI =
246 new PullUpCandidate(MII, HomeBundle, backtrack, DependentOp,
Cost);
247 PullUpCandidates.push_back(PUI);
251 unsigned element = 0;
252 for (
unsigned i = 0; i < HomeBundle.size(); i++) {
253 dbgs() <<
"[" << element++;
254 dbgs() <<
"] Home Duplex("
255 << QII->getDuplexCandidateGroup(*HomeBundle[i]);
256 dbgs() <<
") Compound (" << QII->getCompoundCandidateGroup(*HomeBundle[i])
258 HomeBundle[i]->dump();
262 for (SmallVector<PullUpCandidate *, 4>::iterator
263 I = PullUpCandidates.begin(),
264 E = PullUpCandidates.end();
266 dbgs() <<
"[" << element++ <<
"] Cand: Compound(";
267 dbgs() << QII->getCompoundCandidateGroup(*(*I)->getCandidate()) <<
") ";
274 for (SmallVector<PullUpCandidate *, 4>::iterator
275 I = PullUpCandidates.begin(),
276 E = PullUpCandidates.end();
279 PullUpCandidates.clear();
285 HomeLocation = WorkPoint;
288 unsigned haveCandidates() {
return PullUpCandidates.size(); }
293 std::vector<BasicBlockRegion *> PullUpRegions;
296 DenseMap<MachineBasicBlock *, unsigned> BlockToInstOffset;
298 PullUpState CurrentState;
300 std::vector<MachineBasicBlock *> EmptyBBs;
306 std::map<MachineInstr *, MachineBasicBlock *> SpeculatedIns;
308 std::map<MachineInstr *, std::vector<unsigned>> MIUseSet;
310 std::map<MachineInstr *, std::vector<unsigned>> MIDefSet;
313 const MachineBranchProbabilityInfo *MBPI;
314 const MachineBlockFrequencyInfo *MBFI;
315 const MachineRegisterInfo *MRI;
316 const MachineFrameInfo &MFI;
317 const HexagonRegisterInfo *QRI;
318 const HexagonInstrInfo *QII;
319 MachineLoopInfo &MLI;
320 MachineDominatorTree &MDT;
321 MachineInstrBuilder Ext;
322 MachineInstrBuilder Nop;
323 const unsigned PacketSize;
324 TargetSchedModel TSchedModel;
330 const MachineBranchProbabilityInfo *MBPI,
331 const MachineBlockFrequencyInfo *MBFI,
332 const MachineRegisterInfo *MRI,
333 const MachineFrameInfo &MFI,
334 const HexagonRegisterInfo *QRI);
335 HexagonGlobalSchedulerImpl(
const HexagonGlobalSchedulerImpl &) =
delete;
336 HexagonGlobalSchedulerImpl &
337 operator=(
const HexagonGlobalSchedulerImpl &) =
delete;
339 ~HexagonGlobalSchedulerImpl() {
341 for (std::vector<BasicBlockRegion *>::iterator
I = PullUpRegions.begin(),
342 E = PullUpRegions.end();
345 MF.deleteMachineInstr(Ext);
346 MF.deleteMachineInstr(Nop);
350 void initPacketizerState()
override;
353 bool ignoreInstruction(MachineInstr *
MI);
357 bool isSoloInstruction(
const MachineInstr &
MI)
override;
360 bool incrementalAddToPacket(MachineInstr &
MI);
366 bool performPullUp();
386 MachineBasicBlock *optimizeBranches(MachineBasicBlock *
MBB,
387 MachineBasicBlock *
TBB,
388 MachineInstr *FirstTerm,
389 MachineBasicBlock *FBB);
394 bool removeRedundantBranches(MachineBasicBlock *
MBB, MachineBasicBlock *
TBB,
395 MachineInstr *FirstTerm, MachineBasicBlock *FBB,
396 MachineInstr *SecondTerm);
400 bool optimizeDualJumps(MachineBasicBlock *
MBB, MachineBasicBlock *
TBB,
401 MachineInstr *FirstTerm, MachineBasicBlock *FBB,
402 MachineInstr *SecondTerm);
407 BasicBlockRegion *getRegionForMBB(std::vector<BasicBlockRegion *> &Regions,
408 MachineBasicBlock *
MBB);
412 void MIUseDefSet(MachineInstr *
MI, std::vector<unsigned> &Defs,
413 std::vector<unsigned> &
Uses);
423 MachineBasicBlock *getNextPURBB(MachineBasicBlock *
MBB,
bool SecondBest);
425 void setUsedRegs(BitVector &Set,
unsigned Reg);
426 bool AliasingRegs(
unsigned RegA,
unsigned RegB);
429 bool ReorderDependencyTest(MachineInstr *MIa, MachineInstr *MIb);
431 bool canAddMIToThisPacket(
435 bool pullUpPeelBBLoop(MachineBasicBlock *PredBB, MachineBasicBlock *LoopBB);
437 MachineInstr *findBundleAndBranch(MachineBasicBlock *BB,
441 bool ResourcesAvailableInBundle(BasicBlockRegion *CurrentRegion,
445 MachineInstr *MoveAndUpdateLiveness(
446 BasicBlockRegion *CurrentRegion, MachineBasicBlock *HomeBB,
447 MachineInstr *InstrToMove,
bool NeedToNewify,
unsigned DepReg,
448 bool MovingDependentOp, MachineBasicBlock *OriginBB,
449 MachineInstr *OriginalInstruction, SmallVector<MachineOperand, 4> &
Cond,
453 std::vector<MachineInstr *> &backtrack);
456 void updateKillAlongThePath(MachineBasicBlock *HomeBB,
457 MachineBasicBlock *OriginBB,
462 std::vector<MachineInstr *> &backtrack);
467 std::vector<MachineInstr *> &backtrack,
468 unsigned MaxCandidates);
471 bool tryMultipleInstructions(
473 std::vector<BasicBlockRegion *>::iterator &CurrentRegion,
479 bool MoveMItoBundle(BasicBlockRegion *CurrentRegion,
484 std::vector<MachineInstr *> &backtrack,
485 bool MovingDependentOp,
bool PathInRegion);
489 insertTempCopy(MachineBasicBlock *
MBB,
495 MachineInstr *
MI,
bool &LastInBundle);
498 MachineInstr *TargetPacket);
501 unsigned DepReg, MachineInstr *TargetPacket);
503 void addInstructionToExistingBundle(MachineBasicBlock *HomeBB,
509 std::vector<MachineInstr *> &backtrack);
511 void removeInstructionFromExistingBundle(
516 std::vector<MachineInstr *> &backtrack);
519 bool MIsCondAssign(MachineInstr *BMI, MachineInstr *
MI,
520 SmallVector<unsigned, 4> &Defs);
525 bool canMIBeSpeculated(MachineInstr *
MI, MachineBasicBlock *ToBB,
526 MachineBasicBlock *FromBB,
527 std::vector<MachineInstr *> &backtrack);
530 bool isBranchWithinRegion(BasicBlockRegion *CurrentRegion, MachineInstr *
MI);
533 bool MIsAreDependent(MachineInstr *MIa, MachineInstr *MIb);
534 bool MIsHaveTrueDependency(MachineInstr *MIa, MachineInstr *MIb);
535 bool canReorderMIs(MachineInstr *MIa, MachineInstr *MIb);
536 bool canCauseStall(MachineInstr *
MI, MachineInstr *MJ);
537 bool canThisMIBeMoved(MachineInstr *
MI,
539 bool &MovingDependentOp,
int &
Cost);
540 bool MIisDualJumpCandidate(MachineInstr *
MI,
542 bool DemoteToDotOld(MachineInstr *
MI);
544 MachineInstr *TargetPacket);
545 bool IsNewifyStore(MachineInstr *
MI);
546 bool isJumpOutOfRange(MachineInstr *
MI);
547 bool IsDualJumpFirstCandidate(MachineInstr *
MI);
548 bool IsDualJumpFirstCandidate(MachineBasicBlock *
MBB);
550 bool IsNotDualJumpFirstCandidate(MachineInstr *
MI);
551 bool isJumpOutOfRange(MachineInstr *UnCond, MachineInstr *
Cond);
552 bool IsDualJumpSecondCandidate(MachineInstr *
MI);
553 bool tryAllocateResourcesForConstExt(MachineInstr *
MI,
bool UpdateState);
554 bool isCompoundPair(MachineInstr *MIa, MachineInstr *MIb);
555 bool doesMIDefinesPredicate(MachineInstr *
MI, SmallVector<unsigned, 4> &Defs);
556 bool AnalyzeBBBranches(MachineBasicBlock *
MBB, MachineBasicBlock *&
TBB,
557 MachineInstr *&FirstTerm, MachineBasicBlock *&FBB,
558 MachineInstr *&SecondTerm);
559 inline bool multipleBranchesFromToBB(MachineBasicBlock *BB)
const;
564 "Hexagon Global Scheduler",
false,
false)
574HexagonGlobalSchedulerImpl::HexagonGlobalSchedulerImpl(
581 MBFI(MBFI), MRI(MRI), MFI(MFI), QRI(QRI), MLI(MLI), MDT(MDT),
582 PacketSize(MF.getSubtarget().getSchedModel().IssueWidth) {
586 TSchedModel.
init(&MF.getSubtarget());
594 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
595 if (MII->isDebugInstr())
603bool HexagonGlobalScheduler::runOnMachineFunction(
MachineFunction &Fn) {
608 const MachineRegisterInfo *MRI = &Fn.
getRegInfo();
610 const HexagonRegisterInfo *QRI = HST.getRegisterInfo();
611 MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
612 MachineDominatorTree &MDT =
613 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
614 const MachineBranchProbabilityInfo *MBPI =
615 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
616 const MachineBlockFrequencyInfo *MBFI =
617 &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
618 AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
626 HexagonGlobalSchedulerImpl GlobalSchedulerState(Fn, MLI, MDT, AA, MBPI, MBFI,
630 assert(GlobalSchedulerState.getResourceTracker() &&
"Empty DFA table!");
635 GlobalSchedulerState.checkBundleCounts(Fn);
641 LLVM_DEBUG(GlobalSchedulerState.countCompounds(Fn));
642 GlobalSchedulerState.GenUseDefChain(Fn);
643 GlobalSchedulerState.formPullUpRegions(Fn);
644 GlobalSchedulerState.performPullUp();
645 GlobalSchedulerState.performPullUpCFG(Fn);
647 GlobalSchedulerState.formPullUpRegions(Fn);
648 GlobalSchedulerState.performExposedOptimizations(Fn);
650 LLVM_DEBUG(GlobalSchedulerState.countCompounds(Fn));
657bool HexagonGlobalSchedulerImpl::tryAllocateResourcesForConstExt(
658 MachineInstr *
MI,
bool UpdateState =
true) {
659 if (ResourceTracker->canReserveResources(*Ext)) {
664 ResourceTracker->reserveResources(*Ext);
665 else if (CurrentPacketMIs.size() >= PacketSize - 1)
674 return MI->getOpcode() == Hexagon::Y2_barrier;
678 return MI->getOpcode() == Hexagon::J2_callr;
683 if (
MI->isBundledWithPred())
687 if (
MI->isBundledWithSucc())
696 dbgs() <<
"\tNULL\n";
703 dbgs() <<
"\tUnattached: ";
709 if (
MI->isBundle()) {
711 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
722 dbgs() <<
"\tBBEnd\n";
731 if (
MI->isBundle()) {
734 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
740 return MI->isBranch();
745bool HexagonGlobalSchedulerImpl::IsNotDualJumpFirstCandidate(MachineInstr *
MI) {
754bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(MachineInstr *
MI) {
765bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(
769 MachineInstr *
MI = &*TargetPacket;
771 if (
MI->isBundle()) {
773 if (&(*
MI->getParent()->rbegin()) !=
MI)
780 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
782 if (IsNotDualJumpFirstCandidate(&*MII))
785 return IsDualJumpFirstCandidate(
MI);
793bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(
794 MachineBasicBlock *
MBB) {
800 MII != MBBEnd; ++MII) {
801 MachineInstr *
MI = &*MII;
802 if (
MI->isDebugInstr())
804 if (!
MI->isBundle() && IsNotDualJumpFirstCandidate(
MI))
811bool HexagonGlobalSchedulerImpl::IsDualJumpSecondCandidate(MachineInstr *
MI) {
832 if (!MII->isBundle() && MII->isTerminator())
843bool HexagonGlobalSchedulerImpl::isJumpOutOfRange(MachineInstr *
MI) {
844 if (!
MI || !
MI->isBranch())
851 unsigned InstOffset = BlockToInstOffset[
MBB];
852 unsigned Distance = 0;
860 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
861 SmallVector<MachineOperand, 4>
Cond;
871 if (
TBB && (
MI == &*FirstTerm)) {
873 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[
TBB]) +
882 MachineInstr *SecondTerm = &*FTMII;
885 "Bad second terminator");
886 if (
MI != SecondTerm)
890 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[FBB]) +
892 LLVM_DEBUG(
dbgs() <<
"\tSecond term offset(" << Distance <<
"): ";
902bool HexagonGlobalSchedulerImpl::isNewifiable(
904 MachineInstr *TargetPacket) {
905 MachineInstr *
MI = &*MII;
907 !CanNewifiedBeUsedInBundle(MII, DepReg, TargetPacket))
913bool HexagonGlobalSchedulerImpl::DemoteToDotOld(MachineInstr *
MI) {
915 MI->setDesc(QII->get(NewOpcode));
920void HexagonGlobalSchedulerImpl::initPacketizerState(
void) {
921 CurrentPacketMIs.clear();
926bool HexagonGlobalSchedulerImpl::ignoreInstruction(MachineInstr *
MI) {
927 if (
MI->isDebugInstr())
931 if (
MI->isInlineAsm())
936 const MCInstrDesc &TID =
MI->getDesc();
938 const InstrStage *
IS =
939 ResourceTracker->getInstrItins()->beginStage(SchedClass);
940 unsigned FuncUnits =
IS->getUnits();
946bool HexagonGlobalSchedulerImpl::isSoloInstruction(
const MachineInstr &
MI) {
947 if (
MI.isInlineAsm())
959 if (
MI.getOpcode() == Hexagon::A2_nop)
966BasicBlockRegion *HexagonGlobalSchedulerImpl::getRegionForMBB(
967 std::vector<BasicBlockRegion *> &Regions, MachineBasicBlock *
MBB) {
968 for (std::vector<BasicBlockRegion *>::iterator
I = Regions.begin(),
971 if ((*I)->findMBB(
MBB))
997HexagonGlobalSchedulerImpl::getNextPURBB(MachineBasicBlock *
MBB,
998 bool SecondBest =
false) {
1002 BlockFrequency BestBlockFreq = BlockFrequency(0);
1003 unsigned BestBlockSize = 0;
1004 MachineBasicBlock *BestBB = NULL;
1005 MachineBasicBlock *SecondBestBB = NULL;
1016 LLVM_DEBUG(
dbgs() <<
"\tsucc BB(" << Succ->getNumber() <<
") freq("
1019 if (!SecondBest && getRegionForMBB(PullUpRegions, Succ))
1024 if (Succ->pred_size() > 1)
1029 if (Succ->isEHPad() || Succ->hasAddressTaken())
1039 BestBlockFreq = EdgeFreq;
1041 SecondBestBB = BestBB;
1043 }
else if (!SecondBestBB) {
1044 SecondBestBB = Succ;
1048 return SecondBestBB;
1054bool HexagonGlobalSchedulerImpl::formPullUpRegions(
MachineFunction &Fn) {
1057 if (std::next(
F.begin()) ==
F.end())
1062 unsigned InstOffset = 0;
1064 LLVM_DEBUG(
dbgs() <<
"****** Form PullUpRegions **************\n");
1074 InstOffset = (InstOffset + ByteAlign) & ~(ByteAlign);
1077 BlockToInstOffset[&*
MBB] = InstOffset;
1081 if (!MII->isBundle())
1082 InstOffset += QII->
getSize(*MII);
1085 if (getRegionForMBB(PullUpRegions, &*
MBB))
1094 BasicBlockRegion *PUR =
new BasicBlockRegion(
TII, QRI, &*
MBB);
1095 PullUpRegions.push_back(PUR);
1097 for (MachineBasicBlock *MBBR = getNextPURBB(&*
MBB); MBBR;
1098 MBBR = getNextPURBB(MBBR)) {
1100 << MBBR->getName() <<
") size("
1103 << MBBR->getParent()->getFunction().getName() <<
")\n");
1113 if (
MI->hasUnmodeledSideEffects() ||
MI->hasOrderedMemoryRef() ||
1115 (
MI->getOpcode() == Hexagon::J2_jump && !
MI->getOperand(0).isMBB()))
1123 if (!
MI ||
MI->memoperands_empty())
1129 if ((*
MI->memoperands_begin())->isVolatile() ||
MI->hasUnmodeledSideEffects())
1132 if (!(*
MI->memoperands_begin())->getValue())
1145 if (
TII->areMemAccessesTriviallyDisjoint(*MIa, *MIb))
1171 assert((MMOa->
getOffset() >= 0) &&
"Negative MachineMemOperand offset");
1172 assert((MMOb->
getOffset() >= 0) &&
"Negative MachineMemOperand offset");
1174 "Size 0 memory access");
1211 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1224 for (
unsigned R = 1, NR = Hexagon::NUM_TARGET_REGS; R != NR; ++R)
1231void HexagonGlobalSchedulerImpl::MIUseDefSet(MachineInstr *
MI,
1232 std::vector<unsigned> &Defs,
1233 std::vector<unsigned> &
Uses) {
1236 assert(!
MI->isBundle() &&
"Cannot parse regs of a bundle.");
1237 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1238 const MachineOperand &MO =
MI->getOperand(i);
1244 assert(Register::isPhysicalRegister(
Reg));
1245 std::vector<unsigned> &Refs = MO.
isUse() ?
Uses : Defs;
1246 for (MCRegAliasIterator AI(MO.
getReg(), QRI,
true); AI.isValid(); ++AI)
1247 Refs.push_back(*AI);
1249 for (
unsigned R = 1, NR = Hexagon::NUM_TARGET_REGS;
R != NR; ++
R)
1286bool HexagonGlobalSchedulerImpl::canAddMIToThisPacket(
1296 isJumpOutOfRange(
MI)) &&
1297 !tryAllocateResourcesForConstExt(
MI,
false))
1301 if (!ResourceTracker->canReserveResources(*
MI) || !shouldAddToPacket(*
MI)) {
1306 SmallVector<unsigned, 4> BundleDefs;
1307 SmallVector<unsigned, 8> BundleUses;
1308 SmallVector<unsigned, 4> Defs;
1309 SmallVector<unsigned, 8>
Uses;
1310 MachineInstr *FirstCompound = NULL, *SecondCompound = NULL;
1311 MachineInstr *FirstDuplex = NULL, *SecondDuplex = NULL;
1314 for (SmallVector<MachineInstr *, HEXAGON_PACKET_SIZE>::iterator
1315 BI = Bundle.
begin(),
1322 MachineInstr *Inst1 = *BI;
1323 MachineInstr *Inst2 =
MI;
1336 FirstCompound = *BI;
1338 SecondCompound = *BI;
1339 if (isCompoundPair(FirstCompound, SecondCompound)) {
1340 if (
MI->mayLoad() ||
MI->mayStore()) {
1354 if (
MI->mayLoad() ||
MI->mayStore()) {
1362 for (
unsigned i = 0; i < Defs.
size(); i++) {
1364 for (
unsigned j = 0;
j < BundleDefs.
size();
j++)
1369 if (AliasingRegs(Defs[i], BundleDefs[j]) &&
1371 !(IsDualJumpFirstCandidate(*BI) && IsDualJumpSecondCandidate(
MI))) {
1373 dbgs() <<
"\t"; (*BI)->dump());
1389 for (
unsigned j = 0;
j < BundleUses.
size();
j++)
1390 if (AliasingRegs(Defs[i], BundleUses[j])) {
1391 for (
unsigned k = 0;
k < BundleDefs.
size();
k++)
1392 for (
unsigned l = 0;
l <
Uses.size();
l++) {
1393 if (AliasingRegs(BundleDefs[k],
Uses[l]) &&
1396 dbgs() <<
"\t"; (*BI)->dump());
1403 for (
unsigned i = 0; i <
Uses.size(); i++) {
1405 for (
unsigned j = 0;
j < BundleDefs.
size();
j++)
1406 if (AliasingRegs(
Uses[i], BundleDefs[j]) &&
1410 MI->dump();
dbgs() <<
"\t"; (*BI)->dump());
1422 if ((*BI)->isCall()) {
1424 for (
unsigned i = 0; i < Defs.
size(); i++) {
1425 if (AliasingRegs(Defs[i], *
I)) {
1440 if ((*BI)->isBarrier()) {
1473 (
MI->mayStore() ||
MI->getOpcode() == Hexagon::S2_allocframe ||
1496 if ((QII->
isMemOp(**BI) &&
MI->mayStore()) ||
1497 (QII->
isMemOp(*
MI) && (*BI)->mayStore())) {
1499 dbgs() <<
"\tSlot 0 not available for store because of memop.\n");
1504 if ((
MI->mayLoad() && (*BI)->mayStore()) ||
1505 (
MI->mayStore() && (*BI)->mayLoad()) ||
1506 (
MI->mayStore() && (*BI)->mayStore())) {
1509 dbgs() <<
"\t"; (*BI)->dump());
1515 std::map<MachineInstr *, MachineBasicBlock *>::iterator MIMoved;
1516 MIMoved = SpeculatedIns.find(*BI);
1517 if ((MIMoved != SpeculatedIns.end()) &&
1518 (MIMoved->second != (*BI)->getParent())) {
1520 dbgs() <<
"This packet already contains a speculated instruction";
1536bool HexagonGlobalSchedulerImpl::ReorderDependencyTest(MachineInstr *MIa,
1537 MachineInstr *MIb) {
1538 SmallVector<unsigned, 4> DefsA;
1539 SmallVector<unsigned, 4> DefsB;
1540 SmallVector<unsigned, 8> UsesA;
1541 SmallVector<unsigned, 8> UsesB;
1546 for (SmallVector<unsigned, 4>::iterator IDA = DefsA.
begin(),
1548 IDA != IDAE; ++IDA) {
1549 for (SmallVector<unsigned, 8>::iterator IUB = UsesB.
begin(),
1553 if (AliasingRegs(*IDA, *IUB))
1556 for (SmallVector<unsigned, 4>::iterator IDB = DefsB.
begin(),
1560 if (AliasingRegs(*IDA, *IDB))
1564 for (SmallVector<unsigned, 4>::iterator IDB = DefsB.
begin(),
1566 IDB != IDBE; ++IDB) {
1567 for (SmallVector<unsigned, 8>::iterator IUA = UsesA.
begin(),
1571 if (AliasingRegs(*IDB, *IUA))
1582 for (
unsigned i = 0; i < DefsB.
size(); i++) {
1583 if (AliasingRegs(DefsB[i], *
I))
1590 for (
unsigned i = 0; i < DefsA.
size(); i++) {
1591 if (AliasingRegs(DefsA[i], *
I))
1613bool HexagonGlobalSchedulerImpl::MIsAreDependent(MachineInstr *MIa,
1614 MachineInstr *MIb) {
1618 if (ReorderDependencyTest(MIa, MIb)) {
1627bool HexagonGlobalSchedulerImpl::MIsHaveTrueDependency(MachineInstr *MIa,
1628 MachineInstr *MIb) {
1632 SmallVector<unsigned, 4> DefsA;
1633 SmallVector<unsigned, 4> DefsB;
1634 SmallVector<unsigned, 8> UsesA;
1635 SmallVector<unsigned, 8> UsesB;
1640 for (SmallVector<unsigned, 4>::iterator IDA = DefsA.
begin(),
1642 IDA != IDAE; ++IDA) {
1643 for (SmallVector<unsigned, 8>::iterator IUB = UsesB.
begin(),
1647 if (AliasingRegs(*IDA, *IUB))
1655bool HexagonGlobalSchedulerImpl::canReorderMIs(MachineInstr *MIa,
1656 MachineInstr *MIb) {
1664 for (++MII; MII != MIIE && MII->isInsideBundle(); ++MII) {
1665 if (MII->isDebugInstr())
1667 if (MIsAreDependent(&*MII, MIb))
1672 return !MIsAreDependent(MIa, MIb);
1682 if (
MI->isBranch() ||
MI->isReturn() ||
MI->isCall() ||
MI->isBarrier() ||
1690bool HexagonGlobalSchedulerImpl::MIisDualJumpCandidate(
1696 MachineBasicBlock *FromThisBB =
MI->getParent();
1697 MachineBasicBlock *ToThisBB = WorkPoint->getParent();
1700 << ToThisBB->
getNumber() <<
") From BB("
1704 if (FromThisBB == ToThisBB)
1710 if ((*(FromThisBB->
pred_begin()) != ToThisBB) ||
1721 MachineBasicBlock *ToTBB = NULL, *ToFBB = NULL;
1726 SmallVector<MachineOperand, 4> ToCond;
1727 if (!QII->
analyzeBranch(*ToThisBB, ToTBB, ToFBB, ToCond,
false)) {
1731 if (ToFBB)
dbgs() << ToFBB->getNumber() <<
").\n";
1732 else dbgs() <<
"None"
1734 if (ToTBB == FromThisBB) {
1738 }
else if (ToFBB == FromThisBB || !ToFBB) {
1747 }
else if (ToThisBB->
succ_size() == 1) {
1749 assert(ToFBB == FromThisBB &&
"Bad CFG layout");
1755 return IsDualJumpFirstCandidate(WorkPoint);
1762bool HexagonGlobalSchedulerImpl::canCauseStall(MachineInstr *
MI,
1764 SmallVector<unsigned, 4> DefsMJI;
1765 SmallVector<unsigned, 8> UsesMJI;
1766 SmallVector<unsigned, 4> DefsMI;
1767 SmallVector<unsigned, 8> UsesMI;
1770 for (
auto Use : UsesMI) {
1771 int UseIdx =
MI->findRegisterUseOperandIdx(Use,
nullptr);
1774 bool ShouldBreak =
false;
1775 int BundleCount = 0;
1779 MJI != Begin; --MJI) {
1780 if (MJI->isBundle()) {
1785 for (
auto Def : DefsMJI) {
1786 if (Def == Use || AliasingRegs(Def, Use)) {
1787 int DefIdx = MJI->findRegisterDefOperandIdx(Def,
nullptr);
1803 if (!MJI->isBundled() && !MJI->isDebugInstr())
1814bool HexagonGlobalSchedulerImpl::canThisMIBeMoved(
1816 bool &MovingDependentOp,
int &
Cost) {
1820 MovingDependentOp =
false;
1833 for (--MII; MII->isBundled(); --MII)
1834 if (MII->isBundle())
1838 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1842 if (isCompoundPair(&*MII,
MI)) {
1855 for (--MII; MII->isBundled(); --MII)
1856 if (MII->isBundle())
1860 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1875 if (MIisDualJumpCandidate(
MI, WorkPoint)) {
1880 MovingDependentOp =
true;
1890 unsigned dist_looplabel =
1891 BlockToInstOffset.
find(
MI->getOperand(0).getMBB())->second;
1892 unsigned dist_newloop0 =
1893 BlockToInstOffset.
find(WorkPoint->getParent())->second;
1896 (unsigned)std::abs((
long long)dist_looplabel - dist_newloop0) +
1898 const HexagonInstrInfo *HII = (
const HexagonInstrInfo *)
TII;
1901 << Distance <<
" outside branch range.";);
1904 LLVM_DEBUG(
dbgs() <<
"\nloopN can be moved since Distance: " << Distance
1905 <<
" within branch range.";);
1910 std::map<MachineInstr *, std::vector<unsigned>>::const_iterator DefIter =
1913 for (
unsigned i = 0; DefIter != MIDefSet.end() && i < DefIter->second.size();
1920 if (
MI->isBundled()) {
1929 for (--MII; MII->isBundled(); --MII)
1930 if (MII->isBundle())
1934 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1936 if (MII->isDebugInstr())
1938 if (MIsAreDependent(&*MII,
MI)) {
1947 IsDualJumpSecondCandidate(&*MII) ||
MI->isBranch()) {
1949 MovingDependentOp =
true;
1953 LLVM_DEBUG(
dbgs() <<
"\t\tDependent, and do not allow for now.\n");
1964bool HexagonGlobalSchedulerImpl::doesMIDefinesPredicate(
1965 MachineInstr *
MI, SmallVector<unsigned, 4> &Defs) {
1966 bool defsPredicate =
false;
1969 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1970 const MachineOperand &MO =
MI->getOperand(i);
1980 assert(Register::isPhysicalRegister(
Reg));
1984 if (RC == &Hexagon::PredRegsRegClass) {
1985 defsPredicate =
true;
1990 return defsPredicate;
1998bool HexagonGlobalSchedulerImpl::NeedToNewify(
2000 MachineInstr *TargetPacket = NULL) {
2002 SmallVector<unsigned, 4> DefsA;
2003 SmallVector<unsigned, 4> DefsB;
2004 SmallVector<unsigned, 8> UsesB;
2015 if (TargetPacket && !TargetPacket->
isBundled()) {
2016 if (doesMIDefinesPredicate(TargetPacket, DefsA)) {
2017 for (SmallVector<unsigned, 4>::iterator IA = DefsA.
begin(),
2020 for (SmallVector<unsigned, 8>::iterator IB = UsesB.
begin(),
2032 for (--MII; MII->isBundled(); --MII)
2033 if (MII->isBundle())
2044 for (++MII; MII != BBEnd && MII->isBundled() && !MII->isBundle(); ++MII) {
2047 if (doesMIDefinesPredicate(&*MII, DefsA)) {
2048 for (SmallVector<unsigned, 4>::iterator IA = DefsA.
begin(),
2051 for (SmallVector<unsigned, 8>::iterator IB = UsesB.
begin(),
2071bool HexagonGlobalSchedulerImpl::CanNewifiedBeUsedInBundle(
2073 MachineInstr *TargetPacket) {
2075 if (!TargetPacket || !TargetPacket->
isBundled())
2079 for (--MII; MII->isBundled(); --MII)
2080 if (MII->isBundle())
2084 for (++MII; MII != BBEnd && MII->isBundled() && !MII->isBundle(); ++MII) {
2089 SmallVector<unsigned, 4> DefsA;
2090 if (!doesMIDefinesPredicate(&*MII, DefsA))
2092 for (
auto &IA : DefsA)
2101void HexagonGlobalSchedulerImpl::setUsedRegs(BitVector &Set,
unsigned Reg) {
2103 for (MCSubRegIterator SubRegs(
Reg, QRI); SubRegs.isValid(); ++SubRegs)
2104 Set.reset(*SubRegs);
2108bool HexagonGlobalSchedulerImpl::AliasingRegs(
unsigned RegA,
unsigned RegB) {
2112 for (MCSubRegIterator SubRegs(RegA, QRI); SubRegs.isValid(); ++SubRegs)
2113 if (RegB == *SubRegs)
2116 for (MCSubRegIterator SubRegs(RegB, QRI); SubRegs.isValid(); ++SubRegs)
2117 if (RegA == *SubRegs)
2125 if (
MI->isDebugInstr())
2128 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2141 if (
MI->isDebugInstr())
2144 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2157void HexagonGlobalSchedulerImpl::updateKillAlongThePath(
2158 MachineBasicBlock *HomeBB, MachineBasicBlock *OriginBB,
2163 std::vector<MachineInstr *> &backtrack) {
2165 MachineInstr *
MI = &*Head;
2166 MachineBasicBlock *CurrentBB = OriginBB;
2167 SmallSet<unsigned, 8> KilledUseSet;
2169 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2170 const MachineOperand &MO =
MI->getOperand(i);
2182 if (KilledUseSet.
empty())
2192 <<
")kills. From BB (" << OriginBB->
getNumber() <<
")\n");
2194 assert(!backtrack.empty() &&
"Empty back track");
2200 for (
signed i = backtrack.size() - 1; i >= 0; --i) {
2202 << backtrack[i]->
getParent()->getNumber() <<
")\t";
2203 backtrack[i]->dump());
2204 if (CurrentBB != backtrack[i]->
getParent()) {
2206 <<
") to(" << backtrack[i]->getParent()->getNumber()
2212 if (*SI == CurrentBB)
2219 E = (*SI)->livein_end();
2221 if (KilledUseSet.
count((*I).PhysReg)) {
2223 <<
") is LiveIn along side exit.\n");
2224 KilledUseSet.
erase((*I).PhysReg);
2227 if (KilledUseSet.
empty())
2231 CurrentBB = backtrack[i]->getParent();
2235 if (backtrack[i] == &*TargetPacket)
2241 if (backtrack[i] == &*SourcePacket)
2245 if (backtrack[i]->isDebugInstr())
2251 SmallVector<unsigned, 4> Defs;
2252 SmallVector<unsigned, 8>
Uses;
2253 MachineInstr *MIU = backtrack[i];
2256 for (SmallVector<unsigned, 8>::iterator IA =
Uses.begin(), IAE =
Uses.end();
2258 if (KilledUseSet.
count(*IA)) {
2270 for (++MII; MII != End && MII->isInsideBundle(); ++MII)
2275 KilledUseSet.
erase(*IA);
2278 if (KilledUseSet.
empty())
2286void HexagonGlobalSchedulerImpl::addInstructionToExistingBundle(
2292 std::vector<MachineInstr *> &backtrack) {
2299 if (Outcast->isBundle() && Outcast->isBundledWithSucc())
2300 Outcast->unbundleFromSucc();
2307 if (memShufDisabled)
2315 for (
unsigned i = 0; i < backtrack.size(); ++i)
2316 if (backtrack[i] == &*Outcast)
2317 backtrack[i] = &*Head;
2320 if (NextMI == Outcast)
2323 TargetPacket = Head;
2324 HomeBB->
erase(Outcast);
2329void HexagonGlobalSchedulerImpl::removeInstructionFromExistingBundle(
2334 std::vector<MachineInstr *> &backtrack) {
2336 if (HomeBB->
empty()) {
2342 if (!SourceLocation->isBundle()) {
2343 LLVM_DEBUG(
dbgs() <<
"\t\t\tOriginal instruction was not bundled.\n\t\t\t";
2344 SourceLocation->dump());
2349 for (
unsigned i = 0; i < backtrack.size(); ++i) {
2350 if (backtrack[i] == &*SourceLocation) {
2352 assert((backtrack[i] == backtrack.back()) &&
"Lost back track");
2353 backtrack.pop_back();
2356 if (NextMI == SourceLocation)
2367 LLVM_DEBUG(
dbgs() <<
"\t\t\t[Rem] SourceLocation after bundle update: ";
2373 if (!SourceLocation->isBundledWithSucc()) {
2374 assert(!Head->isBundledWithSucc() && !Head->isBundledWithPred() &&
2380 unsigned BBSizeWithDbg = 0;
2384 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I) {
2386 if (!
I->isDebugInstr())
2397 if (Outcast->isBundle() && Outcast->isBundledWithSucc())
2398 Outcast->unbundleFromSucc();
2411 if (memShufDisabled)
2415 }
else if (
Size == 1) {
2417 if (BBSizeWithDbg > 1) {
2421 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I) {
2422 I->unbundleFromPred();
2424 if (!
I->isDebugInstr())
2432 if (Head->isBundledWithPred())
2433 Head->unbundleFromPred();
2434 if (Head->isBundledWithSucc())
2435 Head->unbundleFromSucc();
2442 SourceLocation = Head;
2446 for (
unsigned i = 0; i < backtrack.size(); ++i)
2447 if (backtrack[i] == &*Outcast)
2448 backtrack[i] = &*Head;
2451 if (NextMI == Outcast)
2454 HomeBB->
erase(Outcast);
2462 SE =
MBB->succ_end();
2464 LLVM_DEBUG(
dbgs() <<
"\tSuccessor BB (" << (*SI)->getNumber() <<
"):");
2466 E = (*SI)->livein_end();
2481 if (!
MBBI->isDebugInstr())
2491 if (!
MI || !
MI->isBranch() ||
MI->isBundle())
2494 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2504bool HexagonGlobalSchedulerImpl::AnalyzeBBBranches(MachineBasicBlock *
MBB,
2505 MachineBasicBlock *&
TBB,
2506 MachineInstr *&FirstTerm,
2507 MachineBasicBlock *&FBB,
2508 MachineInstr *&SecondTerm) {
2531 if (MII->isBranch())
2535 while (MII != MIE) {
2536 if (!MII->isBundle() && MII->isBranch()) {
2547 LLVM_DEBUG(
dbgs() <<
"\n\t\tCannot analyze BB with indirect branch.");
2550 if ((FirstTerm && FirstTerm->
getOpcode() == Hexagon::J2_jump &&
2552 (SecondTerm && SecondTerm->
getOpcode() == Hexagon::J2_jump &&
2555 dbgs() <<
"\n\t\tCannot analyze BB with a branch out of function.");
2560 SmallVector<MachineOperand, 4>
Cond;
2562 LLVM_DEBUG(
dbgs() <<
"\t\tFail to analyze with analyzeBranch.\n");
2564 else dbgs() <<
"None\n";);
2581 if (FirstTerm && SecondTerm &&
2590 }
else if (SecondTerm && SecondTerm->
getOpcode() == Hexagon::J2_jump &&
2603 <<
") FBB(" << FBB->
getNumber() <<
").\n");
2618 assert(MBBIter != MF.
end() &&
"I give up.");
2625 else if (FBB ==
S1) {
2631 MBBIter = MF.
begin();
2634 assert(MBBIter != MF.
end() &&
"Malformed BB with invalid successors");
2642 <<
") FBB(" << FBB->
getNumber() <<
").\n");
2646 assert(!FirstTerm &&
"Bad BB");
2650 if (!FBB && SecondTerm) {
2666 LLVM_DEBUG(
dbgs() <<
"Possibly the layout successor is an empty BB");
2670 LLVM_DEBUG(
dbgs() <<
"Malformed branch with useless branch condition";);
2673 }
else if (
TBB && !FBB) {
2689 else dbgs() <<
"\t\tFinal FBB(None)\n";);
2734 if (!Pred->isSuccessor(&
MBB))
2736 Pred->ReplaceUsesOfBlockWith(&
MBB, MFBB);
2747 bool RemoveLSIfPresent =
false;
2749 LLVM_DEBUG(
dbgs() <<
"\nNew firstterm conditional jump added to HomeBB";);
2753 LLVM_DEBUG(
dbgs() <<
"\nNew secondterm conditional jump added to HomeBB";);
2757 LLVM_DEBUG(
dbgs() <<
"\nBranch destination for pulled instruction is BB#"
2758 << Dest->getNumber(););
2763 LLVM_DEBUG(
dbgs() <<
"\nNew firstterm unconditional jump added to HomeBB";);
2766 RemoveLSIfPresent =
true;
2769 dbgs() <<
"\nNew secondterm unconditional jump added to HomeBB";);
2772 RemoveLSIfPresent =
true;
2779 if (RemoveLSIfPresent) {
2784 LLVM_DEBUG(
dbgs() <<
"\nRemoving LayoutSucc BB#" << HomeBBLS->getNumber()
2785 <<
"from list of successors";);
2794MachineInstr *HexagonGlobalSchedulerImpl::MoveAndUpdateLiveness(
2795 BasicBlockRegion *CurrentRegion, MachineBasicBlock *HomeBB,
2796 MachineInstr *InstrToMove,
bool NeedToNewify,
unsigned DepReg,
2797 bool MovingDependentOp, MachineBasicBlock *OriginBB,
2798 MachineInstr *OriginalInstruction, SmallVector<MachineOperand, 4> &
Cond,
2802 std::vector<MachineInstr *> &backtrack) {
2804 dbgs() <<
"\n...............[MoveAndUpdateLiveness]..............\n");
2807 OriginalInstruction->
dump());
2821 HomeBB->
erase(kill_it);
2832 std::list<MachineBasicBlock *> WorkList;
2835 for (std::vector<MachineInstr *>::iterator RI = backtrack.begin(),
2836 RIE = backtrack.end();
2838 WorkList.push_back((*RI)->getParent());
2847 TargetHead->getParent()->instr_end();
2848 bool LastInstructionInBundle =
false;
2850 TargetPacket, &*OutcastFrom, LastInstructionInBundle);
2858 MIBundleBuilder Bundle(&*TargetHead);
2868 if (OriginalInstruction->
getIterator() == TargetTail) {
2875 if (OutcastFrom->isBundledWithSucc()) {
2878 }
else if (OutcastFrom->isBundledWithPred()) {
2879 OutcastFrom->unbundleFromPred();
2881 HomeBB->
splice(MII, OriginBB, OutcastFrom);
2882 if (!MII->isBundledWithPred())
2883 MII->bundleWithPred();
2884 if (!LastInstructionInBundle && !MII->isBundledWithSucc())
2885 MII->bundleWithSucc();
2887 if (!MIIToPred->isBundledWithSucc())
2888 MIIToPred->bundleWithSucc();
2906 updateKillAlongThePath(HomeBB, OriginBB, MII, TargetTail, SourceLocation,
2907 TargetPacket, backtrack);
2916 DemoteToDotOld(&*MII);
2931 assert((DepReg < std::numeric_limits<unsigned>::max()) &&
2932 "Invalid pred reg value");
2934 <<
printReg(DepReg, QRI) <<
").\n");
2936 MII->setDesc(QII->get(NewOpcode));
2941 for (
unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
2942 MachineOperand &MO = MII->getOperand(i);
2947 if (DepReg == MO.
getReg())
2951 LLVM_DEBUG(
dbgs() <<
"\t\t\tNew predicated form:\t"; MII->dump());
2954 updateKillAlongThePath(HomeBB, OriginBB, MII, TargetTail, SourceLocation,
2955 TargetPacket, backtrack);
2959 addInstructionToExistingBundle(HomeBB, TargetHead, TargetTail, MII,
2960 TargetPacket, NextMI, backtrack);
2963 removeInstructionFromExistingBundle(OriginBB, ++OriginalHead, OriginalTail,
2964 SourceLocation, NextMI, MovingDependentOp,
2977 QII->
isEndLoopN(OriginalHead->getOpcode())) {
2983 if (OriginBB->
begin() !=
I) {
2985 if (
I->isBundled()) {
2986 if (!
I->isBundledWithSucc())
2987 I->bundleWithSucc();
2988 if (!OriginalHead->isBundledWithPred())
2989 OriginalHead->bundleWithPred();
2994 }
else if (MovingDependentOp &&
2996 if (OriginalHead->isBundled()) {
2998 J != OriginalTail && J->isInsideBundle() && !J->isBundle(); ++J) {
3000 if (MIsHaveTrueDependency(OriginalInstruction, &*J) &&
3003 DemoteToDotOld(&*J);
3008 if (MIsHaveTrueDependency(OriginalInstruction, &*OriginalHead) &&
3011 OriginalHead->dump());
3012 DemoteToDotOld(&*OriginalHead);
3025 for (std::list<MachineBasicBlock *>::iterator BBI = WorkList.begin(),
3026 BBIE = WorkList.end();
3027 BBI != BBIE; BBI++) {
3033 MachineBasicBlock *BB = WorkList.back();
3034 WorkList.pop_back();
3036 }
while (!WorkList.empty());
3039 if (OriginBB == HomeBB)
3040 return &*TargetHead;
3043 MachineBasicBlock *HomeTBB, *HomeFBB;
3044 MachineInstr *FTA = NULL, *STA = NULL;
3045 bool HomeBBAnalyzed = !AnalyzeBBBranches(HomeBB, HomeTBB, FTA, HomeFBB, STA);
3046 if (MII->isBranch()) {
3047 if (HomeBBAnalyzed) {
3048 UpdateCFG(HomeBB, OriginBB, &*MII, HomeTBB, HomeFBB, FTA, STA, MBPI);
3063 EmptyBBs.push_back(OriginBB);
3065 return &*TargetHead;
3069 MachineBasicBlock *CommonFBB = *OriginBB->
succ_begin();
3075 assert((OriginBB->
succ_size() == 2) &&
"Underimplemented 3way branch.");
3076 MachineBasicBlock *OriginTBB, *OriginFBB;
3077 MachineInstr *FTB = NULL, *STB = NULL;
3080 if (HomeBBAnalyzed &&
3081 !AnalyzeBBBranches(OriginBB, OriginTBB, FTB, OriginFBB, STB)) {
3082 assert(OriginFBB &&
"Missing Origin FBB");
3083 if (HomeFBB == OriginBB) {
3085 if (HomeTBB == OriginTBB) {
3088 }
else if (HomeTBB == OriginFBB) {
3099 }
else if (HomeTBB == OriginBB) {
3101 if (HomeFBB == OriginTBB) {
3104 }
else if (HomeFBB == OriginFBB) {
3126 return &*TargetHead;
3132HexagonGlobalSchedulerImpl::findInsertPositionInBundle(
3141 assert(MII->isBundle() &&
"Missing insert location");
3142 bool isDualJumpSecondCandidate = IsDualJumpSecondCandidate(
MI);
3143 LastInBundle =
false;
3145 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
3147 if (MII->isBranch() && (FirstBranch == BBEnd))
3151 if (isDualJumpSecondCandidate && IsDualJumpFirstCandidate(&*MII))
3152 DualJumpFirstCandidate = MII;
3153 LastBundledInstruction = MII;
3156 if (DualJumpFirstCandidate != BBEnd) {
3158 ++DualJumpFirstCandidate;
3159 if (DualJumpFirstCandidate == BBEnd ||
3160 DualJumpFirstCandidate == LastBundledInstruction)
3161 LastInBundle =
true;
3162 return DualJumpFirstCandidate;
3163 }
else if (FirstBranch != BBEnd) {
3168 }
else if (LastBundledInstruction != BBEnd) {
3169 LastInBundle =
true;
3170 return ++LastBundledInstruction;
3181 MachineInstr *
MI,
bool DeleteOldCopy) {
3185 assert(CurrentBB &&
"Corrupt instruction");
3192 MachineInstr *NewMI =
MI->getParent()->getParent()->CloneMachineInstr(
MI);
3199 if (DeleteOldCopy) {
3204 CurrentBB->
erase(kill_it);
3211 DemoteToDotOld(NewMI);
3216 if (TargetPacket->getParent() ==
MBB) {
3219 if (MII->isBundled()) {
3220 bool LastInBundle =
false;
3222 findInsertPositionInBundle(TargetPacket, NewMI, LastInBundle);
3223 MIBundleBuilder Bundle(&*TargetPacket);
3224 Bundle.insert(InsertBefore, NewMI);
3231 while (MII->isDebugInstr())
3234 if (MII->isBundled()) {
3235 MIBundleBuilder Bundle(&*MII);
3236 Bundle.insert(++MII, NewMI);
3244bool HexagonGlobalSchedulerImpl::MIsCondAssign(MachineInstr *BMI,
3246 SmallVector<unsigned, 4> &Defs) {
3250 SmallVector<unsigned, 4> CondDefs;
3251 SmallVector<unsigned, 8> CondUses;
3254 for (SmallVector<unsigned, 4>::iterator ID = Defs.
begin(), IDE = Defs.
end();
3256 for (SmallVector<unsigned, 4>::iterator CID = CondDefs.
begin(),
3257 CIDE = CondDefs.
end();
3258 CID != CIDE; ++CID) {
3259 if (AliasingRegs(*CID, *ID)) {
3273template <
typename ElemType,
typename IndexType>
3275 std::map<ElemType, std::vector<IndexType>> &Set1,
3276 std::map<ElemType, std::vector<IndexType>> &Set2,
3277 std::pair<std::vector<IndexType>, std::vector<IndexType>> &UnionSet,
3278 unsigned union_size = 100) {
3280 typename std::map<ElemType, std::vector<IndexType>>
::iterator PosIter_t;
3281 typedef typename std::vector<IndexType>::iterator IndexIter_t;
3282 std::vector<IndexType> &Union1 = UnionSet.first;
3283 std::vector<IndexType> &Union2 = UnionSet.second;
3284 Union1.resize(union_size, 0);
3285 Union2.resize(union_size, 0);
3287 typename std::vector<ElemType>::iterator iter =
Range.begin();
3288 while (iter !=
Range.end()) {
3289 if ((*iter)->isDebugInstr()) {
3294 PosIter_t set1_pos = Set1.find(*iter);
3295 assert(set1_pos != Set1.end() &&
3296 "Set1 should contain an entry for each element in Range.");
3297 IndexIter_t set1idx = set1_pos->second.begin();
3298 while (set1idx != set1_pos->second.end()) {
3299 Union1[*set1idx] = 1;
3302 PosIter_t set2_pos = Set2.find(*iter);
3303 assert(set2_pos != Set2.end() &&
3304 "Set2 should contain an entry for each element in Range.");
3305 IndexIter_t set2idx = set2_pos->second.begin();
3306 while (set2idx != set2_pos->second.end()) {
3307 Union2[*set2idx] = 1;
3324 MI->unbundleFromPred();
3333bool HexagonGlobalSchedulerImpl::canMIBeSpeculated(
3334 MachineInstr *
MI, MachineBasicBlock *ToBB, MachineBasicBlock *FromBB,
3335 std::vector<MachineInstr *> &backtrack) {
3358 if (!
MI->isDereferenceableInvariantLoad())
3363 SmallVector<unsigned, 4> Defs;
3364 SmallVector<unsigned, 8>
Uses;
3368 for (
unsigned R : Defs)
3381 LLVM_DEBUG(
dbgs() <<
"\tTarget succesor BB to check:\n"; (*SI)->dump());
3384 SIE = (*SI)->succ_end();
3385 SII != SIE; ++SII)(*SII)
3388 E = (*SI)->livein_end();
3390 for (SmallVector<unsigned, 4>::iterator ID = Defs.begin(),
3393 if (AliasingRegs((*I).PhysReg, *ID))
3400 E = (*SI)->instr_end();
3402 if (BI->isBundle() || BI->isDebugInstr())
3405 if (MIsCondAssign(&*BI,
MI, Defs))
3413 std::vector<MachineBasicBlock *> PathBB;
3414 for (
unsigned i = 0; i < backtrack.size(); ++i) {
3416 MachineBasicBlock *
MBB = backtrack[i]->getParent();
3417 if ((
MBB != FromBB) &&
3418 (std::find(PathBB.begin(), PathBB.end(),
MBB) == PathBB.end()))
3419 PathBB.push_back(
MBB);
3421 bool WaitingForTargetPacket =
true;
3423 std::vector<MachineInstr *> TraversalRange;
3431 for (
unsigned i = 0; i < PathBB.size(); ++i) {
3432 for (MII = PathBB[i]->instr_begin(); MII != PathBB[i]->instr_end(); ++MII) {
3436 if (backtrack[0] == &*MII)
3437 WaitingForTargetPacket =
false;
3438 if (WaitingForTargetPacket)
3440 if (MII->isBundle())
3447 if (MII->isCall() || MII->isReturn() ||
3448 (MII->getOpcode() == Hexagon::J2_jump && !MII->getOperand(0).isMBB()))
3451 TraversalRange.push_back(&*MII);
3457 std::pair<std::vector<unsigned>, std::vector<unsigned>> RangeDefUse;
3458 Unify(TraversalRange, MIDefSet, MIUseSet, RangeDefUse, QRI->getNumRegs());
3460 for (
unsigned j = 0;
j <
Uses.size(); ++
j)
3461 if (RangeDefUse.first[
Uses[j]]) {
3462 LLVM_DEBUG(
dbgs() <<
"\n\t\tUnresolved dependency along path to HOME for "
3468 for (
unsigned j = 0;
j < Defs.size(); ++
j)
3469 if (RangeDefUse.first[Defs[j]] || RangeDefUse.second[Defs[j]]) {
3470 LLVM_DEBUG(
dbgs() <<
"\n\t\tUnresolved dependency along path to HOME for "
3493bool HexagonGlobalSchedulerImpl::MoveMItoBundle(
3494 BasicBlockRegion *CurrentRegion,
3499 std::vector<MachineInstr *> &backtrack,
bool MovingDependentOp,
3500 bool PathInRegion) {
3501 MachineBasicBlock *HomeBB = TargetPacket->getParent();
3502 MachineBasicBlock *OriginBB = InstrToMove->
getParent();
3503 MachineBasicBlock *CurrentBB = OriginBB;
3504 MachineBasicBlock *CleanupBB = OriginBB;
3505 MachineBasicBlock *PreviousBB = OriginBB;
3506 MachineInstr *OriginalInstructionToMove = &*InstrToMove;
3508 assert(HomeBB &&
"Missing HomeBB");
3509 assert(OriginBB &&
"Missing OriginBB");
3511 LLVM_DEBUG(
dbgs() <<
"\n.........[MoveMItoBundle]..............\n");
3512 LLVM_DEBUG(
dbgs() <<
"\t\tInstrToMove :\t"; InstrToMove->dump());
3519 if (HomeBB == OriginBB) {
3535 for (
unsigned i = 0; i < backtrack.size(); ++i) {
3538 << backtrack[i]->
getParent()->getNumber() <<
")\t";
3539 backtrack[i]->dump());
3543 bool NeedCleanup =
false;
3544 bool NeedToPredicate =
false;
3545 bool MINeedToNewify =
false;
3546 unsigned DepReg = std::numeric_limits<unsigned>::max();
3547 bool isDualJump =
false;
3548 SmallVector<MachineOperand, 4>
Cond;
3549 SmallVector<MachineOperand, 4> PredCond;
3550 std::vector<MachineInstr *> PullUpPath;
3552 PullUpPath = backtrack;
3554 PullUpPath.push_back(&*TargetPacket);
3555 PullUpPath.push_back(&*InstrToMove);
3561 for (std::vector<MachineInstr *>::reverse_iterator RI = backtrack.rbegin(),
3562 RIE = backtrack.rend();
3566 MachineInstr *MIWH = *RI;
3569 InstrToMove->dump());
3571 CleanupBB->
erase(InstrToMove);
3574 if (canCauseStall(&*InstrToMove, MIWH)) {
3576 CleanupBB->
erase(InstrToMove);
3586 bool isBranchMIWH =
isBranch(MIWH);
3587 if (((&*SourceLocation != MIWH) && isBranchMIWH) ||
3591 PreviousBB = CurrentBB;
3595 MachineBasicBlock *PredTBB = NULL;
3596 MachineBasicBlock *PredFBB = NULL;
3607 if (!canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3610 CleanupBB->
erase(InstrToMove);
3614 SpeculatedIns.insert(
3615 std::make_pair(OriginalInstructionToMove, OriginBB));
3616 LLVM_DEBUG(
dbgs() <<
"\nSpeculatedInsToMove"; InstrToMove->dump());
3624 if (NeedToPredicate) {
3626 <<
"\tUnderimplemented pred for speculative move.\n");
3628 CleanupBB->
erase(InstrToMove);
3632 insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove, NeedCleanup);
3634 NeedToPredicate =
false;
3635 assert(!NeedToPredicate &&
"Need to handle predication for this case");
3636 CleanupBB = CurrentBB;
3640 bool LocalNeedPredication =
true;
3642 if (!isBranchMIWH && !PredTBB) {
3643 LLVM_DEBUG(
dbgs() <<
"\tDo not need predicate for this case.\n");
3644 LocalNeedPredication =
false;
3647 if (IsDualJumpSecondCandidate(&*InstrToMove) &&
3648 IsDualJumpFirstCandidate(TargetPacket)) {
3651 }
else if (LocalNeedPredication && (PredFBB != PreviousBB)) {
3657 if (PreviousBB != PredTBB) {
3662 CleanupBB->
erase(InstrToMove);
3667 <<
")InvertCondition("
3668 << (PreviousBB != PredTBB) <<
")\n");
3673 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3676 NeedToPredicate =
true;
3677 CleanupBB = CurrentBB;
3679 if (PredCond.
empty() &&
3682 InstrToMove->dump());
3689 isJumpOutOfRange(&*InstrToMove)) &&
3690 !tryAllocateResourcesForConstExt(&*InstrToMove,
false)) {
3693 <<
"\tEI Could not be added to the packet.\n");
3694 CleanupBB->
erase(InstrToMove);
3698 if (!ResourceTracker->canReserveResources(*InstrToMove) ||
3699 !shouldAddToPacket(*InstrToMove)) {
3702 CurrentBB->
erase(InstrToMove);
3707 if (NeedToNewify(InstrToMove, &DepReg, &*TargetPacket)) {
3708 if (isNewifiable(InstrToMove, DepReg, &*TargetPacket)) {
3709 MINeedToNewify =
true;
3711 <<
printReg(DepReg, QRI) <<
").\n");
3714 InstrToMove->dump());
3715 CleanupBB->
erase(InstrToMove);
3724 MIUseSet[OriginalInstructionToMove].push_back(
Cond[1].
getReg());
3728 "Update MIUseSet for new-value compare jumps");
3732 InstrToMove->dump());
3733 bool DistantSpeculation =
false;
3734 std::vector<MachineInstr *> NonPredPullUpPath;
3739 while (btidx < backtrack.size()) {
3740 const MachineBasicBlock *btBB = backtrack[btidx]->getParent();
3741 if ((btBB == PreviousBB) || (btBB == CurrentBB))
3742 NonPredPullUpPath.push_back(backtrack[btidx]);
3746 if (PreviousBB != CurrentBB) {
3747 if (*(PreviousBB->
pred_begin()) != CurrentBB) {
3749 DistantSpeculation =
true;
3751 <<
"\n\tMI not in immediate successor of BB#"
3752 << CurrentBB->
getNumber() <<
", MI is in BB#"
3756 "Region with a side entry");
3759 if (DistantSpeculation ||
3760 InstrToMove->mayLoad() || InstrToMove->mayStore() ||
3761 InstrToMove->hasUnmodeledSideEffects() ||
3762 !canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3763 NonPredPullUpPath)) {
3764 CleanupBB->
erase(InstrToMove);
3768 NeedToPredicate =
false;
3769 SpeculatedIns.insert(
3770 std::make_pair(OriginalInstructionToMove, OriginBB));
3772 InstrToMove->dump());
3779 InstrToMove->dump());
3782 InstrToMove->mayLoad() || InstrToMove->mayStore() ||
3783 InstrToMove->hasUnmodeledSideEffects() ||
3784 !canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3787 CleanupBB->
erase(InstrToMove);
3791 SpeculatedIns.insert(
3792 std::make_pair(OriginalInstructionToMove, OriginBB));
3794 InstrToMove->dump());
3797 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3800 CleanupBB = CurrentBB;
3805 <<
"\tCurrentBB:" << CurrentBB->
getNumber()
3806 <<
"\tPreviousBB:" << PreviousBB->
getNumber();
3808 <<
"\tPredFBB:" << PredFBB->
getNumber(););
3812 if (IsDualJumpSecondCandidate(&*InstrToMove)) {
3814 LLVM_DEBUG(
dbgs() <<
"\tUnderimplemented dual jump formation.\n");
3816 CleanupBB->
erase(InstrToMove);
3823 CleanupBB->
erase(InstrToMove);
3826 SpeculatedIns.insert(
3827 std::make_pair(OriginalInstructionToMove, OriginBB));
3829 InstrToMove->dump());
3831 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3834 NeedToPredicate =
false;
3835 CleanupBB = CurrentBB;
3843 if (MIWH == backtrack.front()) {
3854 if (!(MovingDependentOp && (MIWH == &*SourceLocation)) &&
3855 !canReorderMIs(MIWH, &*InstrToMove)) {
3857 CleanupBB->
erase(InstrToMove);
3864 isJumpOutOfRange(&*InstrToMove)) {
3865 if (!tryAllocateResourcesForConstExt(&*InstrToMove))
3874 if (MovingDependentOp)
dbgs() <<
"dependent op";
dbgs() <<
": ";
3875 InstrToMove->dump();
dbgs() <<
"To BB:\n"; HomeBB->
dump();
3876 dbgs() <<
"From BB:\n"; OriginBB->
dump());
3880 HexagonNumPullUps++;
3882 HexagonNumDualJumps++;
3888 insertTempCopy(HomeBB, TargetPacket, &*InstrToMove, NeedCleanup);
3896 if (!TargetPacket->isBundle()) {
3899 std::next(InstrToMove));
3906 for (
unsigned i = 0; i < backtrack.size(); ++i)
3907 if (backtrack[i] == &*TargetPacket)
3908 backtrack[i] = &*MII;
3911 if (NextMI == TargetPacket)
3917 MoveAndUpdateLiveness(CurrentRegion, HomeBB, &*InstrToMove, MINeedToNewify,
3918 DepReg, MovingDependentOp, OriginBB,
3919 OriginalInstructionToMove, PredCond, SourceLocation,
3920 TargetPacket, NextMI, backtrack);
3929bool HexagonGlobalSchedulerImpl::isBranchWithinRegion(
3930 BasicBlockRegion *CurrentRegion, MachineInstr *
MI) {
3931 assert(
MI &&
MI->isBranch() &&
"Missing call info");
3935 <<
") Branch instr:\t";
3945 MachineBasicBlock *NextRegionBB;
3946 MachineBasicBlock *
TBB, *FBB;
3947 MachineInstr *FirstTerm = NULL;
3948 MachineInstr *SecondTerm = NULL;
3950 if (AnalyzeBBBranches(
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
3983 else dbgs() <<
"None\n";);
3995 if (!NextRegionBB) {
4004 if (
MI == FirstTerm) {
4006 <<
") NextBB in the region(" << NextRegionBB->
getNumber()
4008 return (
TBB == NextRegionBB);
4010 assert(FBB &&
"Corrupt BB layout");
4014 if ((
MI != SecondTerm)) {
4015 LLVM_DEBUG(
dbgs() <<
"\t\tDual terminator not matching SecondTerm.\n");
4020 <<
") NextBB in the region(" << NextRegionBB->
getNumber()
4022 return (FBB == NextRegionBB);
4029bool HexagonGlobalSchedulerImpl::isJumpOutOfRange(MachineInstr *UnCond,
4030 MachineInstr *
Cond) {
4031 if (!UnCond || !UnCond->
isBranch())
4034 MachineBasicBlock *UnCondBB = UnCond->
getParent();
4035 MachineBasicBlock *CondBB =
Cond->getParent();
4041 unsigned InstOffset = BlockToInstOffset[UnCondBB];
4042 unsigned Distance = 0;
4049 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4050 SmallVector<MachineOperand, 4> CondList;
4060 if (
TBB && (
Cond == FirstTerm)) {
4062 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[
TBB]) +
4071MachineInstr *HexagonGlobalSchedulerImpl::findBundleAndBranch(
4076 MachineInstr *CondBranch = NULL;
4080 MII != MBBEnd; ++MII) {
4081 MachineInstr *
MI = &*MII;
4082 if (MII->isConditionalBranch()) {
4089 if (!MII->isBundled())
4092 for (--MII; MII->isBundled(); --MII)
4093 if (MII->isBundle()) {
4105bool HexagonGlobalSchedulerImpl::pullUpPeelBBLoop(MachineBasicBlock *PredBB,
4106 MachineBasicBlock *LoopBB) {
4109 if (!LoopBB || !PredBB)
4124 MachineBasicBlock *SuccBB = NULL;
4128 if (*SI != LoopBB) {
4137 MachineInstr *PredCondBranch = NULL;
4138 PredCondBranch = findBundleAndBranch(PredBB, PredBundle);
4139 if (!PredCondBranch)
4141 if (PredBundle == PredBB->
end())
4149 while (FMI->isDebugInstr())
4152 MachineInstr *RegMI = &*FMI;
4156 if (TfrOpcode != Hexagon::A2_tfr && TfrOpcode != Hexagon::A2_tfr)
4165 BasicBlockRegion PUR(BasicBlockRegion(
TII, QRI, PredBB));
4170 if (!ResourcesAvailableInBundle(&PUR, PredBundle))
4173 CurrentState.HomeBundle);
4176 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4177 SmallVector<MachineOperand, 4>
Cond;
4184 MachineBasicBlock *LTBB = NULL, *LFBB = NULL;
4185 SmallVector<MachineOperand, 4> LCond;
4194 MachineInstr *InstrToMove =
4195 &*insertTempCopy(PredBB, PredBundle, RegMI,
false);
4196 if (!canAddMIToThisPacket(InstrToMove, PredBundlePkt)) {
4208 unsigned DepReg = 0;
4209 if (NeedToNewify(InstrToMove->
getIterator(), &DepReg, &*PredBundle) &&
4210 !isNewifiable(InstrToMove->
getIterator(), DepReg, &*PredBundle)) {
4221 InstrToMove->
setDesc(QII->get(NewOpcode));
4222 if (!incrementalAddToPacket(*InstrToMove)) {
4229 MachineInstr *LoopCondBranch = NULL;
4230 LoopCondBranch = findBundleAndBranch(LoopBB, LoopBundle);
4231 if (!LoopCondBranch)
4233 if (LoopBundle == LoopBB->
end())
4239 if (!ResourcesAvailableInBundle(&PUR, LoopBundle))
4242 CurrentState.HomeBundle);
4245 MachineInstr *InstrToSink =
4246 &*insertTempCopy(LoopBB, LoopBundle, RegMI,
false);
4247 if (!canAddMIToThisPacket(InstrToSink, LoopBundlePkt)) {
4261 if (NeedToNewify(InstrToSink->
getIterator(), &DepReg, &*LoopBundle) &&
4262 !isNewifiable(InstrToSink->
getIterator(), DepReg, &*LoopBundle)) {
4272 InstrToSink->
setDesc(QII->get(NewOpcode));
4273 if (!incrementalAddToPacket(*InstrToSink)) {
4295bool HexagonGlobalSchedulerImpl::performPullUpCFG(
MachineFunction &Fn) {
4298 if (std::next(
F.begin()) ==
F.end())
4305 MachineBasicBlock *PrevBlock = NULL;
4306 MachineBasicBlock *JumpBlock = NULL;
4309 MachineBasicBlock *FallBlock = &*
MBB;
4310 if (PrevBlock && JumpBlock) {
4311 Changed |= pullUpPeelBBLoop(PrevBlock, JumpBlock);
4313 PrevBlock = JumpBlock;
4314 JumpBlock = FallBlock;
4320 std::vector<unsigned> Defs;
4321 std::vector<unsigned>
Uses;
4325 MIter != MBBIter->instr_end(); ++MIter) {
4326 if (MIter->isBundle() || MIter->isDebugInstr())
4329 MIUseDefSet(&*MIter, Defs,
Uses);
4331 for (
unsigned i = 0; i < Defs.size(); ++i)
dbgs()
4334 for (
unsigned i = 0; i <
Uses.size(); ++i)
dbgs()
4336 MIDefSet[&*MIter] = Defs;
4337 MIUseSet[&*MIter] =
Uses;
4353MachineBasicBlock *HexagonGlobalSchedulerImpl::optimizeBranches(
4354 MachineBasicBlock *
MBB, MachineBasicBlock *
TBB, MachineInstr *FirstTerm,
4355 MachineBasicBlock *FBB) {
4366 MachineInstr *TBBMIb = &*
TBB->getFirstNonDebugInstr();
4367 if (TBBMIb->
getOpcode() == Hexagon::J2_jump &&
4370 if (
TBB == NewTarget)
4375 int64_t InstOffset =
4377 unsigned Distance = (unsigned)std::abs(
4378 InstOffset - BlockToInstOffset.
find(NewTarget)->second);
4381 <<
" out of range.");
4387 if (!
TBB->hasAddressTaken() && !
TBB->isEHPad() &&
TBB->pred_size() == 1) {
4390 TBB->removeSuccessor(
TBB->succ_begin());
4414 if (FBBMIb->
getOpcode() == Hexagon::J2_jump &&
4423 int64_t InstOffset =
4425 unsigned Distance = (unsigned)std::abs(
4426 InstOffset - BlockToInstOffset.
find(NewTarget)->second);
4429 <<
" out of range.");
4448bool HexagonGlobalSchedulerImpl::performExposedOptimizations(
4455 std::vector<MachineBasicBlock *>::iterator ebb = EmptyBBs.begin();
4456 while (ebb != EmptyBBs.end()) {
4459 <<
") from parent.\n");
4460 (*ebb)->eraseFromParent();
4463 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4464 MachineInstr *FirstTerm = NULL, *SecondTerm = NULL;
4466 SmallVector<MachineBasicBlock *, 4> Erase;
4468 for (MachineBasicBlock &
MBB : Fn) {
4470 AnalyzeBBBranches(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4477 if (
TBB && FirstTerm &&
4478 removeRedundantBranches(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4483 if (FirstTerm && SecondTerm &&
4484 optimizeDualJumps(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4489 if (
TBB && FBB && FirstTerm && !SecondTerm) {
4490 MachineBasicBlock *MBBToErase =
4491 optimizeBranches(&
MBB,
TBB, FirstTerm, FBB);
4499 for (MachineBasicBlock *
MBB : Erase)
4507bool HexagonGlobalSchedulerImpl::removeRedundantBranches(
4508 MachineBasicBlock *
MBB, MachineBasicBlock *
TBB, MachineInstr *FirstTerm,
4509 MachineBasicBlock *FBB, MachineInstr *SecondTerm) {
4510 bool Analyzed =
false;
4512 MachineInstr *Head = NULL, *ToErase = NULL;
4513 if (!FBB && (FirstTerm->
getOpcode() == Hexagon::J2_jump) &&
4517 dbgs() <<
"\nRemoving Uncond. jump to the layout successor in BB#"
4519 ToErase = FirstTerm;
4520 }
else if (SecondTerm && (
TBB == FBB) &&
4521 (SecondTerm->
getOpcode() == Hexagon::J2_jump)) {
4530 if (++FirstTermIter == SecondTermIter) {
4531 LLVM_DEBUG(
dbgs() <<
"\nRemoving multiple branching to same target in BB#"
4535 ToErase = FirstTerm;
4537 }
else if (SecondTerm && (SecondTerm->
getOpcode() == Hexagon::J2_jump) &&
4543 ToErase = SecondTerm;
4550 LLVM_DEBUG(
dbgs() <<
"\nRemoving Cond. jump to the layout successor in BB#"
4552 ToErase = SecondTerm;
4556 if (ToErase->isBundled()) {
4558 ToErase->eraseFromBundle();
4561 ToErase->eraseFromParent();
4575bool HexagonGlobalSchedulerImpl::optimizeDualJumps(MachineBasicBlock *
MBB,
4576 MachineBasicBlock *
TBB,
4577 MachineInstr *FirstTerm,
4578 MachineBasicBlock *FBB,
4579 MachineInstr *SecondTerm) {
4582 bool Analyzed =
false;
4585 (SecondTerm->
getOpcode() == Hexagon::J2_jump)) {
4597 MachineInstr *
SI = &*SII;
4598 std::map<MachineInstr *, MachineBasicBlock *>::iterator MIMoved;
4599 MIMoved = SpeculatedIns.find(SI);
4600 if ((MIMoved != SpeculatedIns.end()) &&
4601 (MIMoved->second !=
SI->getParent())) {
4614 int64_t InstOffset =
4617 (unsigned)std::abs(InstOffset - BlockToInstOffset.
find(FBB)->second) +
4621 <<
" out of range.");
4635 MachineInstr *SecondHead, *FirstHead;
4646 else if (!FirstHead) {
4650 }
else if (FirstHead == SecondHead) {
4652 assert((FirstHead && SecondHead) &&
"Unbundled Instruction");
4654 if (SecondHead->getBundleSize() < 2)
4668bool HexagonGlobalSchedulerImpl::ResourcesAvailableInBundle(
4669 BasicBlockRegion *CurrentRegion,
4674 if (!TargetPacket->isBundle()) {
4675 if (ignoreInstruction(&*MII) || isSoloInstruction(*MII))
4680 if (MII->isBranch() && !isBranchWithinRegion(CurrentRegion, &*MII))
4686 initPacketizerState();
4687 ResourceTracker->clearResources();
4688 CurrentState.addHomeLocation(MII);
4689 return incrementalAddToPacket(*MII);
4695 initPacketizerState();
4696 ResourceTracker->clearResources();
4697 CurrentState.addHomeLocation(MII);
4699 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
4700 if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
4701 MII->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
4702 MII->getOpcode() == TargetOpcode::CFI_INSTRUCTION || MII->isEHLabel())
4715 if (MII->isBranch() && !isBranchWithinRegion(CurrentRegion, &*MII))
4718 if (!incrementalAddToPacket(*MII))
4721 return ResourceTracker->canReserveResources(*Nop);
4725bool HexagonGlobalSchedulerImpl::isCompoundPair(MachineInstr *MIa,
4726 MachineInstr *MIb) {
4733 (Opcb == Hexagon::A2_tfr || Opcb == Hexagon::A2_tfrsi))
4737 (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
4746inline bool HexagonGlobalSchedulerImpl::multipleBranchesFromToBB(
4747 MachineBasicBlock *BB)
const {
4751 return ((Jumpers.
size() == 1) && !Jumpers[0]->isUnconditionalBranch());
4756bool HexagonGlobalSchedulerImpl::findPullUpCandidates(
4759 std::vector<MachineInstr *> &backtrack,
unsigned MaxCandidates = 1) {
4761 const HexagonInstrInfo *QII = (
const HexagonInstrInfo *)
TII;
4762 MachineBasicBlock *FromThisBB = FromHere->getParent();
4763 bool MovingDependentOp =
false;
4767 if (CurrentState.haveCandidates() >= MaxCandidates)
4773 if (FromHere->isBundle()) {
4775 for (++MII; MII != FromThisBB->
instr_end() && MII->isInsideBundle();
4777 if (MII->isDebugInstr())
4780 << MII->getParent()->getNumber() <<
"): ";
4784 if (!canThisMIBeMoved(&*MII, WorkPoint, MovingDependentOp,
CostBenefit))
4788 if (canAddMIToThisPacket(&*InstrToMove, CurrentState.HomeBundle)) {
4793 if (MII->isCompare())
4796 for (
unsigned i = 0; i < CurrentState.HomeBundle.size(); i++) {
4797 if (QII->
isDuplexPair(*CurrentState.HomeBundle[i], *MII)) {
4801 if (isCompoundPair(CurrentState.HomeBundle[i], &*MII)) {
4807 CurrentState.addPullUpCandidate(InstrToMove, WorkPoint, backtrack,
4816 else if (canThisMIBeMoved(&*FromHere, WorkPoint, MovingDependentOp,
4819 if (canAddMIToThisPacket(&*InstrToMove, CurrentState.HomeBundle)) {
4822 if (InstrToMove->isCompare())
4828 for (
unsigned i = 0; i < CurrentState.HomeBundle.size(); i++) {
4829 if (QII->
isDuplexPair(*CurrentState.HomeBundle[i], *InstrToMove)) {
4833 if (isCompoundPair(CurrentState.HomeBundle[i], &*InstrToMove)) {
4839 CurrentState.addPullUpCandidate(InstrToMove, WorkPoint, backtrack,
4842 LLVM_DEBUG(
dbgs() <<
"\tNo resources for single in the target packet.\n");
4850bool HexagonGlobalSchedulerImpl::tryMultipleInstructions(
4852 std::vector<BasicBlockRegion *>::iterator &CurrentRegion,
4859 bool MovingDependentOp =
false;
4860 std::vector<MachineInstr *> backtrack;
4864 std::sort(CurrentState.PullUpCandidates.begin(),
4865 CurrentState.PullUpCandidates.end(), PullUpCandidateSorter());
4868 for (SmallVector<PullUpCandidate *, 4>::iterator
4869 I = CurrentState.PullUpCandidates.begin(),
4870 E = CurrentState.PullUpCandidates.end();
4872 (*I)->populate(MII, WorkPoint, backtrack, MovingDependentOp);
4874 MachineBasicBlock *FromThisBB = MII->
getParent();
4875 MachineBasicBlock *ToThisBB = WorkPoint->getParent();
4878 LLVM_DEBUG(
dbgs() <<
"\tDependent(" << MovingDependentOp <<
") FromBB("
4880 << ToThisBB->
getNumber() <<
") to this packet:\n";
4884 if (MII->isInsideBundle()) {
4885 while (!FromHereII->isBundle())
4891 if (MoveMItoBundle(*CurrentRegion, MII, NextMI, WorkPoint, FromHere,
4892 backtrack, MovingDependentOp, PathInRegion)) {
4898 FromThisBBEnd = FromThisBB->
end();
4899 ToThisBBEnd = ToThisBB->
end();
4913 if (MoveMItoBundle(*CurrentRegion, MII, NextMI, WorkPoint, FromHere,
4914 backtrack, MovingDependentOp, PathInRegion)) {
4921 FromThisBBEnd = FromThisBB->
end();
4922 ToThisBBEnd = ToThisBB->
end();
4949bool HexagonGlobalSchedulerImpl::performPullUp() {
4950 std::vector<MachineInstr *> backtrack;
4956 for (std::vector<BasicBlockRegion *>::iterator
4957 CurrentRegion = PullUpRegions.begin(),
4958 E = PullUpRegions.end();
4959 CurrentRegion !=
E; ++CurrentRegion) {
4961 LLVM_DEBUG(
dbgs() <<
"\n\nRegion with(" << (*CurrentRegion)->size()
4969 for (
auto ToThisBB = (*CurrentRegion)->getRootMBB(),
4970 LastBBInRegion = (*CurrentRegion)->getLastMBB();
4971 ToThisBB != LastBBInRegion; ++ToThisBB) {
4975 if (multipleBranchesFromToBB(*ToThisBB))
4978 auto FromThisBB = ToThisBB;
4983 << (*ToThisBB)->getNumber() <<
")\n";
4984 (*ToThisBB)->dump());
4987 while (
MI != ToThisBBEnd) {
4993 while (ResourcesAvailableInBundle(*CurrentRegion, WorkPoint)) {
4995 << (*ToThisBB)->getNumber() <<
"):\n";
5009 FromThisBB = ToThisBB;
5010 FromHere = WorkPoint;
5012 FromThisBBEnd = (*FromThisBB)->end();
5019 backtrack.push_back(&*
I);
5021 FromThisBB = ToThisBB;
5023 FromHere = (*FromThisBB)->begin();
5024 FromThisBBEnd = (*FromThisBB)->end();
5031 backtrack.push_back(&*
I);
5038 if (FromHere == FromThisBBEnd) {
5042 LastBBInRegion = (*CurrentRegion)->getLastMBB();
5043 if (FromThisBB == LastBBInRegion)
5047 (*FromThisBB)->dump());
5048 FromThisBBEnd = (*FromThisBB)->end();
5049 FromHere = (*FromThisBB)->begin();
5050 if (FromThisBBEnd == FromHere)
5054 if ((*FromHere).isDebugInstr()) {
5059 backtrack.push_back(&*FromHere);
5060 if (!findPullUpCandidates(WorkPoint, FromHere, backtrack,
5066 if (!tryMultipleInstructions( WorkPoint, CurrentRegion,
MI,
5067 ToThisBBEnd, FromThisBBEnd))
5072 LastBBInRegion = (*CurrentRegion)->getLastMBB();
5085 std::vector<std::pair<MachineBasicBlock *, MachineBasicBlock *>>
5087 UnlikelyWork.reserve((*CurrentRegion)->size());
5088 for (
auto ToIt = (*CurrentRegion)->getRootMBB(),
5089 End = (*CurrentRegion)->getLastMBB();
5090 ToIt != End; ++ToIt) {
5091 MachineBasicBlock *ToBB = *ToIt;
5092 MachineBasicBlock *SecondBest = getNextPURBB(ToBB,
true);
5094 UnlikelyWork.emplace_back(ToBB, SecondBest);
5097 for (
auto [ToBB, SecondBest] : UnlikelyWork) {
5102 (*CurrentRegion)->addBBtoRegion(SecondBest);
5110 while (
MI != ToThisBBEnd) {
5116 while (ResourcesAvailableInBundle(*CurrentRegion, WorkPoint)) {
5121 FromHere = SecondBest->
begin();
5122 FromThisBBEnd = SecondBest->
end();
5130 backtrack.push_back(&*
I);
5135 if (FromHere == FromThisBBEnd) {
5137 <<
"\tOnly do one successor for the second try\n");
5140 if ((*FromHere).isDebugInstr()) {
5145 backtrack.push_back(&*FromHere);
5146 if (!findPullUpCandidates(WorkPoint, FromHere, backtrack,
5152 if (!tryMultipleInstructions( WorkPoint, CurrentRegion,
MI,
5153 ToThisBBEnd, FromThisBBEnd,
false))
5162bool HexagonGlobalSchedulerImpl::incrementalAddToPacket(MachineInstr &
MI) {
5164 LLVM_DEBUG(
dbgs() <<
"\t[AddToPacket] (" << CurrentPacketMIs.size()
5168 if (!ResourceTracker->canReserveResources(
MI) || !shouldAddToPacket(
MI))
5171 ResourceTracker->reserveResources(
MI);
5172 CurrentPacketMIs.push_back(&
MI);
5173 CurrentState.HomeBundle.push_back(&
MI);
5176 isJumpOutOfRange(&
MI)) {
5182 if (ResourceTracker->canReserveResources(*Ext)) {
5183 ResourceTracker->reserveResources(*Ext);
5184 LLVM_DEBUG(
dbgs() <<
"\t[AddToPacket] (" << CurrentPacketMIs.size()
5185 <<
") adding:\t immext_i\n");
5186 CurrentPacketMIs.push_back(Ext);
5187 CurrentState.HomeBundle.push_back(Ext);
5197void HexagonGlobalSchedulerImpl::checkBundleCounts(
MachineFunction &Fn) {
5201 unsigned BundleLimit = 4;
5204 MBBi != MBBe; ++MBBi) {
5207 ME = MBBi->instr_end();
5209 if (
MI->isBundle()) {
5215 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
5216 if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
5217 MII->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
5218 MII->getOpcode() == TargetOpcode::CFI_INSTRUCTION ||
5219 MII->isEHLabel() || QII->
isEndLoopN(MII->getOpcode())) {
5229 assert(0 &&
"Bundle size exceeded");
5238unsigned HexagonGlobalSchedulerImpl::countCompounds(
MachineFunction &Fn) {
5239 unsigned CompoundCount = 0;
5240 [[maybe_unused]]
unsigned DuplexCount = 0;
5241 [[maybe_unused]]
unsigned InstOffset = 0;
5252 if (
MI->isDebugInstr())
5254 if (
MI->isBundle()) {
5257 MachineInstr *FirstCompound = NULL, *SecondCompound = NULL;
5258 MachineInstr *FirstDuplex = NULL, *SecondDuplex = NULL;
5261 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
5263 if (MII->isDebugInstr())
5266 InstOffset += QII->
getSize(*MII);
5268 if (!FirstCompound) {
5269 FirstCompound = &*MII;
5272 SecondCompound = &*MII;
5278 FirstDuplex = &*MII;
5281 SecondDuplex = &*MII;
5288 if (SecondCompound) {
5289 if (isCompoundPair(FirstCompound, SecondCompound)) {
5290 LLVM_DEBUG(
dbgs() <<
"Compound pair (" << CompoundCount <<
")\n");
5311 LLVM_DEBUG(
dbgs() <<
"Total compound(" << CompoundCount <<
") duplex("
5312 << DuplexCount <<
")\n");
5313 return CompoundCount;
5321 return new HexagonGlobalScheduler();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator MBBI
static const Function * getParent(const Value *V)
bbsections Prepares for basic block by splitting functions into clusters of basic static false void updateBranches(MachineFunction &MF, const SmallVector< MachineBasicBlock * > &PreLayoutFallThroughs)
static bool IsEmptyBlock(MachineBasicBlock *MBB)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static InstructionCost getCost(Instruction &Inst, TTI::TargetCostKind CostKind, TargetTransformInfo &TTI)
static unsigned InstrCount
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static void DumpLinked(MachineInstr *MI)
static bool IsSchedBarrier(const MachineInstr *MI)
static cl::opt< bool > EnableSpeculativePullUp("enable-speculative-pull-up", cl::Hidden, cl::desc("Enable speculation during Hexagon pull-up pass"))
static cl::opt< bool > ForceNoopHazards("force-noop-hazards", cl::Hidden, cl::init(false), cl::desc("Force noop hazards in scheduler"))
static MachineBasicBlock::instr_iterator getHexagonFirstInstrTerminator(MachineBasicBlock *MBB)
static void debugLivenessForBB(const MachineBasicBlock *MBB, const TargetRegisterInfo *TRI)
static void markKillReg(MachineInstr *MI, unsigned Reg)
Find use with this reg, and unmark the kill flag.
static MachineBasicBlock * getBranchDestination(MachineInstr *MI)
Treat given instruction as a branch, go through its operands and see if any of them is a BB address.
static cl::opt< bool > AllowBBPeelPullUp("enable-bb-peel-pull-up", cl::Hidden, cl::init(true), cl::desc("Peel a reg copy out of a BBloop"))
static cl::opt< bool > OneComplexPerPacket("single-complex-packet", cl::Hidden, cl::desc("Allow only one complex instruction in a packet"))
static void updatePredecessors(MachineBasicBlock &MBB, MachineBasicBlock *MFBB)
Rewrite all predecessors of the old block to go to the fallthrough instead.
static void parseOperands(MachineInstr *MI, SmallVector< unsigned, 4 > &Defs, SmallVector< unsigned, 8 > &Uses)
Gather register def/uses from MI.
static bool selectBestBB(BlockFrequency &BBaFreq, unsigned BBaSize, BlockFrequency &BBbFreq, unsigned BBbSize)
Select best candidate to form regions.
static bool MIMustNotBePulledUp(MachineInstr *MI)
static cl::opt< bool > PreventDuplexSeparation("prevent-duplex-separation", cl::Hidden, cl::init(true), cl::desc("Do not destroy existing duplexes during pull up"))
static cl::opt< bool > AllowCmpBranchLoads("cmp-branch-loads-pull-up", cl::Hidden, cl::init(true), cl::desc("Allow compare-branch loads during Hexagon pull-up pass"))
static void DumpPacket(MachineBasicBlock::instr_iterator MII)
static cl::opt< unsigned > SecondaryCandidateQueueSize("pull-up-sec-queue-size", cl::Hidden, cl::init(2))
static bool isDelayedUseException(MachineInstr *MIa, MachineInstr *MIb)
Some apparent dependencies are not actually restricting us since there is a delay between assignment ...
static cl::opt< bool > AllowUnlikelyPath("unlikely-path-pull-up", cl::Hidden, cl::init(true), cl::desc("Allow unlikely path pull up"))
static const unsigned SafetyBuffer
static cl::opt< bool > EnableLocalPullUp("enable-local-pull-up", cl::Hidden, cl::init(true), cl::desc("Enable same BB pull during Hexagon pull-up pass"))
static cl::opt< bool > SpeculateNonPredInsn("speculate-non-pred-insn", cl::Hidden, cl::init(true), cl::desc("Speculate non-predicable instructions in parent BB"))
static void UpdateCFG(MachineBasicBlock *HomeBB, MachineBasicBlock *OriginBB, MachineInstr *MII, MachineBasicBlock *HomeTBB, MachineBasicBlock *HomeFBB, MachineInstr *FTA, MachineInstr *STA, const MachineBranchProbabilityInfo *MBPI)
static cl::opt< bool > WarnOnBundleSize("warn-on-bundle-size", cl::Hidden, cl::desc("Hexagon check bundles and warn on size"))
static unsigned nonDbgBundleSize(MachineBasicBlock::iterator &TargetPacket)
static bool isGlobalMemoryObject(MachineInstr *MI)
Return true if MI is an instruction we are unable to reason about (like something with unmodeled memo...
void Unify(std::vector< ElemType > Range, std::map< ElemType, std::vector< IndexType > > &Set1, std::map< ElemType, std::vector< IndexType > > &Set2, std::pair< std::vector< IndexType >, std::vector< IndexType > > &UnionSet, unsigned union_size=100)
static cl::opt< bool > PreventCompoundSeparation("prevent-compound-separation", cl::Hidden, cl::desc("Do not destroy existing compounds during pull up"))
static cl::opt< bool > AllowDependentPullUp("enable-dependent-pull-up", cl::Hidden, cl::init(true), cl::desc("Perform dual jump formation during pull up"))
static cl::opt< unsigned > MainCandidateQueueSize("pull-up-main-queue-size", cl::Hidden, cl::init(8))
static cl::opt< bool > DisableCheckBundles("disable-hexagon-check-bundles", cl::Hidden, cl::init(true), cl::desc("Disable Hexagon check bundles pass"))
static cl::opt< bool > PerformDualJumps("dual-jump-in-pull-up", cl::Hidden, cl::init(true), cl::desc("Perform dual jump formation during pull up"))
static bool MIsNeedChainEdge(AliasAnalysis *AA, const TargetInstrInfo *TII, MachineInstr *MIa, MachineInstr *MIb)
This returns true if the two MIs could be memory dependent.
static void UpdateBundle(MachineInstr *BundleHead)
static bool IsIndirectCall(const MachineInstr *MI)
static cl::opt< bool > DisablePullUp("disable-pull-up", cl::Hidden, cl::desc("Disable Hexagon pull-up pass"))
static cl::opt< bool > AllowSpeculateLoads("speculate-loads-on-pull-up", cl::Hidden, cl::init(true), cl::desc("Allow speculative loads during Hexagon pull-up pass"))
static cl::opt< bool > OneFloatPerPacket("single-float-packet", cl::Hidden, cl::desc("Allow only one single floating point instruction in a packet"))
static void unmarkKillReg(MachineInstr *MI, unsigned Reg)
Find use with this reg, and unmark the kill flag.
static bool MIShouldNotBePulledUp(MachineInstr *MI)
static bool isUnsafeMemoryObject(MachineInstr *MI)
static cl::opt< bool > PostPullUpOpt("post-pull-up-opt", cl::Hidden, cl::init(true), cl::desc("Enable opt. exposed by pull-up e.g., remove redundant jumps"))
#define HEXAGON_INSTR_SIZE
static constexpr Value * getValue(Ty &ValueOrUse)
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static bool isBranch(unsigned Opcode)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
static bool InBlock(const Value *V, const BasicBlock *BB)
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
The possible results of an alias query.
@ NoAlias
The two locations do not alias at all.
LLVM_ABI AnalysisUsage & addRequiredID(const void *ID)
AnalysisUsage & addRequired()
void RemoveBBFromRegion(MachineBasicBlock *MBB)
MachineBasicBlock * findNextMBB(MachineBasicBlock *MBB)
LivenessInfo * getLivenessInfoForBB(MachineBasicBlock *MBB)
void addBBtoRegion(MachineBasicBlock *MBB)
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
iterator find(const_arg_type_t< KeyT > Val)
FunctionPass class - This class is used to implement most global optimizations.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
bool isCompoundBranchInstr(const MachineInstr &MI) const
bool isDuplexPair(const MachineInstr &MIa, const MachineInstr &MIb) const
Symmetrical. See if these two instructions are fit for duplex pair.
bool isJumpR(const MachineInstr &MI) const
bool invertAndChangeJumpTarget(MachineInstr &MI, MachineBasicBlock *NewTarget) const
int getDotNewPredOp(const MachineInstr &MI, const MachineBranchProbabilityInfo *MBPI) const
unsigned getInvertedPredicatedOpcode(const int Opc) const
HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr &MI) const
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool isPredicatedNew(const MachineInstr &MI) const
bool isJumpWithinBranchRange(const MachineInstr &MI, unsigned offset) const
bool mayBeNewStore(const MachineInstr &MI) const
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
bool isLoopN(const MachineInstr &MI) const
bool isConstExtended(const MachineInstr &MI) const
bool PredOpcodeHasJMP_c(unsigned Opcode) const
bool isExtended(const MachineInstr &MI) const
bool isPredicateLate(unsigned Opcode) const
bool isComplex(const MachineInstr &MI) const
void setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const
bool isMemOp(const MachineInstr &MI) const
int getDotOldOp(const MachineInstr &MI) const
bool isDeallocRet(const MachineInstr &MI) const
unsigned getCExtOpNum(const MachineInstr &MI) const
bool isDotNewInst(const MachineInstr &MI) const
unsigned getSize(const MachineInstr &MI) const
bool isHVXVec(const MachineInstr &MI) const
bool getBundleNoShuf(const MachineInstr &MIB) const
bool isNewValueJump(const MachineInstr &MI) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Cond) const override
Convert the instruction into a predicated instruction.
bool isFloat(const MachineInstr &MI) const
unsigned nonDbgBBSize(const MachineBasicBlock *BB) const
getInstrTimingClassLatency - Compute the instruction latency of a given instruction using Timing Clas...
bool isEndLoopN(unsigned Opcode) const
bool isPredicable(const MachineInstr &MI) const override
Return true if the specified instruction can be predicated.
HexagonII::CompoundGroup getCompoundCandidateGroup(const MachineInstr &MI) const
SmallVector< MachineInstr *, 2 > getBranchingInstrs(MachineBasicBlock &MBB) const
bool isNewValueStore(const MachineInstr &MI) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
bool isFakeReg(MCPhysReg Reg) const
Returns true if the given reserved physical register Reg is live across function calls/returns.
bool isGlobalReg(MCPhysReg Reg) const
Returns true if the given reserved physical register is live across function calls/returns.
void UpdateLiveness(MachineBasicBlock *MBB)
TypeSize getValue() const
unsigned getSchedClass() const
Return the scheduling class for this instruction.
unsigned pred_size() const
bool isEHPad() const
Returns true if the block is a landing pad.
instr_iterator instr_begin()
reverse_instr_iterator instr_rbegin()
instr_iterator erase_instr(MachineInstr *I)
Remove an instruction from the instruction list and delete it.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
SmallVectorImpl< MachineBasicBlock * >::const_iterator const_succ_iterator
LLVM_ABI iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the first non-debug instruction in the basic block, or end().
succ_iterator succ_begin()
LiveInVector::const_iterator livein_iterator
unsigned succ_size() const
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
void setAlignment(Align A)
Set alignment of the basic block.
LLVM_ABI void dump() const
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI bool isPredecessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a predecessor of this block.
reverse_instr_iterator instr_rend()
Instructions::iterator instr_iterator
pred_iterator pred_begin()
LLVM_ABI void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Given a machine basic block that branched to 'Old', change the code and CFG so that it branches to 'N...
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
instr_iterator instr_end()
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
LLVM_ABI instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
Align getAlignment() const
Return alignment of the basic block.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
Instructions::reverse_iterator reverse_instr_iterator
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
LLVM_ABI BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
instr_iterator getInstrIterator() const
Representation of each machine instruction.
mop_iterator operands_begin()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
LLVM_ABI MachineInstr * removeFromBundle()
Unlink this instruction from its basic block and return it without deleting it.
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isBundledWithPred() const
Return true if this instruction is part of a bundle, and it is not the first instruction in the bundl...
LLVM_ABI void unbundleFromPred()
Break bundle above this instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
mop_iterator operands_end()
LLVM_ABI unsigned getBundleSize() const
Return the number of instructions inside the MI bundle, excluding the bundle header.
bool isConditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block.
LLVM_ABI void eraseFromBundle()
Unlink 'this' from its basic block and delete it.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
LLVM_ABI void dump() const
bool isBundledWithSucc() const
Return true if this instruction is part of a bundle, and it is not the last instruction in the bundle...
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void unbundleFromSucc()
Break bundle below this instruction.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
bool isBundled() const
Return true if this instruction part of a bundle.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
const Value * getValue() const
Return the base address of the memory access.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
MachineOperand class - Representation of each machine instruction operand.
void setIsInternalRead(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
MachineBasicBlock * getMBB() const
void setIsKill(bool Val=true)
void setMBB(MachineBasicBlock *MBB)
Register getReg() const
getReg - Returns the register number.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
Representation for a specific memory location.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
LLVM_ABI unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx, const MachineInstr *UseMI, unsigned UseOperIdx) const
Compute operand latency based on the available machine model.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
int getNumOccurrences() const
unsigned getPosition() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)
Returns an iterator to the first instruction in the bundle containing I.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
void initializeHexagonGlobalSchedulerPass(PassRegistry &)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
LLVM_ABI Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq)
Print the block frequency Freq relative to the current functions entry frequency.
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
FunctionPass * createHexagonGlobalScheduler()
MCRegisterClass TargetRegisterClass
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.