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 CanPromoteToDotNew(MachineInstr *
MI,
unsigned Reg);
437 bool pullUpPeelBBLoop(MachineBasicBlock *PredBB, MachineBasicBlock *LoopBB);
439 MachineInstr *findBundleAndBranch(MachineBasicBlock *BB,
443 bool ResourcesAvailableInBundle(BasicBlockRegion *CurrentRegion,
447 MachineInstr *MoveAndUpdateLiveness(
448 BasicBlockRegion *CurrentRegion, MachineBasicBlock *HomeBB,
449 MachineInstr *InstrToMove,
bool NeedToNewify,
unsigned DepReg,
450 bool MovingDependentOp, MachineBasicBlock *OriginBB,
455 std::vector<MachineInstr *> &backtrack);
458 void updateKillAlongThePath(MachineBasicBlock *HomeBB,
459 MachineBasicBlock *OriginBB,
464 std::vector<MachineInstr *> &backtrack);
469 std::vector<MachineInstr *> &backtrack,
470 unsigned MaxCandidates);
473 bool tryMultipleInstructions(
475 std::vector<BasicBlockRegion *>::iterator &CurrentRegion,
481 bool MoveMItoBundle(BasicBlockRegion *CurrentRegion,
486 std::vector<MachineInstr *> &backtrack,
487 bool MovingDependentOp,
bool PathInRegion);
491 insertTempCopy(MachineBasicBlock *
MBB,
497 MachineInstr *
MI,
bool &LastInBundle);
500 MachineInstr *TargetPacket);
503 unsigned DepReg, MachineInstr *TargetPacket);
505 void addInstructionToExistingBundle(MachineBasicBlock *HomeBB,
511 std::vector<MachineInstr *> &backtrack);
513 void removeInstructionFromExistingBundle(
518 std::vector<MachineInstr *> &backtrack);
521 bool MIsCondAssign(MachineInstr *BMI, MachineInstr *
MI,
522 SmallVector<unsigned, 4> &Defs);
527 bool canMIBeSpeculated(MachineInstr *
MI, MachineBasicBlock *ToBB,
528 MachineBasicBlock *FromBB,
529 std::vector<MachineInstr *> &backtrack);
532 bool isBranchWithinRegion(BasicBlockRegion *CurrentRegion, MachineInstr *
MI);
535 bool MIsAreDependent(MachineInstr *MIa, MachineInstr *MIb);
536 bool MIsHaveTrueDependency(MachineInstr *MIa, MachineInstr *MIb);
537 bool canReorderMIs(MachineInstr *MIa, MachineInstr *MIb);
538 bool canCauseStall(MachineInstr *
MI, MachineInstr *MJ);
539 bool canThisMIBeMoved(MachineInstr *
MI,
541 bool &MovingDependentOp,
int &
Cost);
542 bool MIisDualJumpCandidate(MachineInstr *
MI,
544 bool DemoteToDotOld(MachineInstr *
MI);
546 MachineInstr *TargetPacket);
547 bool IsNewifyStore(MachineInstr *
MI);
548 bool isJumpOutOfRange(MachineInstr *
MI);
549 bool IsDualJumpFirstCandidate(MachineInstr *
MI);
550 bool IsDualJumpFirstCandidate(MachineBasicBlock *
MBB);
552 bool IsNotDualJumpFirstCandidate(MachineInstr *
MI);
553 bool isJumpOutOfRange(MachineInstr *UnCond, MachineInstr *
Cond);
554 bool IsDualJumpSecondCandidate(MachineInstr *
MI);
555 bool tryAllocateResourcesForConstExt(MachineInstr *
MI,
bool UpdateState);
556 bool isCompoundPair(MachineInstr *MIa, MachineInstr *MIb);
557 bool doesMIDefinesPredicate(MachineInstr *
MI, SmallVector<unsigned, 4> &Defs);
558 bool AnalyzeBBBranches(MachineBasicBlock *
MBB, MachineBasicBlock *&
TBB,
559 MachineInstr *&FirstTerm, MachineBasicBlock *&FBB,
560 MachineInstr *&SecondTerm);
561 inline bool multipleBranchesFromToBB(MachineBasicBlock *BB)
const;
566 "Hexagon Global Scheduler",
false,
false)
576HexagonGlobalSchedulerImpl::HexagonGlobalSchedulerImpl(
583 MBFI(MBFI), MRI(MRI), MFI(MFI), QRI(QRI), MLI(MLI), MDT(MDT),
584 PacketSize(MF.getSubtarget().getSchedModel().IssueWidth) {
588 TSchedModel.
init(&MF.getSubtarget());
596 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
597 if (MII->isDebugInstr())
605bool HexagonGlobalScheduler::runOnMachineFunction(
MachineFunction &Fn) {
610 const MachineRegisterInfo *MRI = &Fn.
getRegInfo();
612 const HexagonRegisterInfo *QRI = HST.getRegisterInfo();
613 MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
614 MachineDominatorTree &MDT =
615 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
616 const MachineBranchProbabilityInfo *MBPI =
617 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
618 const MachineBlockFrequencyInfo *MBFI =
619 &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
620 AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
628 HexagonGlobalSchedulerImpl GlobalSchedulerState(Fn, MLI, MDT, AA, MBPI, MBFI,
632 assert(GlobalSchedulerState.getResourceTracker() &&
"Empty DFA table!");
637 GlobalSchedulerState.checkBundleCounts(Fn);
643 LLVM_DEBUG(GlobalSchedulerState.countCompounds(Fn));
644 GlobalSchedulerState.GenUseDefChain(Fn);
645 GlobalSchedulerState.formPullUpRegions(Fn);
646 GlobalSchedulerState.performPullUp();
647 GlobalSchedulerState.performPullUpCFG(Fn);
649 GlobalSchedulerState.formPullUpRegions(Fn);
650 GlobalSchedulerState.performExposedOptimizations(Fn);
652 LLVM_DEBUG(GlobalSchedulerState.countCompounds(Fn));
659bool HexagonGlobalSchedulerImpl::tryAllocateResourcesForConstExt(
660 MachineInstr *
MI,
bool UpdateState =
true) {
661 if (ResourceTracker->canReserveResources(*Ext)) {
666 ResourceTracker->reserveResources(*Ext);
667 else if (CurrentPacketMIs.size() >= PacketSize - 1)
676 return MI->getOpcode() == Hexagon::Y2_barrier;
680 return MI->getOpcode() == Hexagon::J2_callr;
685 if (
MI->isBundledWithPred())
689 if (
MI->isBundledWithSucc())
698 dbgs() <<
"\tNULL\n";
705 dbgs() <<
"\tUnattached: ";
711 if (
MI->isBundle()) {
713 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
724 dbgs() <<
"\tBBEnd\n";
733 if (
MI->isBundle()) {
736 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
742 return MI->isBranch();
747bool HexagonGlobalSchedulerImpl::IsNotDualJumpFirstCandidate(MachineInstr *
MI) {
756bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(MachineInstr *
MI) {
767bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(
771 MachineInstr *
MI = &*TargetPacket;
773 if (
MI->isBundle()) {
775 if (&(*
MI->getParent()->rbegin()) !=
MI)
782 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
784 if (IsNotDualJumpFirstCandidate(&*MII))
787 return IsDualJumpFirstCandidate(
MI);
795bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(
796 MachineBasicBlock *
MBB) {
802 MII != MBBEnd; ++MII) {
803 MachineInstr *
MI = &*MII;
804 if (
MI->isDebugInstr())
806 if (!
MI->isBundle() && IsNotDualJumpFirstCandidate(
MI))
813bool HexagonGlobalSchedulerImpl::IsDualJumpSecondCandidate(MachineInstr *
MI) {
834 if (!MII->isBundle() && MII->isTerminator())
845bool HexagonGlobalSchedulerImpl::isJumpOutOfRange(MachineInstr *
MI) {
846 if (!
MI || !
MI->isBranch())
853 unsigned InstOffset = BlockToInstOffset[
MBB];
854 unsigned Distance = 0;
862 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
873 if (
TBB && (
MI == &*FirstTerm)) {
875 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[
TBB]) +
884 MachineInstr *SecondTerm = &*FTMII;
887 "Bad second terminator");
888 if (
MI != SecondTerm)
892 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[FBB]) +
894 LLVM_DEBUG(
dbgs() <<
"\tSecond term offset(" << Distance <<
"): ";
904bool HexagonGlobalSchedulerImpl::isNewifiable(
906 MachineInstr *TargetPacket) {
907 MachineInstr *
MI = &*MII;
909 !CanNewifiedBeUsedInBundle(MII, DepReg, TargetPacket))
915bool HexagonGlobalSchedulerImpl::DemoteToDotOld(MachineInstr *
MI) {
917 MI->setDesc(QII->get(NewOpcode));
922void HexagonGlobalSchedulerImpl::initPacketizerState(
void) {
923 CurrentPacketMIs.clear();
928bool HexagonGlobalSchedulerImpl::ignoreInstruction(MachineInstr *
MI) {
929 if (
MI->isDebugInstr())
933 if (
MI->isInlineAsm())
938 const MCInstrDesc &TID =
MI->getDesc();
940 const InstrStage *
IS =
941 ResourceTracker->getInstrItins()->beginStage(SchedClass);
942 unsigned FuncUnits =
IS->getUnits();
948bool HexagonGlobalSchedulerImpl::isSoloInstruction(
const MachineInstr &
MI) {
949 if (
MI.isInlineAsm())
961 if (
MI.getOpcode() == Hexagon::A2_nop)
968BasicBlockRegion *HexagonGlobalSchedulerImpl::getRegionForMBB(
969 std::vector<BasicBlockRegion *> &Regions, MachineBasicBlock *
MBB) {
970 for (std::vector<BasicBlockRegion *>::iterator
I = Regions.begin(),
973 if ((*I)->findMBB(
MBB))
999HexagonGlobalSchedulerImpl::getNextPURBB(MachineBasicBlock *
MBB,
1000 bool SecondBest =
false) {
1004 BlockFrequency BestBlockFreq = BlockFrequency(0);
1005 unsigned BestBlockSize = 0;
1006 MachineBasicBlock *BestBB = NULL;
1007 MachineBasicBlock *SecondBestBB = NULL;
1018 LLVM_DEBUG(
dbgs() <<
"\tsucc BB(" << Succ->getNumber() <<
") freq("
1021 if (!SecondBest && getRegionForMBB(PullUpRegions, Succ))
1026 if (Succ->pred_size() > 1)
1031 if (Succ->isEHPad() || Succ->hasAddressTaken())
1041 BestBlockFreq = EdgeFreq;
1043 SecondBestBB = BestBB;
1045 }
else if (!SecondBestBB) {
1046 SecondBestBB = Succ;
1050 return SecondBestBB;
1056bool HexagonGlobalSchedulerImpl::formPullUpRegions(
MachineFunction &Fn) {
1059 if (std::next(
F.begin()) ==
F.end())
1064 unsigned InstOffset = 0;
1066 LLVM_DEBUG(
dbgs() <<
"****** Form PullUpRegions **************\n");
1076 InstOffset = (InstOffset + ByteAlign) & ~(ByteAlign);
1079 BlockToInstOffset[&*
MBB] = InstOffset;
1083 if (!MII->isBundle())
1084 InstOffset += QII->
getSize(*MII);
1087 if (getRegionForMBB(PullUpRegions, &*
MBB))
1096 BasicBlockRegion *PUR =
new BasicBlockRegion(
TII, QRI, &*
MBB);
1097 PullUpRegions.push_back(PUR);
1099 for (MachineBasicBlock *MBBR = getNextPURBB(&*
MBB); MBBR;
1100 MBBR = getNextPURBB(MBBR)) {
1102 << MBBR->getName() <<
") size("
1105 << MBBR->getParent()->getFunction().getName() <<
")\n");
1115 if (
MI->hasUnmodeledSideEffects() ||
MI->hasOrderedMemoryRef() ||
1117 (
MI->getOpcode() == Hexagon::J2_jump && !
MI->getOperand(0).isMBB()))
1125 if (!
MI ||
MI->memoperands_empty())
1131 if ((*
MI->memoperands_begin())->isVolatile() ||
MI->hasUnmodeledSideEffects())
1134 if (!(*
MI->memoperands_begin())->getValue())
1147 if (
TII->areMemAccessesTriviallyDisjoint(*MIa, *MIb))
1173 assert((MMOa->
getOffset() >= 0) &&
"Negative MachineMemOperand offset");
1174 assert((MMOb->
getOffset() >= 0) &&
"Negative MachineMemOperand offset");
1176 "Size 0 memory access");
1213 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1226 for (
unsigned R = 1, NR = Hexagon::NUM_TARGET_REGS; R != NR; ++R)
1233void HexagonGlobalSchedulerImpl::MIUseDefSet(MachineInstr *
MI,
1234 std::vector<unsigned> &Defs,
1235 std::vector<unsigned> &
Uses) {
1238 assert(!
MI->isBundle() &&
"Cannot parse regs of a bundle.");
1239 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1240 const MachineOperand &MO =
MI->getOperand(i);
1246 assert(Register::isPhysicalRegister(
Reg));
1247 std::vector<unsigned> &Refs = MO.
isUse() ?
Uses : Defs;
1248 for (MCRegAliasIterator AI(MO.
getReg(), QRI,
true); AI.isValid(); ++AI)
1249 Refs.push_back(*AI);
1251 for (
unsigned R = 1, NR = Hexagon::NUM_TARGET_REGS;
R != NR; ++
R)
1288bool HexagonGlobalSchedulerImpl::canAddMIToThisPacket(
1298 isJumpOutOfRange(
MI)) &&
1299 !tryAllocateResourcesForConstExt(
MI,
false))
1303 if (!ResourceTracker->canReserveResources(*
MI) || !shouldAddToPacket(*
MI)) {
1308 SmallVector<unsigned, 4> BundleDefs;
1309 SmallVector<unsigned, 8> BundleUses;
1310 SmallVector<unsigned, 4> Defs;
1311 SmallVector<unsigned, 8>
Uses;
1312 MachineInstr *FirstCompound = NULL, *SecondCompound = NULL;
1313 MachineInstr *FirstDuplex = NULL, *SecondDuplex = NULL;
1316 for (SmallVector<MachineInstr *, HEXAGON_PACKET_SIZE>::iterator
1317 BI = Bundle.
begin(),
1324 MachineInstr *Inst1 = *BI;
1325 MachineInstr *Inst2 =
MI;
1338 FirstCompound = *BI;
1340 SecondCompound = *BI;
1341 if (isCompoundPair(FirstCompound, SecondCompound)) {
1342 if (
MI->mayLoad() ||
MI->mayStore()) {
1356 if (
MI->mayLoad() ||
MI->mayStore()) {
1364 for (
unsigned i = 0; i < Defs.
size(); i++) {
1366 for (
unsigned j = 0;
j < BundleDefs.
size();
j++)
1371 if (AliasingRegs(Defs[i], BundleDefs[j]) &&
1373 !(IsDualJumpFirstCandidate(*BI) && IsDualJumpSecondCandidate(
MI))) {
1375 dbgs() <<
"\t"; (*BI)->dump());
1391 for (
unsigned j = 0;
j < BundleUses.
size();
j++)
1392 if (AliasingRegs(Defs[i], BundleUses[j])) {
1393 for (
unsigned k = 0;
k < BundleDefs.
size();
k++)
1394 for (
unsigned l = 0;
l <
Uses.size();
l++) {
1395 if (AliasingRegs(BundleDefs[k],
Uses[l]) &&
1398 dbgs() <<
"\t"; (*BI)->dump());
1405 for (
unsigned i = 0; i <
Uses.size(); i++) {
1407 for (
unsigned j = 0;
j < BundleDefs.
size();
j++)
1408 if (AliasingRegs(
Uses[i], BundleDefs[j]) &&
1412 MI->dump();
dbgs() <<
"\t"; (*BI)->dump());
1424 if ((*BI)->isCall()) {
1426 for (
unsigned i = 0; i < Defs.
size(); i++) {
1427 if (AliasingRegs(Defs[i], *
I)) {
1442 if ((*BI)->isBarrier()) {
1475 (
MI->mayStore() ||
MI->getOpcode() == Hexagon::S2_allocframe ||
1498 if ((QII->
isMemOp(**BI) &&
MI->mayStore()) ||
1499 (QII->
isMemOp(*
MI) && (*BI)->mayStore())) {
1501 dbgs() <<
"\tSlot 0 not available for store because of memop.\n");
1506 if ((
MI->mayLoad() && (*BI)->mayStore()) ||
1507 (
MI->mayStore() && (*BI)->mayLoad()) ||
1508 (
MI->mayStore() && (*BI)->mayStore())) {
1511 dbgs() <<
"\t"; (*BI)->dump());
1517 std::map<MachineInstr *, MachineBasicBlock *>::iterator MIMoved;
1518 MIMoved = SpeculatedIns.find(*BI);
1519 if ((MIMoved != SpeculatedIns.end()) &&
1520 (MIMoved->second != (*BI)->getParent())) {
1522 dbgs() <<
"This packet already contains a speculated instruction";
1538bool HexagonGlobalSchedulerImpl::ReorderDependencyTest(MachineInstr *MIa,
1539 MachineInstr *MIb) {
1540 SmallVector<unsigned, 4> DefsA;
1541 SmallVector<unsigned, 4> DefsB;
1542 SmallVector<unsigned, 8> UsesA;
1543 SmallVector<unsigned, 8> UsesB;
1548 for (SmallVector<unsigned, 4>::iterator IDA = DefsA.
begin(),
1550 IDA != IDAE; ++IDA) {
1551 for (SmallVector<unsigned, 8>::iterator IUB = UsesB.
begin(),
1555 if (AliasingRegs(*IDA, *IUB))
1558 for (SmallVector<unsigned, 4>::iterator IDB = DefsB.
begin(),
1562 if (AliasingRegs(*IDA, *IDB))
1566 for (SmallVector<unsigned, 4>::iterator IDB = DefsB.
begin(),
1568 IDB != IDBE; ++IDB) {
1569 for (SmallVector<unsigned, 8>::iterator IUA = UsesA.
begin(),
1573 if (AliasingRegs(*IDB, *IUA))
1584 for (
unsigned i = 0; i < DefsB.
size(); i++) {
1585 if (AliasingRegs(DefsB[i], *
I))
1592 for (
unsigned i = 0; i < DefsA.
size(); i++) {
1593 if (AliasingRegs(DefsA[i], *
I))
1615bool HexagonGlobalSchedulerImpl::MIsAreDependent(MachineInstr *MIa,
1616 MachineInstr *MIb) {
1620 if (ReorderDependencyTest(MIa, MIb)) {
1629bool HexagonGlobalSchedulerImpl::MIsHaveTrueDependency(MachineInstr *MIa,
1630 MachineInstr *MIb) {
1634 SmallVector<unsigned, 4> DefsA;
1635 SmallVector<unsigned, 4> DefsB;
1636 SmallVector<unsigned, 8> UsesA;
1637 SmallVector<unsigned, 8> UsesB;
1642 for (SmallVector<unsigned, 4>::iterator IDA = DefsA.
begin(),
1644 IDA != IDAE; ++IDA) {
1645 for (SmallVector<unsigned, 8>::iterator IUB = UsesB.
begin(),
1649 if (AliasingRegs(*IDA, *IUB))
1657bool HexagonGlobalSchedulerImpl::canReorderMIs(MachineInstr *MIa,
1658 MachineInstr *MIb) {
1666 for (++MII; MII != MIIE && MII->isInsideBundle(); ++MII) {
1667 if (MII->isDebugInstr())
1669 if (MIsAreDependent(&*MII, MIb))
1674 return !MIsAreDependent(MIa, MIb);
1684 if (
MI->isBranch() ||
MI->isReturn() ||
MI->isCall() ||
MI->isBarrier() ||
1692bool HexagonGlobalSchedulerImpl::MIisDualJumpCandidate(
1698 MachineBasicBlock *FromThisBB =
MI->getParent();
1699 MachineBasicBlock *ToThisBB = WorkPoint->getParent();
1702 << ToThisBB->
getNumber() <<
") From BB("
1706 if (FromThisBB == ToThisBB)
1712 if ((*(FromThisBB->
pred_begin()) != ToThisBB) ||
1723 MachineBasicBlock *ToTBB = NULL, *ToFBB = NULL;
1729 if (!QII->
analyzeBranch(*ToThisBB, ToTBB, ToFBB, ToCond,
false)) {
1733 if (ToFBB)
dbgs() << ToFBB->getNumber() <<
").\n";
1734 else dbgs() <<
"None"
1736 if (ToTBB == FromThisBB) {
1740 }
else if (ToFBB == FromThisBB || !ToFBB) {
1749 }
else if (ToThisBB->
succ_size() == 1) {
1751 assert(ToFBB == FromThisBB &&
"Bad CFG layout");
1757 return IsDualJumpFirstCandidate(WorkPoint);
1764bool HexagonGlobalSchedulerImpl::canCauseStall(MachineInstr *
MI,
1766 SmallVector<unsigned, 4> DefsMJI;
1767 SmallVector<unsigned, 8> UsesMJI;
1768 SmallVector<unsigned, 4> DefsMI;
1769 SmallVector<unsigned, 8> UsesMI;
1772 for (
auto Use : UsesMI) {
1773 int UseIdx =
MI->findRegisterUseOperandIdx(Use,
nullptr);
1776 bool ShouldBreak =
false;
1777 int BundleCount = 0;
1781 MJI != Begin; --MJI) {
1782 if (MJI->isBundle()) {
1787 for (
auto Def : DefsMJI) {
1788 if (Def == Use || AliasingRegs(Def, Use)) {
1789 int DefIdx = MJI->findRegisterDefOperandIdx(Def,
nullptr);
1805 if (!MJI->isBundled() && !MJI->isDebugInstr())
1816bool HexagonGlobalSchedulerImpl::canThisMIBeMoved(
1818 bool &MovingDependentOp,
int &
Cost) {
1822 MovingDependentOp =
false;
1835 for (--MII; MII->isBundled(); --MII)
1836 if (MII->isBundle())
1840 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1844 if (isCompoundPair(&*MII,
MI)) {
1857 for (--MII; MII->isBundled(); --MII)
1858 if (MII->isBundle())
1862 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1877 if (MIisDualJumpCandidate(
MI, WorkPoint)) {
1882 MovingDependentOp =
true;
1892 unsigned dist_looplabel =
1893 BlockToInstOffset.
find(
MI->getOperand(0).getMBB())->second;
1894 unsigned dist_newloop0 =
1895 BlockToInstOffset.
find(WorkPoint->getParent())->second;
1898 (unsigned)std::abs((
long long)dist_looplabel - dist_newloop0) +
1900 const HexagonInstrInfo *HII = (
const HexagonInstrInfo *)
TII;
1903 << Distance <<
" outside branch range.";);
1906 LLVM_DEBUG(
dbgs() <<
"\nloopN can be moved since Distance: " << Distance
1907 <<
" within branch range.";);
1912 std::map<MachineInstr *, std::vector<unsigned>>::const_iterator DefIter =
1915 for (
unsigned i = 0; DefIter != MIDefSet.end() && i < DefIter->second.size();
1922 if (
MI->isBundled()) {
1931 for (--MII; MII->isBundled(); --MII)
1932 if (MII->isBundle())
1936 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1938 if (MII->isDebugInstr())
1940 if (MIsAreDependent(&*MII,
MI)) {
1949 IsDualJumpSecondCandidate(&*MII) ||
MI->isBranch()) {
1951 MovingDependentOp =
true;
1955 LLVM_DEBUG(
dbgs() <<
"\t\tDependent, and do not allow for now.\n");
1966bool HexagonGlobalSchedulerImpl::doesMIDefinesPredicate(
1967 MachineInstr *
MI, SmallVector<unsigned, 4> &Defs) {
1968 bool defsPredicate =
false;
1971 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1972 const MachineOperand &MO =
MI->getOperand(i);
1982 assert(Register::isPhysicalRegister(
Reg));
1986 if (RC == &Hexagon::PredRegsRegClass) {
1987 defsPredicate =
true;
1992 return defsPredicate;
2000bool HexagonGlobalSchedulerImpl::NeedToNewify(
2002 MachineInstr *TargetPacket = NULL) {
2004 SmallVector<unsigned, 4> DefsA;
2005 SmallVector<unsigned, 4> DefsB;
2006 SmallVector<unsigned, 8> UsesB;
2017 if (TargetPacket && !TargetPacket->
isBundled()) {
2018 if (doesMIDefinesPredicate(TargetPacket, DefsA)) {
2019 for (SmallVector<unsigned, 4>::iterator IA = DefsA.
begin(),
2022 for (SmallVector<unsigned, 8>::iterator IB = UsesB.
begin(),
2034 for (--MII; MII->isBundled(); --MII)
2035 if (MII->isBundle())
2046 for (++MII; MII != BBEnd && MII->isBundled() && !MII->isBundle(); ++MII) {
2049 if (doesMIDefinesPredicate(&*MII, DefsA)) {
2050 for (SmallVector<unsigned, 4>::iterator IA = DefsA.
begin(),
2053 for (SmallVector<unsigned, 8>::iterator IB = UsesB.
begin(),
2073bool HexagonGlobalSchedulerImpl::CanNewifiedBeUsedInBundle(
2075 MachineInstr *TargetPacket) {
2077 if (!TargetPacket || !TargetPacket->
isBundled())
2081 for (--MII; MII->isBundled(); --MII)
2082 if (MII->isBundle())
2086 for (++MII; MII != BBEnd && MII->isBundled() && !MII->isBundle(); ++MII) {
2091 SmallVector<unsigned, 4> DefsA;
2092 if (!doesMIDefinesPredicate(&*MII, DefsA))
2094 for (
auto &IA : DefsA)
2103void HexagonGlobalSchedulerImpl::setUsedRegs(BitVector &Set,
unsigned Reg) {
2105 for (MCSubRegIterator SubRegs(
Reg, QRI); SubRegs.isValid(); ++SubRegs)
2106 Set.reset(*SubRegs);
2110bool HexagonGlobalSchedulerImpl::AliasingRegs(
unsigned RegA,
unsigned RegB) {
2114 for (MCSubRegIterator SubRegs(RegA, QRI); SubRegs.isValid(); ++SubRegs)
2115 if (RegB == *SubRegs)
2118 for (MCSubRegIterator SubRegs(RegB, QRI); SubRegs.isValid(); ++SubRegs)
2119 if (RegA == *SubRegs)
2127 if (
MI->isDebugInstr())
2130 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2143 if (
MI->isDebugInstr())
2146 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2159void HexagonGlobalSchedulerImpl::updateKillAlongThePath(
2160 MachineBasicBlock *HomeBB, MachineBasicBlock *OriginBB,
2165 std::vector<MachineInstr *> &backtrack) {
2167 MachineInstr *
MI = &*Head;
2168 MachineBasicBlock *CurrentBB = OriginBB;
2169 SmallSet<unsigned, 8> KilledUseSet;
2171 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2172 const MachineOperand &MO =
MI->getOperand(i);
2184 if (KilledUseSet.
empty())
2194 <<
")kills. From BB (" << OriginBB->
getNumber() <<
")\n");
2196 assert(!backtrack.empty() &&
"Empty back track");
2202 for (
signed i = backtrack.size() - 1; i >= 0; --i) {
2204 << backtrack[i]->
getParent()->getNumber() <<
")\t";
2205 backtrack[i]->dump());
2206 if (CurrentBB != backtrack[i]->
getParent()) {
2208 <<
") to(" << backtrack[i]->getParent()->getNumber()
2214 if (*SI == CurrentBB)
2221 E = (*SI)->livein_end();
2223 if (KilledUseSet.
count((*I).PhysReg)) {
2225 <<
") is LiveIn along side exit.\n");
2226 KilledUseSet.
erase((*I).PhysReg);
2229 if (KilledUseSet.
empty())
2233 CurrentBB = backtrack[i]->getParent();
2237 if (backtrack[i] == &*TargetPacket)
2243 if (backtrack[i] == &*SourcePacket)
2247 if (backtrack[i]->isDebugInstr())
2253 SmallVector<unsigned, 4> Defs;
2254 SmallVector<unsigned, 8>
Uses;
2255 MachineInstr *MIU = backtrack[i];
2258 for (SmallVector<unsigned, 8>::iterator IA =
Uses.begin(), IAE =
Uses.end();
2260 if (KilledUseSet.
count(*IA)) {
2272 for (++MII; MII != End && MII->isInsideBundle(); ++MII)
2277 KilledUseSet.
erase(*IA);
2280 if (KilledUseSet.
empty())
2288void HexagonGlobalSchedulerImpl::addInstructionToExistingBundle(
2294 std::vector<MachineInstr *> &backtrack) {
2301 if (Outcast->isBundle() && Outcast->isBundledWithSucc())
2302 Outcast->unbundleFromSucc();
2309 if (memShufDisabled)
2317 for (
unsigned i = 0; i < backtrack.size(); ++i)
2318 if (backtrack[i] == &*Outcast)
2319 backtrack[i] = &*Head;
2322 if (NextMI == Outcast)
2325 TargetPacket = Head;
2326 HomeBB->
erase(Outcast);
2331void HexagonGlobalSchedulerImpl::removeInstructionFromExistingBundle(
2336 std::vector<MachineInstr *> &backtrack) {
2338 if (HomeBB->
empty()) {
2344 if (!SourceLocation->isBundle()) {
2345 LLVM_DEBUG(
dbgs() <<
"\t\t\tOriginal instruction was not bundled.\n\t\t\t";
2346 SourceLocation->dump());
2351 for (
unsigned i = 0; i < backtrack.size(); ++i) {
2352 if (backtrack[i] == &*SourceLocation) {
2354 assert((backtrack[i] == backtrack.back()) &&
"Lost back track");
2355 backtrack.pop_back();
2358 if (NextMI == SourceLocation)
2369 LLVM_DEBUG(
dbgs() <<
"\t\t\t[Rem] SourceLocation after bundle update: ";
2375 if (!SourceLocation->isBundledWithSucc()) {
2376 assert(!Head->isBundledWithSucc() && !Head->isBundledWithPred() &&
2382 unsigned BBSizeWithDbg = 0;
2386 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I) {
2388 if (!
I->isDebugInstr())
2399 if (Outcast->isBundle() && Outcast->isBundledWithSucc())
2400 Outcast->unbundleFromSucc();
2413 if (memShufDisabled)
2417 }
else if (
Size == 1) {
2419 if (BBSizeWithDbg > 1) {
2423 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I) {
2424 I->unbundleFromPred();
2426 if (!
I->isDebugInstr())
2434 if (Head->isBundledWithPred())
2435 Head->unbundleFromPred();
2436 if (Head->isBundledWithSucc())
2437 Head->unbundleFromSucc();
2444 SourceLocation = Head;
2448 for (
unsigned i = 0; i < backtrack.size(); ++i)
2449 if (backtrack[i] == &*Outcast)
2450 backtrack[i] = &*Head;
2453 if (NextMI == Outcast)
2456 HomeBB->
erase(Outcast);
2464 SE =
MBB->succ_end();
2466 LLVM_DEBUG(
dbgs() <<
"\tSuccessor BB (" << (*SI)->getNumber() <<
"):");
2468 E = (*SI)->livein_end();
2483 if (!
MBBI->isDebugInstr())
2493 if (!
MI || !
MI->isBranch() ||
MI->isBundle())
2496 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2506bool HexagonGlobalSchedulerImpl::AnalyzeBBBranches(MachineBasicBlock *
MBB,
2507 MachineBasicBlock *&
TBB,
2508 MachineInstr *&FirstTerm,
2509 MachineBasicBlock *&FBB,
2510 MachineInstr *&SecondTerm) {
2533 if (MII->isBranch())
2537 while (MII != MIE) {
2538 if (!MII->isBundle() && MII->isBranch()) {
2549 LLVM_DEBUG(
dbgs() <<
"\n\t\tCannot analyze BB with indirect branch.");
2552 if ((FirstTerm && FirstTerm->
getOpcode() == Hexagon::J2_jump &&
2554 (SecondTerm && SecondTerm->
getOpcode() == Hexagon::J2_jump &&
2557 dbgs() <<
"\n\t\tCannot analyze BB with a branch out of function.");
2564 LLVM_DEBUG(
dbgs() <<
"\t\tFail to analyze with analyzeBranch.\n");
2566 else dbgs() <<
"None\n";);
2583 if (FirstTerm && SecondTerm &&
2592 }
else if (SecondTerm && SecondTerm->
getOpcode() == Hexagon::J2_jump &&
2605 <<
") FBB(" << FBB->
getNumber() <<
").\n");
2620 assert(MBBIter != MF.
end() &&
"I give up.");
2627 else if (FBB ==
S1) {
2633 MBBIter = MF.
begin();
2636 assert(MBBIter != MF.
end() &&
"Malformed BB with invalid successors");
2644 <<
") FBB(" << FBB->
getNumber() <<
").\n");
2648 assert(!FirstTerm &&
"Bad BB");
2652 if (!FBB && SecondTerm) {
2668 LLVM_DEBUG(
dbgs() <<
"Possibly the layout successor is an empty BB");
2672 LLVM_DEBUG(
dbgs() <<
"Malformed branch with useless branch condition";);
2675 }
else if (
TBB && !FBB) {
2691 else dbgs() <<
"\t\tFinal FBB(None)\n";);
2736 if (!Pred->isSuccessor(&
MBB))
2738 Pred->ReplaceUsesOfBlockWith(&
MBB, MFBB);
2749 bool RemoveLSIfPresent =
false;
2751 LLVM_DEBUG(
dbgs() <<
"\nNew firstterm conditional jump added to HomeBB";);
2755 LLVM_DEBUG(
dbgs() <<
"\nNew secondterm conditional jump added to HomeBB";);
2759 LLVM_DEBUG(
dbgs() <<
"\nBranch destination for pulled instruction is BB#"
2760 << Dest->getNumber(););
2765 LLVM_DEBUG(
dbgs() <<
"\nNew firstterm unconditional jump added to HomeBB";);
2768 RemoveLSIfPresent =
true;
2771 dbgs() <<
"\nNew secondterm unconditional jump added to HomeBB";);
2774 RemoveLSIfPresent =
true;
2781 if (RemoveLSIfPresent) {
2786 LLVM_DEBUG(
dbgs() <<
"\nRemoving LayoutSucc BB#" << HomeBBLS->getNumber()
2787 <<
"from list of successors";);
2796MachineInstr *HexagonGlobalSchedulerImpl::MoveAndUpdateLiveness(
2797 BasicBlockRegion *CurrentRegion, MachineBasicBlock *HomeBB,
2798 MachineInstr *InstrToMove,
bool NeedToNewify,
unsigned DepReg,
2799 bool MovingDependentOp, MachineBasicBlock *OriginBB,
2804 std::vector<MachineInstr *> &backtrack) {
2806 dbgs() <<
"\n...............[MoveAndUpdateLiveness]..............\n");
2809 OriginalInstruction->
dump());
2823 HomeBB->
erase(kill_it);
2834 std::list<MachineBasicBlock *> WorkList;
2837 for (std::vector<MachineInstr *>::iterator RI = backtrack.begin(),
2838 RIE = backtrack.end();
2840 WorkList.push_back((*RI)->getParent());
2849 TargetHead->getParent()->instr_end();
2850 bool LastInstructionInBundle =
false;
2852 TargetPacket, &*OutcastFrom, LastInstructionInBundle);
2860 MIBundleBuilder Bundle(&*TargetHead);
2870 if (OriginalInstruction->
getIterator() == TargetTail) {
2877 if (OutcastFrom->isBundledWithSucc()) {
2880 }
else if (OutcastFrom->isBundledWithPred()) {
2881 OutcastFrom->unbundleFromPred();
2883 HomeBB->
splice(MII, OriginBB, OutcastFrom);
2884 if (!MII->isBundledWithPred())
2885 MII->bundleWithPred();
2886 if (!LastInstructionInBundle && !MII->isBundledWithSucc())
2887 MII->bundleWithSucc();
2889 if (!MIIToPred->isBundledWithSucc())
2890 MIIToPred->bundleWithSucc();
2908 updateKillAlongThePath(HomeBB, OriginBB, MII, TargetTail, SourceLocation,
2909 TargetPacket, backtrack);
2918 DemoteToDotOld(&*MII);
2928 if (!
Cond.empty()) {
2933 assert((DepReg < std::numeric_limits<unsigned>::max()) &&
2934 "Invalid pred reg value");
2936 <<
printReg(DepReg, QRI) <<
").\n");
2938 MII->setDesc(QII->get(NewOpcode));
2943 for (
unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
2944 MachineOperand &MO = MII->getOperand(i);
2949 if (DepReg == MO.
getReg())
2953 LLVM_DEBUG(
dbgs() <<
"\t\t\tNew predicated form:\t"; MII->dump());
2956 updateKillAlongThePath(HomeBB, OriginBB, MII, TargetTail, SourceLocation,
2957 TargetPacket, backtrack);
2961 addInstructionToExistingBundle(HomeBB, TargetHead, TargetTail, MII,
2962 TargetPacket, NextMI, backtrack);
2965 removeInstructionFromExistingBundle(OriginBB, ++OriginalHead, OriginalTail,
2966 SourceLocation, NextMI, MovingDependentOp,
2979 QII->
isEndLoopN(OriginalHead->getOpcode())) {
2985 if (OriginBB->
begin() !=
I) {
2987 if (
I->isBundled()) {
2988 if (!
I->isBundledWithSucc())
2989 I->bundleWithSucc();
2990 if (!OriginalHead->isBundledWithPred())
2991 OriginalHead->bundleWithPred();
2996 }
else if (MovingDependentOp &&
2998 if (OriginalHead->isBundled()) {
3000 J != OriginalTail && J->isInsideBundle() && !J->isBundle(); ++J) {
3002 if (MIsHaveTrueDependency(OriginalInstruction, &*J) &&
3005 DemoteToDotOld(&*J);
3010 if (MIsHaveTrueDependency(OriginalInstruction, &*OriginalHead) &&
3013 OriginalHead->dump());
3014 DemoteToDotOld(&*OriginalHead);
3027 for (std::list<MachineBasicBlock *>::iterator BBI = WorkList.begin(),
3028 BBIE = WorkList.end();
3029 BBI != BBIE; BBI++) {
3035 MachineBasicBlock *BB = WorkList.back();
3036 WorkList.pop_back();
3038 }
while (!WorkList.empty());
3041 if (OriginBB == HomeBB)
3042 return &*TargetHead;
3045 MachineBasicBlock *HomeTBB, *HomeFBB;
3046 MachineInstr *FTA = NULL, *STA = NULL;
3047 bool HomeBBAnalyzed = !AnalyzeBBBranches(HomeBB, HomeTBB, FTA, HomeFBB, STA);
3048 if (MII->isBranch()) {
3049 if (HomeBBAnalyzed) {
3050 UpdateCFG(HomeBB, OriginBB, &*MII, HomeTBB, HomeFBB, FTA, STA, MBPI);
3065 EmptyBBs.push_back(OriginBB);
3067 return &*TargetHead;
3071 MachineBasicBlock *CommonFBB = *OriginBB->
succ_begin();
3077 assert((OriginBB->
succ_size() == 2) &&
"Underimplemented 3way branch.");
3078 MachineBasicBlock *OriginTBB, *OriginFBB;
3079 MachineInstr *FTB = NULL, *STB = NULL;
3082 if (HomeBBAnalyzed &&
3083 !AnalyzeBBBranches(OriginBB, OriginTBB, FTB, OriginFBB, STB)) {
3084 assert(OriginFBB &&
"Missing Origin FBB");
3085 if (HomeFBB == OriginBB) {
3087 if (HomeTBB == OriginTBB) {
3090 }
else if (HomeTBB == OriginFBB) {
3101 }
else if (HomeTBB == OriginBB) {
3103 if (HomeFBB == OriginTBB) {
3106 }
else if (HomeFBB == OriginFBB) {
3128 return &*TargetHead;
3134HexagonGlobalSchedulerImpl::findInsertPositionInBundle(
3143 assert(MII->isBundle() &&
"Missing insert location");
3144 bool isDualJumpSecondCandidate = IsDualJumpSecondCandidate(
MI);
3145 LastInBundle =
false;
3147 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
3149 if (MII->isBranch() && (FirstBranch == BBEnd))
3153 if (isDualJumpSecondCandidate && IsDualJumpFirstCandidate(&*MII))
3154 DualJumpFirstCandidate = MII;
3155 LastBundledInstruction = MII;
3158 if (DualJumpFirstCandidate != BBEnd) {
3160 ++DualJumpFirstCandidate;
3161 if (DualJumpFirstCandidate == BBEnd ||
3162 DualJumpFirstCandidate == LastBundledInstruction)
3163 LastInBundle =
true;
3164 return DualJumpFirstCandidate;
3165 }
else if (FirstBranch != BBEnd) {
3170 }
else if (LastBundledInstruction != BBEnd) {
3171 LastInBundle =
true;
3172 return ++LastBundledInstruction;
3183 MachineInstr *
MI,
bool DeleteOldCopy) {
3187 assert(CurrentBB &&
"Corrupt instruction");
3194 MachineInstr *NewMI =
MI->getParent()->getParent()->CloneMachineInstr(
MI);
3201 if (DeleteOldCopy) {
3206 CurrentBB->
erase(kill_it);
3213 DemoteToDotOld(NewMI);
3218 if (TargetPacket->getParent() ==
MBB) {
3221 if (MII->isBundled()) {
3222 bool LastInBundle =
false;
3224 findInsertPositionInBundle(TargetPacket, NewMI, LastInBundle);
3225 MIBundleBuilder Bundle(&*TargetPacket);
3226 Bundle.insert(InsertBefore, NewMI);
3233 while (MII->isDebugInstr())
3236 if (MII->isBundled()) {
3237 MIBundleBuilder Bundle(&*MII);
3238 Bundle.insert(++MII, NewMI);
3246bool HexagonGlobalSchedulerImpl::MIsCondAssign(MachineInstr *BMI,
3248 SmallVector<unsigned, 4> &Defs) {
3252 SmallVector<unsigned, 4> CondDefs;
3253 SmallVector<unsigned, 8> CondUses;
3256 for (SmallVector<unsigned, 4>::iterator ID = Defs.
begin(), IDE = Defs.
end();
3258 for (SmallVector<unsigned, 4>::iterator CID = CondDefs.
begin(),
3259 CIDE = CondDefs.
end();
3260 CID != CIDE; ++CID) {
3261 if (AliasingRegs(*CID, *ID)) {
3275template <
typename ElemType,
typename IndexType>
3277 std::map<ElemType, std::vector<IndexType>> &Set1,
3278 std::map<ElemType, std::vector<IndexType>> &Set2,
3279 std::pair<std::vector<IndexType>, std::vector<IndexType>> &UnionSet,
3280 unsigned union_size = 100) {
3282 typename std::map<ElemType, std::vector<IndexType>>
::iterator PosIter_t;
3283 typedef typename std::vector<IndexType>::iterator IndexIter_t;
3284 std::vector<IndexType> &Union1 = UnionSet.first;
3285 std::vector<IndexType> &Union2 = UnionSet.second;
3286 Union1.resize(union_size, 0);
3287 Union2.resize(union_size, 0);
3289 typename std::vector<ElemType>::iterator iter =
Range.begin();
3290 while (iter !=
Range.end()) {
3291 if ((*iter)->isDebugInstr()) {
3296 PosIter_t set1_pos = Set1.find(*iter);
3297 assert(set1_pos != Set1.end() &&
3298 "Set1 should contain an entry for each element in Range.");
3299 IndexIter_t set1idx = set1_pos->second.begin();
3300 while (set1idx != set1_pos->second.end()) {
3301 Union1[*set1idx] = 1;
3304 PosIter_t set2_pos = Set2.find(*iter);
3305 assert(set2_pos != Set2.end() &&
3306 "Set2 should contain an entry for each element in Range.");
3307 IndexIter_t set2idx = set2_pos->second.begin();
3308 while (set2idx != set2_pos->second.end()) {
3309 Union2[*set2idx] = 1;
3326 MI->unbundleFromPred();
3335bool HexagonGlobalSchedulerImpl::canMIBeSpeculated(
3336 MachineInstr *
MI, MachineBasicBlock *ToBB, MachineBasicBlock *FromBB,
3337 std::vector<MachineInstr *> &backtrack) {
3360 if (!
MI->isDereferenceableInvariantLoad())
3365 SmallVector<unsigned, 4> Defs;
3366 SmallVector<unsigned, 8>
Uses;
3370 for (
unsigned R : Defs)
3383 LLVM_DEBUG(
dbgs() <<
"\tTarget succesor BB to check:\n"; (*SI)->dump());
3386 SIE = (*SI)->succ_end();
3387 SII != SIE; ++SII)(*SII)
3390 E = (*SI)->livein_end();
3392 for (SmallVector<unsigned, 4>::iterator ID = Defs.begin(),
3395 if (AliasingRegs((*I).PhysReg, *ID))
3402 E = (*SI)->instr_end();
3404 if (BI->isBundle() || BI->isDebugInstr())
3407 if (MIsCondAssign(&*BI,
MI, Defs))
3415 std::vector<MachineBasicBlock *> PathBB;
3416 for (
unsigned i = 0; i < backtrack.size(); ++i) {
3418 MachineBasicBlock *
MBB = backtrack[i]->getParent();
3419 if ((
MBB != FromBB) &&
3420 (std::find(PathBB.begin(), PathBB.end(),
MBB) == PathBB.end()))
3421 PathBB.push_back(
MBB);
3423 bool WaitingForTargetPacket =
true;
3425 std::vector<MachineInstr *> TraversalRange;
3433 for (
unsigned i = 0; i < PathBB.size(); ++i) {
3434 for (MII = PathBB[i]->instr_begin(); MII != PathBB[i]->instr_end(); ++MII) {
3438 if (backtrack[0] == &*MII)
3439 WaitingForTargetPacket =
false;
3440 if (WaitingForTargetPacket)
3442 if (MII->isBundle())
3449 if (MII->isCall() || MII->isReturn() ||
3450 (MII->getOpcode() == Hexagon::J2_jump && !MII->getOperand(0).isMBB()))
3453 TraversalRange.push_back(&*MII);
3459 std::pair<std::vector<unsigned>, std::vector<unsigned>> RangeDefUse;
3460 Unify(TraversalRange, MIDefSet, MIUseSet, RangeDefUse, QRI->getNumRegs());
3462 for (
unsigned j = 0;
j <
Uses.size(); ++
j)
3463 if (RangeDefUse.first[
Uses[j]]) {
3464 LLVM_DEBUG(
dbgs() <<
"\n\t\tUnresolved dependency along path to HOME for "
3470 for (
unsigned j = 0;
j < Defs.size(); ++
j)
3471 if (RangeDefUse.first[Defs[j]] || RangeDefUse.second[Defs[j]]) {
3472 LLVM_DEBUG(
dbgs() <<
"\n\t\tUnresolved dependency along path to HOME for "
3495bool HexagonGlobalSchedulerImpl::MoveMItoBundle(
3496 BasicBlockRegion *CurrentRegion,
3501 std::vector<MachineInstr *> &backtrack,
bool MovingDependentOp,
3502 bool PathInRegion) {
3503 MachineBasicBlock *HomeBB = TargetPacket->getParent();
3504 MachineBasicBlock *OriginBB = InstrToMove->
getParent();
3505 MachineBasicBlock *CurrentBB = OriginBB;
3506 MachineBasicBlock *CleanupBB = OriginBB;
3507 MachineBasicBlock *PreviousBB = OriginBB;
3508 MachineInstr *OriginalInstructionToMove = &*InstrToMove;
3510 assert(HomeBB &&
"Missing HomeBB");
3511 assert(OriginBB &&
"Missing OriginBB");
3513 LLVM_DEBUG(
dbgs() <<
"\n.........[MoveMItoBundle]..............\n");
3514 LLVM_DEBUG(
dbgs() <<
"\t\tInstrToMove :\t"; InstrToMove->dump());
3521 if (HomeBB == OriginBB) {
3537 for (
unsigned i = 0; i < backtrack.size(); ++i) {
3540 << backtrack[i]->
getParent()->getNumber() <<
")\t";
3541 backtrack[i]->dump());
3545 bool NeedCleanup =
false;
3546 bool NeedToPredicate =
false;
3547 bool MINeedToNewify =
false;
3548 unsigned DepReg = std::numeric_limits<unsigned>::max();
3549 bool isDualJump =
false;
3552 std::vector<MachineInstr *> PullUpPath;
3554 PullUpPath = backtrack;
3556 PullUpPath.push_back(&*TargetPacket);
3557 PullUpPath.push_back(&*InstrToMove);
3563 for (std::vector<MachineInstr *>::reverse_iterator RI = backtrack.rbegin(),
3564 RIE = backtrack.rend();
3568 MachineInstr *MIWH = *RI;
3571 InstrToMove->dump());
3573 CleanupBB->
erase(InstrToMove);
3576 if (canCauseStall(&*InstrToMove, MIWH)) {
3578 CleanupBB->
erase(InstrToMove);
3588 bool isBranchMIWH =
isBranch(MIWH);
3589 if (((&*SourceLocation != MIWH) && isBranchMIWH) ||
3593 PreviousBB = CurrentBB;
3597 MachineBasicBlock *PredTBB = NULL;
3598 MachineBasicBlock *PredFBB = NULL;
3609 if (!canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3612 CleanupBB->
erase(InstrToMove);
3616 SpeculatedIns.insert(
3617 std::make_pair(OriginalInstructionToMove, OriginBB));
3618 LLVM_DEBUG(
dbgs() <<
"\nSpeculatedInsToMove"; InstrToMove->dump());
3626 if (NeedToPredicate) {
3628 <<
"\tUnderimplemented pred for speculative move.\n");
3630 CleanupBB->
erase(InstrToMove);
3634 insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove, NeedCleanup);
3636 NeedToPredicate =
false;
3637 assert(!NeedToPredicate &&
"Need to handle predication for this case");
3638 CleanupBB = CurrentBB;
3642 bool LocalNeedPredication =
true;
3644 if (!isBranchMIWH && !PredTBB) {
3645 LLVM_DEBUG(
dbgs() <<
"\tDo not need predicate for this case.\n");
3646 LocalNeedPredication =
false;
3649 if (IsDualJumpSecondCandidate(&*InstrToMove) &&
3650 IsDualJumpFirstCandidate(TargetPacket)) {
3653 }
else if (LocalNeedPredication && (PredFBB != PreviousBB)) {
3659 if (PreviousBB != PredTBB) {
3664 CleanupBB->
erase(InstrToMove);
3669 <<
")InvertCondition("
3670 << (PreviousBB != PredTBB) <<
")\n");
3675 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3678 NeedToPredicate =
true;
3679 CleanupBB = CurrentBB;
3681 if (PredCond.
empty() &&
3684 InstrToMove->dump());
3691 isJumpOutOfRange(&*InstrToMove)) &&
3692 !tryAllocateResourcesForConstExt(&*InstrToMove,
false)) {
3695 <<
"\tEI Could not be added to the packet.\n");
3696 CleanupBB->
erase(InstrToMove);
3700 if (!ResourceTracker->canReserveResources(*InstrToMove) ||
3701 !shouldAddToPacket(*InstrToMove)) {
3704 CurrentBB->
erase(InstrToMove);
3709 if (NeedToNewify(InstrToMove, &DepReg, &*TargetPacket)) {
3710 if (isNewifiable(InstrToMove, DepReg, &*TargetPacket)) {
3711 MINeedToNewify =
true;
3713 <<
printReg(DepReg, QRI) <<
").\n");
3716 InstrToMove->dump());
3717 CleanupBB->
erase(InstrToMove);
3725 if (!
Cond.empty() && (
Cond.size() == 2)) {
3726 MIUseSet[OriginalInstructionToMove].push_back(
Cond[1].
getReg());
3730 "Update MIUseSet for new-value compare jumps");
3734 InstrToMove->dump());
3735 bool DistantSpeculation =
false;
3736 std::vector<MachineInstr *> NonPredPullUpPath;
3741 while (btidx < backtrack.size()) {
3742 const MachineBasicBlock *btBB = backtrack[btidx]->getParent();
3743 if ((btBB == PreviousBB) || (btBB == CurrentBB))
3744 NonPredPullUpPath.push_back(backtrack[btidx]);
3748 if (PreviousBB != CurrentBB) {
3749 if (*(PreviousBB->
pred_begin()) != CurrentBB) {
3751 DistantSpeculation =
true;
3753 <<
"\n\tMI not in immediate successor of BB#"
3754 << CurrentBB->
getNumber() <<
", MI is in BB#"
3758 "Region with a side entry");
3761 if (DistantSpeculation ||
3762 InstrToMove->mayLoad() || InstrToMove->mayStore() ||
3763 InstrToMove->hasUnmodeledSideEffects() ||
3764 !canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3765 NonPredPullUpPath)) {
3766 CleanupBB->
erase(InstrToMove);
3770 NeedToPredicate =
false;
3771 SpeculatedIns.insert(
3772 std::make_pair(OriginalInstructionToMove, OriginBB));
3774 InstrToMove->dump());
3781 InstrToMove->dump());
3784 InstrToMove->mayLoad() || InstrToMove->mayStore() ||
3785 InstrToMove->hasUnmodeledSideEffects() ||
3786 !canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3789 CleanupBB->
erase(InstrToMove);
3793 SpeculatedIns.insert(
3794 std::make_pair(OriginalInstructionToMove, OriginBB));
3796 InstrToMove->dump());
3799 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3802 CleanupBB = CurrentBB;
3807 <<
"\tCurrentBB:" << CurrentBB->
getNumber()
3808 <<
"\tPreviousBB:" << PreviousBB->
getNumber();
3810 <<
"\tPredFBB:" << PredFBB->
getNumber(););
3814 if (IsDualJumpSecondCandidate(&*InstrToMove)) {
3816 LLVM_DEBUG(
dbgs() <<
"\tUnderimplemented dual jump formation.\n");
3818 CleanupBB->
erase(InstrToMove);
3825 CleanupBB->
erase(InstrToMove);
3828 SpeculatedIns.insert(
3829 std::make_pair(OriginalInstructionToMove, OriginBB));
3831 InstrToMove->dump());
3833 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3836 NeedToPredicate =
false;
3837 CleanupBB = CurrentBB;
3845 if (MIWH == backtrack.front()) {
3856 if (!(MovingDependentOp && (MIWH == &*SourceLocation)) &&
3857 !canReorderMIs(MIWH, &*InstrToMove)) {
3859 CleanupBB->
erase(InstrToMove);
3866 isJumpOutOfRange(&*InstrToMove)) {
3867 if (!tryAllocateResourcesForConstExt(&*InstrToMove))
3876 if (MovingDependentOp)
dbgs() <<
"dependent op";
dbgs() <<
": ";
3877 InstrToMove->dump();
dbgs() <<
"To BB:\n"; HomeBB->
dump();
3878 dbgs() <<
"From BB:\n"; OriginBB->
dump());
3882 HexagonNumPullUps++;
3884 HexagonNumDualJumps++;
3890 insertTempCopy(HomeBB, TargetPacket, &*InstrToMove, NeedCleanup);
3898 if (!TargetPacket->isBundle()) {
3901 std::next(InstrToMove));
3908 for (
unsigned i = 0; i < backtrack.size(); ++i)
3909 if (backtrack[i] == &*TargetPacket)
3910 backtrack[i] = &*MII;
3913 if (NextMI == TargetPacket)
3919 MoveAndUpdateLiveness(CurrentRegion, HomeBB, &*InstrToMove, MINeedToNewify,
3920 DepReg, MovingDependentOp, OriginBB,
3921 OriginalInstructionToMove, PredCond, SourceLocation,
3922 TargetPacket, NextMI, backtrack);
3931bool HexagonGlobalSchedulerImpl::isBranchWithinRegion(
3932 BasicBlockRegion *CurrentRegion, MachineInstr *
MI) {
3933 assert(
MI &&
MI->isBranch() &&
"Missing call info");
3937 <<
") Branch instr:\t";
3947 MachineBasicBlock *NextRegionBB;
3948 MachineBasicBlock *
TBB, *FBB;
3949 MachineInstr *FirstTerm = NULL;
3950 MachineInstr *SecondTerm = NULL;
3952 if (AnalyzeBBBranches(
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
3985 else dbgs() <<
"None\n";);
3997 if (!NextRegionBB) {
4006 if (
MI == FirstTerm) {
4008 <<
") NextBB in the region(" << NextRegionBB->
getNumber()
4010 return (
TBB == NextRegionBB);
4012 assert(FBB &&
"Corrupt BB layout");
4016 if ((
MI != SecondTerm)) {
4017 LLVM_DEBUG(
dbgs() <<
"\t\tDual terminator not matching SecondTerm.\n");
4022 <<
") NextBB in the region(" << NextRegionBB->
getNumber()
4024 return (FBB == NextRegionBB);
4031bool HexagonGlobalSchedulerImpl::isJumpOutOfRange(MachineInstr *UnCond,
4032 MachineInstr *
Cond) {
4033 if (!UnCond || !UnCond->
isBranch())
4036 MachineBasicBlock *UnCondBB = UnCond->
getParent();
4043 unsigned InstOffset = BlockToInstOffset[UnCondBB];
4044 unsigned Distance = 0;
4051 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4062 if (
TBB && (
Cond == FirstTerm)) {
4064 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[
TBB]) +
4073MachineInstr *HexagonGlobalSchedulerImpl::findBundleAndBranch(
4078 MachineInstr *CondBranch = NULL;
4082 MII != MBBEnd; ++MII) {
4083 MachineInstr *
MI = &*MII;
4084 if (MII->isConditionalBranch()) {
4091 if (!MII->isBundled())
4094 for (--MII; MII->isBundled(); --MII)
4095 if (MII->isBundle()) {
4107bool HexagonGlobalSchedulerImpl::pullUpPeelBBLoop(MachineBasicBlock *PredBB,
4108 MachineBasicBlock *LoopBB) {
4111 if (!LoopBB || !PredBB)
4126 MachineBasicBlock *SuccBB = NULL;
4130 if (*SI != LoopBB) {
4139 MachineInstr *PredCondBranch = NULL;
4140 PredCondBranch = findBundleAndBranch(PredBB, PredBundle);
4141 if (!PredCondBranch)
4143 if (PredBundle == PredBB->
end())
4151 while (FMI->isDebugInstr())
4154 MachineInstr *RegMI = &*FMI;
4158 if (TfrOpcode != Hexagon::A2_tfr && TfrOpcode != Hexagon::A2_tfr)
4167 BasicBlockRegion PUR(BasicBlockRegion(
TII, QRI, PredBB));
4172 if (!ResourcesAvailableInBundle(&PUR, PredBundle))
4175 CurrentState.HomeBundle);
4178 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4186 MachineBasicBlock *LTBB = NULL, *LFBB = NULL;
4196 MachineInstr *InstrToMove =
4197 &*insertTempCopy(PredBB, PredBundle, RegMI,
false);
4198 if (!canAddMIToThisPacket(InstrToMove, PredBundlePkt)) {
4210 unsigned DepReg = 0;
4211 if (NeedToNewify(InstrToMove->
getIterator(), &DepReg, &*PredBundle) &&
4212 !isNewifiable(InstrToMove->
getIterator(), DepReg, &*PredBundle)) {
4223 InstrToMove->
setDesc(QII->get(NewOpcode));
4224 if (!incrementalAddToPacket(*InstrToMove)) {
4231 MachineInstr *LoopCondBranch = NULL;
4232 LoopCondBranch = findBundleAndBranch(LoopBB, LoopBundle);
4233 if (!LoopCondBranch)
4235 if (LoopBundle == LoopBB->
end())
4241 if (!ResourcesAvailableInBundle(&PUR, LoopBundle))
4244 CurrentState.HomeBundle);
4247 MachineInstr *InstrToSink =
4248 &*insertTempCopy(LoopBB, LoopBundle, RegMI,
false);
4249 if (!canAddMIToThisPacket(InstrToSink, LoopBundlePkt)) {
4263 if (NeedToNewify(InstrToSink->
getIterator(), &DepReg, &*LoopBundle) &&
4264 !isNewifiable(InstrToSink->
getIterator(), DepReg, &*LoopBundle)) {
4274 InstrToSink->
setDesc(QII->get(NewOpcode));
4275 if (!incrementalAddToPacket(*InstrToSink)) {
4297bool HexagonGlobalSchedulerImpl::performPullUpCFG(
MachineFunction &Fn) {
4300 if (std::next(
F.begin()) ==
F.end())
4307 MachineBasicBlock *PrevBlock = NULL;
4308 MachineBasicBlock *JumpBlock = NULL;
4311 MachineBasicBlock *FallBlock = &*
MBB;
4312 if (PrevBlock && JumpBlock) {
4313 Changed |= pullUpPeelBBLoop(PrevBlock, JumpBlock);
4315 PrevBlock = JumpBlock;
4316 JumpBlock = FallBlock;
4322 std::vector<unsigned> Defs;
4323 std::vector<unsigned>
Uses;
4327 MIter != MBBIter->instr_end(); ++MIter) {
4328 if (MIter->isBundle() || MIter->isDebugInstr())
4331 MIUseDefSet(&*MIter, Defs,
Uses);
4333 for (
unsigned i = 0; i < Defs.size(); ++i)
dbgs()
4336 for (
unsigned i = 0; i <
Uses.size(); ++i)
dbgs()
4338 MIDefSet[&*MIter] = Defs;
4339 MIUseSet[&*MIter] =
Uses;
4355MachineBasicBlock *HexagonGlobalSchedulerImpl::optimizeBranches(
4356 MachineBasicBlock *
MBB, MachineBasicBlock *
TBB, MachineInstr *FirstTerm,
4357 MachineBasicBlock *FBB) {
4369 if (TBBMIb->
getOpcode() == Hexagon::J2_jump &&
4372 if (
TBB == NewTarget)
4377 int64_t InstOffset =
4379 unsigned Distance = (unsigned)std::abs(
4380 InstOffset - BlockToInstOffset.
find(NewTarget)->second);
4383 <<
" out of range.");
4416 if (FBBMIb->
getOpcode() == Hexagon::J2_jump &&
4425 int64_t InstOffset =
4427 unsigned Distance = (unsigned)std::abs(
4428 InstOffset - BlockToInstOffset.
find(NewTarget)->second);
4431 <<
" out of range.");
4450bool HexagonGlobalSchedulerImpl::performExposedOptimizations(
4457 std::vector<MachineBasicBlock *>::iterator ebb = EmptyBBs.begin();
4458 while (ebb != EmptyBBs.end()) {
4461 <<
") from parent.\n");
4462 (*ebb)->eraseFromParent();
4465 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4466 MachineInstr *FirstTerm = NULL, *SecondTerm = NULL;
4468 SmallVector<MachineBasicBlock *, 4> Erase;
4470 for (MachineBasicBlock &
MBB : Fn) {
4472 AnalyzeBBBranches(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4479 if (
TBB && FirstTerm &&
4480 removeRedundantBranches(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4485 if (FirstTerm && SecondTerm &&
4486 optimizeDualJumps(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4491 if (
TBB && FBB && FirstTerm && !SecondTerm) {
4492 MachineBasicBlock *MBBToErase =
4493 optimizeBranches(&
MBB,
TBB, FirstTerm, FBB);
4501 for (MachineBasicBlock *
MBB : Erase)
4509bool HexagonGlobalSchedulerImpl::removeRedundantBranches(
4510 MachineBasicBlock *
MBB, MachineBasicBlock *
TBB, MachineInstr *FirstTerm,
4511 MachineBasicBlock *FBB, MachineInstr *SecondTerm) {
4512 bool Analyzed =
false;
4514 MachineInstr *Head = NULL, *ToErase = NULL;
4515 if (!FBB && (FirstTerm->
getOpcode() == Hexagon::J2_jump) &&
4519 dbgs() <<
"\nRemoving Uncond. jump to the layout successor in BB#"
4521 ToErase = FirstTerm;
4522 }
else if (SecondTerm && (
TBB == FBB) &&
4523 (SecondTerm->
getOpcode() == Hexagon::J2_jump)) {
4532 if (++FirstTermIter == SecondTermIter) {
4533 LLVM_DEBUG(
dbgs() <<
"\nRemoving multiple branching to same target in BB#"
4537 ToErase = FirstTerm;
4539 }
else if (SecondTerm && (SecondTerm->
getOpcode() == Hexagon::J2_jump) &&
4545 ToErase = SecondTerm;
4552 LLVM_DEBUG(
dbgs() <<
"\nRemoving Cond. jump to the layout successor in BB#"
4554 ToErase = SecondTerm;
4558 if (ToErase->isBundled()) {
4560 ToErase->eraseFromBundle();
4563 ToErase->eraseFromParent();
4577bool HexagonGlobalSchedulerImpl::optimizeDualJumps(MachineBasicBlock *
MBB,
4578 MachineBasicBlock *
TBB,
4579 MachineInstr *FirstTerm,
4580 MachineBasicBlock *FBB,
4581 MachineInstr *SecondTerm) {
4584 bool Analyzed =
false;
4587 (SecondTerm->
getOpcode() == Hexagon::J2_jump)) {
4599 MachineInstr *
SI = &*SII;
4600 std::map<MachineInstr *, MachineBasicBlock *>::iterator MIMoved;
4601 MIMoved = SpeculatedIns.find(SI);
4602 if ((MIMoved != SpeculatedIns.end()) &&
4603 (MIMoved->second !=
SI->getParent())) {
4616 int64_t InstOffset =
4619 (unsigned)std::abs(InstOffset - BlockToInstOffset.
find(FBB)->second) +
4623 <<
" out of range.");
4637 MachineInstr *SecondHead, *FirstHead;
4648 else if (!FirstHead) {
4652 }
else if (FirstHead == SecondHead) {
4654 assert((FirstHead && SecondHead) &&
"Unbundled Instruction");
4656 if (SecondHead->getBundleSize() < 2)
4670bool HexagonGlobalSchedulerImpl::ResourcesAvailableInBundle(
4671 BasicBlockRegion *CurrentRegion,
4676 if (!TargetPacket->isBundle()) {
4677 if (ignoreInstruction(&*MII) || isSoloInstruction(*MII))
4682 if (MII->isBranch() && !isBranchWithinRegion(CurrentRegion, &*MII))
4688 initPacketizerState();
4689 ResourceTracker->clearResources();
4690 CurrentState.addHomeLocation(MII);
4691 return incrementalAddToPacket(*MII);
4697 initPacketizerState();
4698 ResourceTracker->clearResources();
4699 CurrentState.addHomeLocation(MII);
4701 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
4702 if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
4703 MII->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
4704 MII->getOpcode() == TargetOpcode::CFI_INSTRUCTION || MII->isEHLabel())
4717 if (MII->isBranch() && !isBranchWithinRegion(CurrentRegion, &*MII))
4720 if (!incrementalAddToPacket(*MII))
4723 return ResourceTracker->canReserveResources(*Nop);
4727bool HexagonGlobalSchedulerImpl::isCompoundPair(MachineInstr *MIa,
4728 MachineInstr *MIb) {
4735 (Opcb == Hexagon::A2_tfr || Opcb == Hexagon::A2_tfrsi))
4739 (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
4748inline bool HexagonGlobalSchedulerImpl::multipleBranchesFromToBB(
4749 MachineBasicBlock *BB)
const {
4753 return ((Jumpers.
size() == 1) && !Jumpers[0]->isUnconditionalBranch());
4758bool HexagonGlobalSchedulerImpl::findPullUpCandidates(
4761 std::vector<MachineInstr *> &backtrack,
unsigned MaxCandidates = 1) {
4763 const HexagonInstrInfo *QII = (
const HexagonInstrInfo *)
TII;
4764 MachineBasicBlock *FromThisBB = FromHere->getParent();
4765 bool MovingDependentOp =
false;
4769 if (CurrentState.haveCandidates() >= MaxCandidates)
4775 if (FromHere->isBundle()) {
4777 for (++MII; MII != FromThisBB->
instr_end() && MII->isInsideBundle();
4779 if (MII->isDebugInstr())
4782 << MII->getParent()->getNumber() <<
"): ";
4786 if (!canThisMIBeMoved(&*MII, WorkPoint, MovingDependentOp,
CostBenefit))
4790 if (canAddMIToThisPacket(&*InstrToMove, CurrentState.HomeBundle)) {
4795 if (MII->isCompare())
4798 for (
unsigned i = 0; i < CurrentState.HomeBundle.size(); i++) {
4799 if (QII->
isDuplexPair(*CurrentState.HomeBundle[i], *MII)) {
4803 if (isCompoundPair(CurrentState.HomeBundle[i], &*MII)) {
4809 CurrentState.addPullUpCandidate(InstrToMove, WorkPoint, backtrack,
4818 else if (canThisMIBeMoved(&*FromHere, WorkPoint, MovingDependentOp,
4821 if (canAddMIToThisPacket(&*InstrToMove, CurrentState.HomeBundle)) {
4824 if (InstrToMove->isCompare())
4830 for (
unsigned i = 0; i < CurrentState.HomeBundle.size(); i++) {
4831 if (QII->
isDuplexPair(*CurrentState.HomeBundle[i], *InstrToMove)) {
4835 if (isCompoundPair(CurrentState.HomeBundle[i], &*InstrToMove)) {
4841 CurrentState.addPullUpCandidate(InstrToMove, WorkPoint, backtrack,
4844 LLVM_DEBUG(
dbgs() <<
"\tNo resources for single in the target packet.\n");
4852bool HexagonGlobalSchedulerImpl::tryMultipleInstructions(
4854 std::vector<BasicBlockRegion *>::iterator &CurrentRegion,
4861 bool MovingDependentOp =
false;
4862 std::vector<MachineInstr *> backtrack;
4866 std::sort(CurrentState.PullUpCandidates.begin(),
4867 CurrentState.PullUpCandidates.end(), PullUpCandidateSorter());
4870 for (SmallVector<PullUpCandidate *, 4>::iterator
4871 I = CurrentState.PullUpCandidates.begin(),
4872 E = CurrentState.PullUpCandidates.end();
4874 (*I)->populate(MII, WorkPoint, backtrack, MovingDependentOp);
4876 MachineBasicBlock *FromThisBB = MII->
getParent();
4877 MachineBasicBlock *ToThisBB = WorkPoint->getParent();
4880 LLVM_DEBUG(
dbgs() <<
"\tDependent(" << MovingDependentOp <<
") FromBB("
4882 << ToThisBB->
getNumber() <<
") to this packet:\n";
4886 if (MII->isInsideBundle()) {
4887 while (!FromHereII->isBundle())
4893 if (MoveMItoBundle(*CurrentRegion, MII, NextMI, WorkPoint, FromHere,
4894 backtrack, MovingDependentOp, PathInRegion)) {
4900 FromThisBBEnd = FromThisBB->
end();
4901 ToThisBBEnd = ToThisBB->
end();
4915 if (MoveMItoBundle(*CurrentRegion, MII, NextMI, WorkPoint, FromHere,
4916 backtrack, MovingDependentOp, PathInRegion)) {
4923 FromThisBBEnd = FromThisBB->
end();
4924 ToThisBBEnd = ToThisBB->
end();
4951bool HexagonGlobalSchedulerImpl::performPullUp() {
4952 std::vector<MachineInstr *> backtrack;
4958 for (std::vector<BasicBlockRegion *>::iterator
4959 CurrentRegion = PullUpRegions.begin(),
4960 E = PullUpRegions.end();
4961 CurrentRegion !=
E; ++CurrentRegion) {
4963 LLVM_DEBUG(
dbgs() <<
"\n\nRegion with(" << (*CurrentRegion)->size()
4971 for (
auto ToThisBB = (*CurrentRegion)->getRootMBB(),
4972 LastBBInRegion = (*CurrentRegion)->getLastMBB();
4973 ToThisBB != LastBBInRegion; ++ToThisBB) {
4977 if (multipleBranchesFromToBB(*ToThisBB))
4980 auto FromThisBB = ToThisBB;
4985 << (*ToThisBB)->getNumber() <<
")\n";
4986 (*ToThisBB)->dump());
4989 while (
MI != ToThisBBEnd) {
4995 while (ResourcesAvailableInBundle(*CurrentRegion, WorkPoint)) {
4997 << (*ToThisBB)->getNumber() <<
"):\n";
5011 FromThisBB = ToThisBB;
5012 FromHere = WorkPoint;
5014 FromThisBBEnd = (*FromThisBB)->end();
5021 backtrack.push_back(&*
I);
5023 FromThisBB = ToThisBB;
5025 FromHere = (*FromThisBB)->begin();
5026 FromThisBBEnd = (*FromThisBB)->end();
5033 backtrack.push_back(&*
I);
5040 if (FromHere == FromThisBBEnd) {
5044 LastBBInRegion = (*CurrentRegion)->getLastMBB();
5045 if (FromThisBB == LastBBInRegion)
5049 (*FromThisBB)->dump());
5050 FromThisBBEnd = (*FromThisBB)->end();
5051 FromHere = (*FromThisBB)->begin();
5052 if (FromThisBBEnd == FromHere)
5056 if ((*FromHere).isDebugInstr()) {
5061 backtrack.push_back(&*FromHere);
5062 if (!findPullUpCandidates(WorkPoint, FromHere, backtrack,
5068 if (!tryMultipleInstructions( WorkPoint, CurrentRegion,
MI,
5069 ToThisBBEnd, FromThisBBEnd))
5074 LastBBInRegion = (*CurrentRegion)->getLastMBB();
5087 std::vector<std::pair<MachineBasicBlock *, MachineBasicBlock *>>
5089 UnlikelyWork.reserve((*CurrentRegion)->size());
5090 for (
auto ToIt = (*CurrentRegion)->getRootMBB(),
5091 End = (*CurrentRegion)->getLastMBB();
5092 ToIt != End; ++ToIt) {
5093 MachineBasicBlock *ToBB = *ToIt;
5094 MachineBasicBlock *SecondBest = getNextPURBB(ToBB,
true);
5096 UnlikelyWork.emplace_back(ToBB, SecondBest);
5099 for (
auto [ToBB, SecondBest] : UnlikelyWork) {
5104 (*CurrentRegion)->addBBtoRegion(SecondBest);
5112 while (
MI != ToThisBBEnd) {
5118 while (ResourcesAvailableInBundle(*CurrentRegion, WorkPoint)) {
5123 FromHere = SecondBest->
begin();
5124 FromThisBBEnd = SecondBest->
end();
5132 backtrack.push_back(&*
I);
5137 if (FromHere == FromThisBBEnd) {
5139 <<
"\tOnly do one successor for the second try\n");
5142 if ((*FromHere).isDebugInstr()) {
5147 backtrack.push_back(&*FromHere);
5148 if (!findPullUpCandidates(WorkPoint, FromHere, backtrack,
5154 if (!tryMultipleInstructions( WorkPoint, CurrentRegion,
MI,
5155 ToThisBBEnd, FromThisBBEnd,
false))
5164bool HexagonGlobalSchedulerImpl::incrementalAddToPacket(MachineInstr &
MI) {
5166 LLVM_DEBUG(
dbgs() <<
"\t[AddToPacket] (" << CurrentPacketMIs.size()
5170 if (!ResourceTracker->canReserveResources(
MI) || !shouldAddToPacket(
MI))
5173 ResourceTracker->reserveResources(
MI);
5174 CurrentPacketMIs.push_back(&
MI);
5175 CurrentState.HomeBundle.push_back(&
MI);
5178 isJumpOutOfRange(&
MI)) {
5184 if (ResourceTracker->canReserveResources(*Ext)) {
5185 ResourceTracker->reserveResources(*Ext);
5186 LLVM_DEBUG(
dbgs() <<
"\t[AddToPacket] (" << CurrentPacketMIs.size()
5187 <<
") adding:\t immext_i\n");
5188 CurrentPacketMIs.push_back(Ext);
5189 CurrentState.HomeBundle.push_back(Ext);
5199void HexagonGlobalSchedulerImpl::checkBundleCounts(
MachineFunction &Fn) {
5203 unsigned BundleLimit = 4;
5206 MBBi != MBBe; ++MBBi) {
5209 ME = MBBi->instr_end();
5211 if (
MI->isBundle()) {
5217 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
5218 if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
5219 MII->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
5220 MII->getOpcode() == TargetOpcode::CFI_INSTRUCTION ||
5221 MII->isEHLabel() || QII->
isEndLoopN(MII->getOpcode())) {
5231 assert(0 &&
"Bundle size exceeded");
5240unsigned HexagonGlobalSchedulerImpl::countCompounds(
MachineFunction &Fn) {
5241 unsigned CompoundCount = 0;
5242 [[maybe_unused]]
unsigned DuplexCount = 0;
5243 [[maybe_unused]]
unsigned InstOffset = 0;
5254 if (
MI->isDebugInstr())
5256 if (
MI->isBundle()) {
5259 MachineInstr *FirstCompound = NULL, *SecondCompound = NULL;
5260 MachineInstr *FirstDuplex = NULL, *SecondDuplex = NULL;
5263 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
5265 if (MII->isDebugInstr())
5268 InstOffset += QII->
getSize(*MII);
5270 if (!FirstCompound) {
5271 FirstCompound = &*MII;
5274 SecondCompound = &*MII;
5280 FirstDuplex = &*MII;
5283 SecondDuplex = &*MII;
5290 if (SecondCompound) {
5291 if (isCompoundPair(FirstCompound, SecondCompound)) {
5292 LLVM_DEBUG(
dbgs() <<
"Compound pair (" << CompoundCount <<
")\n");
5313 LLVM_DEBUG(
dbgs() <<
"Total compound(" << CompoundCount <<
") duplex("
5314 << DuplexCount <<
")\n");
5315 return CompoundCount;
5323 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 > SpeculateNonPredInsn("speculate-non-pred-insn", cl::Hidden, cl::Optional, cl::init(true), cl::desc("Speculate non-predicable instructions in parent BB"))
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 cl::opt< bool > PostPullUpOpt("post-pull-up-opt", cl::Hidden, cl::Optional, cl::init(true), cl::desc("Enable opt. exposed by pull-up e.g., remove redundant jumps"))
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 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)
#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.