59#define DEBUG_TYPE "global_sched"
63STATISTIC(HexagonNumPullUps,
"Number of instructions pull-ups");
64STATISTIC(HexagonNumDualJumps,
"Number of dual jumps formed");
67 cl::desc(
"Disable Hexagon pull-up pass"));
71 cl::desc(
"Enable speculation during Hexagon pull-up pass"));
75 cl::desc(
"Enable same BB pull during Hexagon pull-up pass"));
79 cl::desc(
"Allow speculative loads during Hexagon pull-up pass"));
83 cl::desc(
"Allow compare-branch loads during Hexagon pull-up pass"));
87 cl::desc(
"Allow unlikely path pull up"));
91 cl::desc(
"Perform dual jump formation during pull up"));
95 cl::desc(
"Perform dual jump formation during pull up"));
99 cl::desc(
"Peel a reg copy out of a BBloop"));
103 cl::desc(
"Do not destroy existing compounds during pull up"));
107 cl::desc(
"Do not destroy existing duplexes during pull up"));
117 cl::desc(
"Enable opt. exposed by pull-up e.g., remove redundant jumps"));
121 cl::desc(
"Speculate non-predicable instructions in parent BB"));
126 cl::desc(
"Disable Hexagon check bundles pass"));
130 cl::desc(
"Hexagon check bundles and warn on size"));
134 cl::desc(
"Force noop hazards in scheduler"));
137 cl::desc(
"Allow only one single floating point instruction in a packet"));
140 cl::desc(
"Allow only one complex instruction in a packet"));
148class HexagonGlobalSchedulerImpl;
153 HexagonGlobalScheduler() : MachineFunctionPass(ID) {
157 void getAnalysisUsage(AnalysisUsage &AU)
const override {
161 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
162 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
167 StringRef getPassName()
const override {
return "Hexagon Global Scheduler"; }
169 bool runOnMachineFunction(MachineFunction &Fn)
override;
171char HexagonGlobalScheduler::ID = 0;
174class PullUpCandidate {
179 std::vector<MachineInstr *> Backtrack;
183 CandidateLocation = MII;
189 std::vector<MachineInstr *> &backtrack,
bool DependentOp,
191 : CandidateLocation(MII), HomeBundle(HomeBundle),
192 DependentOp(DependentOp), BenefitCost(
Cost) {
194 Backtrack = backtrack;
199 std::vector<MachineInstr *> &backtrack,
bool &dependentOp) {
200 MII = CandidateLocation;
201 WorkPoint = HomeBundle;
202 backtrack = Backtrack;
203 dependentOp = DependentOp;
206 signed getCost() {
return BenefitCost; }
208 MachineInstr *getCandidate() {
return &*CandidateLocation; }
211 dbgs() <<
"Cost(" << BenefitCost;
212 dbgs() <<
") Dependent(" << DependentOp;
213 dbgs() <<
") backtrack size(" << Backtrack.size() <<
")\t";
214 CandidateLocation->dump();
219struct PullUpCandidateSorter {
220 PullUpCandidateSorter() {}
221 bool operator()(PullUpCandidate *
LHS, PullUpCandidate *
RHS) {
222 return LHS->getCost() >
RHS->getCost();
230 friend class HexagonGlobalSchedulerImpl;
239 const HexagonInstrInfo *QII;
242 PullUpState(
const HexagonInstrInfo *QII) : HomeLocation(NULL), QII(QII) {}
244 ~PullUpState() { reset(); }
248 std::vector<MachineInstr *> &backtrack,
249 bool DependentOp,
signed Cost) {
251 PullUpCandidate *PUI =
252 new PullUpCandidate(MII, HomeBundle, backtrack, DependentOp,
Cost);
253 PullUpCandidates.push_back(PUI);
257 unsigned element = 0;
258 for (
unsigned i = 0; i < HomeBundle.size(); i++) {
259 dbgs() <<
"[" << element++;
260 dbgs() <<
"] Home Duplex("
261 << QII->getDuplexCandidateGroup(*HomeBundle[i]);
262 dbgs() <<
") Compound (" << QII->getCompoundCandidateGroup(*HomeBundle[i])
264 HomeBundle[i]->dump();
268 for (SmallVector<PullUpCandidate *, 4>::iterator
269 I = PullUpCandidates.begin(),
270 E = PullUpCandidates.end();
272 dbgs() <<
"[" << element++ <<
"] Cand: Compound(";
273 dbgs() << QII->getCompoundCandidateGroup(*(*I)->getCandidate()) <<
") ";
280 for (SmallVector<PullUpCandidate *, 4>::iterator
281 I = PullUpCandidates.begin(),
282 E = PullUpCandidates.end();
285 PullUpCandidates.clear();
291 HomeLocation = WorkPoint;
294 unsigned haveCandidates() {
return PullUpCandidates.size(); }
299 std::vector<BasicBlockRegion *> PullUpRegions;
302 DenseMap<MachineBasicBlock *, unsigned> BlockToInstOffset;
304 PullUpState CurrentState;
306 std::vector<MachineBasicBlock *> EmptyBBs;
312 std::map<MachineInstr *, MachineBasicBlock *> SpeculatedIns;
314 std::map<MachineInstr *, std::vector<unsigned>> MIUseSet;
316 std::map<MachineInstr *, std::vector<unsigned>> MIDefSet;
319 const MachineBranchProbabilityInfo *MBPI;
320 const MachineBlockFrequencyInfo *MBFI;
321 const MachineRegisterInfo *MRI;
322 const MachineFrameInfo &MFI;
323 const HexagonRegisterInfo *QRI;
324 const HexagonInstrInfo *QII;
325 MachineLoopInfo &MLI;
326 MachineDominatorTree &MDT;
327 MachineInstrBuilder Ext;
328 MachineInstrBuilder Nop;
329 const unsigned PacketSize;
330 TargetSchedModel TSchedModel;
334 HexagonGlobalSchedulerImpl(MachineFunction &MF, MachineLoopInfo &MLI,
336 const MachineBranchProbabilityInfo *MBPI,
337 const MachineBlockFrequencyInfo *MBFI,
338 const MachineRegisterInfo *MRI,
339 const MachineFrameInfo &MFI,
340 const HexagonRegisterInfo *QRI);
341 HexagonGlobalSchedulerImpl(
const HexagonGlobalSchedulerImpl &) =
delete;
342 HexagonGlobalSchedulerImpl &
343 operator=(
const HexagonGlobalSchedulerImpl &) =
delete;
345 ~HexagonGlobalSchedulerImpl() {
347 for (std::vector<BasicBlockRegion *>::iterator
I = PullUpRegions.begin(),
348 E = PullUpRegions.end();
351 MF.deleteMachineInstr(Ext);
352 MF.deleteMachineInstr(Nop);
356 void initPacketizerState()
override;
359 bool ignoreInstruction(MachineInstr *
MI);
363 bool isSoloInstruction(
const MachineInstr &
MI)
override;
366 bool incrementalAddToPacket(MachineInstr &
MI);
369 bool formPullUpRegions(MachineFunction &Fn);
372 bool performPullUp();
375 bool performPullUpCFG(MachineFunction &Fn);
379 bool performExposedOptimizations(MachineFunction &Fn);
392 MachineBasicBlock *optimizeBranches(MachineBasicBlock *
MBB,
393 MachineBasicBlock *
TBB,
394 MachineInstr *FirstTerm,
395 MachineBasicBlock *FBB);
400 bool removeRedundantBranches(MachineBasicBlock *
MBB, MachineBasicBlock *
TBB,
401 MachineInstr *FirstTerm, MachineBasicBlock *FBB,
402 MachineInstr *SecondTerm);
406 bool optimizeDualJumps(MachineBasicBlock *
MBB, MachineBasicBlock *
TBB,
407 MachineInstr *FirstTerm, MachineBasicBlock *FBB,
408 MachineInstr *SecondTerm);
410 void GenUseDefChain(MachineFunction &Fn);
413 BasicBlockRegion *getRegionForMBB(std::vector<BasicBlockRegion *> &Regions,
414 MachineBasicBlock *
MBB);
418 void MIUseDefSet(MachineInstr *
MI, std::vector<unsigned> &Defs,
419 std::vector<unsigned> &
Uses);
422 unsigned countCompounds(MachineFunction &Fn);
425 void checkBundleCounts(MachineFunction &Fn);
429 MachineBasicBlock *getNextPURBB(MachineBasicBlock *
MBB,
bool SecondBest);
431 void setUsedRegs(BitVector &Set,
unsigned Reg);
432 bool AliasingRegs(
unsigned RegA,
unsigned RegB);
435 bool ReorderDependencyTest(MachineInstr *MIa, MachineInstr *MIb);
437 bool canAddMIToThisPacket(
441 bool CanPromoteToDotNew(MachineInstr *
MI,
unsigned Reg);
443 bool pullUpPeelBBLoop(MachineBasicBlock *PredBB, MachineBasicBlock *LoopBB);
445 MachineInstr *findBundleAndBranch(MachineBasicBlock *BB,
449 bool ResourcesAvailableInBundle(BasicBlockRegion *CurrentRegion,
453 MachineInstr *MoveAndUpdateLiveness(
454 BasicBlockRegion *CurrentRegion, MachineBasicBlock *HomeBB,
455 MachineInstr *InstrToMove,
bool NeedToNewify,
unsigned DepReg,
456 bool MovingDependentOp, MachineBasicBlock *OriginBB,
461 std::vector<MachineInstr *> &backtrack);
464 void updateKillAlongThePath(MachineBasicBlock *HomeBB,
465 MachineBasicBlock *OriginBB,
470 std::vector<MachineInstr *> &backtrack);
475 std::vector<MachineInstr *> &backtrack,
476 unsigned MaxCandidates);
479 bool tryMultipleInstructions(
481 std::vector<BasicBlockRegion *>::iterator &CurrentRegion,
487 bool MoveMItoBundle(BasicBlockRegion *CurrentRegion,
492 std::vector<MachineInstr *> &backtrack,
493 bool MovingDependentOp,
bool PathInRegion);
497 insertTempCopy(MachineBasicBlock *
MBB,
503 MachineInstr *
MI,
bool &LastInBundle);
506 MachineInstr *TargetPacket);
509 unsigned DepReg, MachineInstr *TargetPacket);
511 void addInstructionToExistingBundle(MachineBasicBlock *HomeBB,
517 std::vector<MachineInstr *> &backtrack);
519 void removeInstructionFromExistingBundle(
524 std::vector<MachineInstr *> &backtrack);
527 bool MIsCondAssign(MachineInstr *BMI, MachineInstr *
MI,
528 SmallVector<unsigned, 4> &Defs);
533 bool canMIBeSpeculated(MachineInstr *
MI, MachineBasicBlock *ToBB,
534 MachineBasicBlock *FromBB,
535 std::vector<MachineInstr *> &backtrack);
538 bool isBranchWithinRegion(BasicBlockRegion *CurrentRegion, MachineInstr *
MI);
541 bool MIsAreDependent(MachineInstr *MIa, MachineInstr *MIb);
542 bool MIsHaveTrueDependency(MachineInstr *MIa, MachineInstr *MIb);
543 bool canReorderMIs(MachineInstr *MIa, MachineInstr *MIb);
544 bool canCauseStall(MachineInstr *
MI, MachineInstr *MJ);
545 bool canThisMIBeMoved(MachineInstr *
MI,
547 bool &MovingDependentOp,
int &
Cost);
548 bool MIisDualJumpCandidate(MachineInstr *
MI,
550 bool DemoteToDotOld(MachineInstr *
MI);
552 MachineInstr *TargetPacket);
553 bool IsNewifyStore(MachineInstr *
MI);
554 bool isJumpOutOfRange(MachineInstr *
MI);
555 bool IsDualJumpFirstCandidate(MachineInstr *
MI);
556 bool IsDualJumpFirstCandidate(MachineBasicBlock *
MBB);
558 bool IsNotDualJumpFirstCandidate(MachineInstr *
MI);
559 bool isJumpOutOfRange(MachineInstr *UnCond, MachineInstr *
Cond);
560 bool IsDualJumpSecondCandidate(MachineInstr *
MI);
561 bool tryAllocateResourcesForConstExt(MachineInstr *
MI,
bool UpdateState);
562 bool isCompoundPair(MachineInstr *MIa, MachineInstr *MIb);
563 bool doesMIDefinesPredicate(MachineInstr *
MI, SmallVector<unsigned, 4> &Defs);
564 bool AnalyzeBBBranches(MachineBasicBlock *
MBB, MachineBasicBlock *&
TBB,
565 MachineInstr *&FirstTerm, MachineBasicBlock *&FBB,
566 MachineInstr *&SecondTerm);
567 inline bool multipleBranchesFromToBB(MachineBasicBlock *BB)
const;
572 "Hexagon Global Scheduler",
false,
false)
582HexagonGlobalSchedulerImpl::HexagonGlobalSchedulerImpl(
589 MBFI(MBFI),
MRI(
MRI), MFI(MFI), QRI(QRI), MLI(MLI), MDT(MDT),
590 PacketSize(MF.getSubtarget().getSchedModel().IssueWidth) {
594 TSchedModel.
init(&MF.getSubtarget());
602 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
603 if (MII->isDebugInstr())
611bool HexagonGlobalScheduler::runOnMachineFunction(
MachineFunction &Fn) {
618 const HexagonRegisterInfo *QRI = HST.getRegisterInfo();
619 MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
620 MachineDominatorTree &MDT =
621 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
622 const MachineBranchProbabilityInfo *MBPI =
623 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
624 const MachineBlockFrequencyInfo *MBFI =
625 &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
626 AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
634 HexagonGlobalSchedulerImpl GlobalSchedulerState(Fn, MLI, MDT, AA, MBPI, MBFI,
638 assert(GlobalSchedulerState.getResourceTracker() &&
"Empty DFA table!");
643 GlobalSchedulerState.checkBundleCounts(Fn);
649 LLVM_DEBUG(GlobalSchedulerState.countCompounds(Fn));
650 GlobalSchedulerState.GenUseDefChain(Fn);
651 GlobalSchedulerState.formPullUpRegions(Fn);
652 GlobalSchedulerState.performPullUp();
653 GlobalSchedulerState.performPullUpCFG(Fn);
655 GlobalSchedulerState.formPullUpRegions(Fn);
656 GlobalSchedulerState.performExposedOptimizations(Fn);
658 LLVM_DEBUG(GlobalSchedulerState.countCompounds(Fn));
665bool HexagonGlobalSchedulerImpl::tryAllocateResourcesForConstExt(
666 MachineInstr *
MI,
bool UpdateState =
true) {
667 if (ResourceTracker->canReserveResources(*Ext)) {
672 ResourceTracker->reserveResources(*Ext);
673 else if (CurrentPacketMIs.size() >= PacketSize - 1)
682 return MI->getOpcode() == Hexagon::Y2_barrier;
686 return MI->getOpcode() == Hexagon::J2_callr;
691 if (
MI->isBundledWithPred())
695 if (
MI->isBundledWithSucc())
704 dbgs() <<
"\tNULL\n";
711 dbgs() <<
"\tUnattached: ";
717 if (
MI->isBundle()) {
719 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
730 dbgs() <<
"\tBBEnd\n";
739 if (
MI->isBundle()) {
742 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
748 return MI->isBranch();
753bool HexagonGlobalSchedulerImpl::IsNotDualJumpFirstCandidate(MachineInstr *
MI) {
762bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(MachineInstr *
MI) {
773bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(
777 MachineInstr *
MI = &*TargetPacket;
779 if (
MI->isBundle()) {
781 if (&(*
MI->getParent()->rbegin()) !=
MI)
788 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
790 if (IsNotDualJumpFirstCandidate(&*MII))
793 return IsDualJumpFirstCandidate(
MI);
801bool HexagonGlobalSchedulerImpl::IsDualJumpFirstCandidate(
802 MachineBasicBlock *
MBB) {
808 MII != MBBEnd; ++MII) {
809 MachineInstr *
MI = &*MII;
810 if (
MI->isDebugInstr())
812 if (!
MI->isBundle() && IsNotDualJumpFirstCandidate(
MI))
819bool HexagonGlobalSchedulerImpl::IsDualJumpSecondCandidate(MachineInstr *
MI) {
840 if (!MII->isBundle() && MII->isTerminator())
851bool HexagonGlobalSchedulerImpl::isJumpOutOfRange(MachineInstr *
MI) {
852 if (!
MI || !
MI->isBranch())
854 MachineBasicBlock *
MBB =
MI->getParent();
859 unsigned InstOffset = BlockToInstOffset[
MBB];
860 unsigned Distance = 0;
868 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
879 if (
TBB && (
MI == &*FirstTerm)) {
881 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[
TBB]) +
890 MachineInstr *SecondTerm = &*FTMII;
893 "Bad second terminator");
894 if (
MI != SecondTerm)
898 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[FBB]) +
900 LLVM_DEBUG(
dbgs() <<
"\tSecond term offset(" << Distance <<
"): ";
910bool HexagonGlobalSchedulerImpl::isNewifiable(
912 MachineInstr *TargetPacket) {
913 MachineInstr *
MI = &*MII;
915 !CanNewifiedBeUsedInBundle(MII, DepReg, TargetPacket))
921bool HexagonGlobalSchedulerImpl::DemoteToDotOld(MachineInstr *
MI) {
923 MI->setDesc(QII->get(NewOpcode));
928void HexagonGlobalSchedulerImpl::initPacketizerState(
void) {
929 CurrentPacketMIs.clear();
934bool HexagonGlobalSchedulerImpl::ignoreInstruction(MachineInstr *
MI) {
935 if (
MI->isDebugInstr())
939 if (
MI->isInlineAsm())
944 const MCInstrDesc &TID =
MI->getDesc();
946 const InstrStage *IS =
947 ResourceTracker->getInstrItins()->beginStage(SchedClass);
948 unsigned FuncUnits = IS->
getUnits();
954bool HexagonGlobalSchedulerImpl::isSoloInstruction(
const MachineInstr &
MI) {
955 if (
MI.isInlineAsm())
967 if (
MI.getOpcode() == Hexagon::A2_nop)
974BasicBlockRegion *HexagonGlobalSchedulerImpl::getRegionForMBB(
975 std::vector<BasicBlockRegion *> &Regions, MachineBasicBlock *
MBB) {
976 for (std::vector<BasicBlockRegion *>::iterator
I = Regions.begin(),
979 if ((*I)->findMBB(
MBB))
1005HexagonGlobalSchedulerImpl::getNextPURBB(MachineBasicBlock *
MBB,
1006 bool SecondBest =
false) {
1010 BlockFrequency BestBlockFreq = BlockFrequency(0);
1011 unsigned BestBlockSize = 0;
1012 MachineBasicBlock *BestBB = NULL;
1013 MachineBasicBlock *SecondBestBB = NULL;
1024 LLVM_DEBUG(
dbgs() <<
"\tsucc BB(" << Succ->getNumber() <<
") freq("
1027 if (!SecondBest && getRegionForMBB(PullUpRegions, Succ))
1032 if (Succ->pred_size() > 1)
1037 if (Succ->isEHPad() || Succ->hasAddressTaken())
1047 BestBlockFreq = EdgeFreq;
1049 SecondBestBB = BestBB;
1051 }
else if (!SecondBestBB) {
1052 SecondBestBB = Succ;
1056 return SecondBestBB;
1062bool HexagonGlobalSchedulerImpl::formPullUpRegions(MachineFunction &Fn) {
1065 if (std::next(
F.begin()) ==
F.end())
1070 unsigned InstOffset = 0;
1072 LLVM_DEBUG(
dbgs() <<
"****** Form PullUpRegions **************\n");
1082 InstOffset = (InstOffset + ByteAlign) & ~(ByteAlign);
1085 BlockToInstOffset[&*
MBB] = InstOffset;
1089 if (!MII->isBundle())
1090 InstOffset += QII->
getSize(*MII);
1093 if (getRegionForMBB(PullUpRegions, &*
MBB))
1102 BasicBlockRegion *PUR =
new BasicBlockRegion(
TII, QRI, &*
MBB);
1103 PullUpRegions.push_back(PUR);
1105 for (MachineBasicBlock *MBBR = getNextPURBB(&*
MBB); MBBR;
1106 MBBR = getNextPURBB(MBBR)) {
1108 << MBBR->getName() <<
") size("
1111 << MBBR->getParent()->getFunction().getName() <<
")\n");
1121 if (
MI->hasUnmodeledSideEffects() ||
MI->hasOrderedMemoryRef() ||
1123 (
MI->getOpcode() == Hexagon::J2_jump && !
MI->getOperand(0).isMBB()))
1131 if (!
MI ||
MI->memoperands_empty())
1137 if ((*
MI->memoperands_begin())->isVolatile() ||
MI->hasUnmodeledSideEffects())
1140 if (!(*
MI->memoperands_begin())->getValue())
1153 if (
TII->areMemAccessesTriviallyDisjoint(*MIa, *MIb))
1179 assert((MMOa->
getOffset() >= 0) &&
"Negative MachineMemOperand offset");
1180 assert((MMOb->
getOffset() >= 0) &&
"Negative MachineMemOperand offset");
1182 "Size 0 memory access");
1190 return !(MMOb->
getSize().getValue() <= offDiff);
1193 return !(MMOa->
getSize().getValue() <= offDiff);
1219 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1232 for (
unsigned R = 1, NR = Hexagon::NUM_TARGET_REGS; R != NR; ++R)
1239void HexagonGlobalSchedulerImpl::MIUseDefSet(MachineInstr *
MI,
1240 std::vector<unsigned> &Defs,
1241 std::vector<unsigned> &
Uses) {
1244 assert(!
MI->isBundle() &&
"Cannot parse regs of a bundle.");
1245 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1246 const MachineOperand &MO =
MI->getOperand(i);
1252 assert(Register::isPhysicalRegister(
Reg));
1253 std::vector<unsigned> &Refs = MO.
isUse() ?
Uses : Defs;
1254 for (MCRegAliasIterator AI(MO.
getReg(), QRI,
true); AI.isValid(); ++AI)
1255 Refs.push_back(*AI);
1257 for (
unsigned R = 1, NR = Hexagon::NUM_TARGET_REGS;
R != NR; ++
R)
1294bool HexagonGlobalSchedulerImpl::canAddMIToThisPacket(
1304 isJumpOutOfRange(
MI)) &&
1305 !tryAllocateResourcesForConstExt(
MI,
false))
1309 if (!ResourceTracker->canReserveResources(*
MI) || !shouldAddToPacket(*
MI)) {
1314 SmallVector<unsigned, 4> BundleDefs;
1315 SmallVector<unsigned, 8> BundleUses;
1316 SmallVector<unsigned, 4> Defs;
1317 SmallVector<unsigned, 8>
Uses;
1318 MachineInstr *FirstCompound = NULL, *SecondCompound = NULL;
1319 MachineInstr *FirstDuplex = NULL, *SecondDuplex = NULL;
1322 for (SmallVector<MachineInstr *, HEXAGON_PACKET_SIZE>::iterator
1323 BI = Bundle.
begin(),
1330 MachineInstr *Inst1 = *BI;
1331 MachineInstr *Inst2 =
MI;
1344 FirstCompound = *BI;
1346 SecondCompound = *BI;
1347 if (isCompoundPair(FirstCompound, SecondCompound)) {
1348 if (
MI->mayLoad() ||
MI->mayStore()) {
1362 if (
MI->mayLoad() ||
MI->mayStore()) {
1370 for (
unsigned i = 0; i < Defs.
size(); i++) {
1372 for (
unsigned j = 0;
j < BundleDefs.
size();
j++)
1377 if (AliasingRegs(Defs[i], BundleDefs[j]) &&
1379 !(IsDualJumpFirstCandidate(*BI) && IsDualJumpSecondCandidate(
MI))) {
1381 dbgs() <<
"\t"; (*BI)->dump());
1397 for (
unsigned j = 0;
j < BundleUses.
size();
j++)
1398 if (AliasingRegs(Defs[i], BundleUses[j])) {
1399 for (
unsigned k = 0;
k < BundleDefs.
size();
k++)
1400 for (
unsigned l = 0;
l <
Uses.size();
l++) {
1401 if (AliasingRegs(BundleDefs[k],
Uses[l]) &&
1404 dbgs() <<
"\t"; (*BI)->dump());
1411 for (
unsigned i = 0; i <
Uses.size(); i++) {
1413 for (
unsigned j = 0;
j < BundleDefs.
size();
j++)
1414 if (AliasingRegs(
Uses[i], BundleDefs[j]) &&
1430 if ((*BI)->isCall()) {
1432 for (
unsigned i = 0; i < Defs.
size(); i++) {
1433 if (AliasingRegs(Defs[i], *
I)) {
1448 if ((*BI)->isBarrier()) {
1481 (
MI->mayStore() ||
MI->getOpcode() == Hexagon::S2_allocframe ||
1504 if ((QII->
isMemOp(**BI) &&
MI->mayStore()) ||
1505 (QII->
isMemOp(*
MI) && (*BI)->mayStore())) {
1507 dbgs() <<
"\tSlot 0 not available for store because of memop.\n");
1512 if ((
MI->mayLoad() && (*BI)->mayStore()) ||
1513 (
MI->mayStore() && (*BI)->mayLoad()) ||
1514 (
MI->mayStore() && (*BI)->mayStore())) {
1517 dbgs() <<
"\t"; (*BI)->dump());
1523 std::map<MachineInstr *, MachineBasicBlock *>::iterator MIMoved;
1524 MIMoved = SpeculatedIns.find(*BI);
1525 if ((MIMoved != SpeculatedIns.end()) &&
1526 (MIMoved->second != (*BI)->getParent())) {
1528 dbgs() <<
"This packet already contains a speculated instruction";
1544bool HexagonGlobalSchedulerImpl::ReorderDependencyTest(MachineInstr *MIa,
1545 MachineInstr *MIb) {
1546 SmallVector<unsigned, 4> DefsA;
1547 SmallVector<unsigned, 4> DefsB;
1548 SmallVector<unsigned, 8> UsesA;
1549 SmallVector<unsigned, 8> UsesB;
1554 for (SmallVector<unsigned, 4>::iterator IDA = DefsA.
begin(),
1556 IDA != IDAE; ++IDA) {
1557 for (SmallVector<unsigned, 8>::iterator IUB = UsesB.
begin(),
1561 if (AliasingRegs(*IDA, *IUB))
1564 for (SmallVector<unsigned, 4>::iterator IDB = DefsB.
begin(),
1568 if (AliasingRegs(*IDA, *IDB))
1572 for (SmallVector<unsigned, 4>::iterator IDB = DefsB.
begin(),
1574 IDB != IDBE; ++IDB) {
1575 for (SmallVector<unsigned, 8>::iterator IUA = UsesA.
begin(),
1579 if (AliasingRegs(*IDB, *IUA))
1590 for (
unsigned i = 0; i < DefsB.
size(); i++) {
1591 if (AliasingRegs(DefsB[i], *
I))
1598 for (
unsigned i = 0; i < DefsA.
size(); i++) {
1599 if (AliasingRegs(DefsA[i], *
I))
1621bool HexagonGlobalSchedulerImpl::MIsAreDependent(MachineInstr *MIa,
1622 MachineInstr *MIb) {
1626 if (ReorderDependencyTest(MIa, MIb)) {
1635bool HexagonGlobalSchedulerImpl::MIsHaveTrueDependency(MachineInstr *MIa,
1636 MachineInstr *MIb) {
1640 SmallVector<unsigned, 4> DefsA;
1641 SmallVector<unsigned, 4> DefsB;
1642 SmallVector<unsigned, 8> UsesA;
1643 SmallVector<unsigned, 8> UsesB;
1648 for (SmallVector<unsigned, 4>::iterator IDA = DefsA.
begin(),
1650 IDA != IDAE; ++IDA) {
1651 for (SmallVector<unsigned, 8>::iterator IUB = UsesB.
begin(),
1655 if (AliasingRegs(*IDA, *IUB))
1663bool HexagonGlobalSchedulerImpl::canReorderMIs(MachineInstr *MIa,
1664 MachineInstr *MIb) {
1672 for (++MII; MII != MIIE && MII->isInsideBundle(); ++MII) {
1673 if (MII->isDebugInstr())
1675 if (MIsAreDependent(&*MII, MIb))
1680 return !MIsAreDependent(MIa, MIb);
1690 if (
MI->isBranch() ||
MI->isReturn() ||
MI->isCall() ||
MI->isBarrier() ||
1698bool HexagonGlobalSchedulerImpl::MIisDualJumpCandidate(
1704 MachineBasicBlock *FromThisBB =
MI->getParent();
1705 MachineBasicBlock *ToThisBB = WorkPoint->getParent();
1708 << ToThisBB->
getNumber() <<
") From BB("
1712 if (FromThisBB == ToThisBB)
1718 if ((*(FromThisBB->
pred_begin()) != ToThisBB) ||
1729 MachineBasicBlock *ToTBB = NULL, *ToFBB = NULL;
1735 if (!QII->
analyzeBranch(*ToThisBB, ToTBB, ToFBB, ToCond,
false)) {
1739 if (ToFBB)
dbgs() << ToFBB->getNumber() <<
").\n";
1740 else dbgs() <<
"None"
1742 if (ToTBB == FromThisBB) {
1746 }
else if (ToFBB == FromThisBB || !ToFBB) {
1755 }
else if (ToThisBB->
succ_size() == 1) {
1757 assert(ToFBB == FromThisBB &&
"Bad CFG layout");
1763 return IsDualJumpFirstCandidate(WorkPoint);
1770bool HexagonGlobalSchedulerImpl::canCauseStall(MachineInstr *
MI,
1772 SmallVector<unsigned, 4> DefsMJI;
1773 SmallVector<unsigned, 8> UsesMJI;
1774 SmallVector<unsigned, 4> DefsMI;
1775 SmallVector<unsigned, 8> UsesMI;
1778 for (
auto Use : UsesMI) {
1779 int UseIdx =
MI->findRegisterUseOperandIdx(Use,
nullptr);
1782 bool ShouldBreak =
false;
1783 int BundleCount = 0;
1787 MJI != Begin; --MJI) {
1788 if (MJI->isBundle()) {
1793 for (
auto Def : DefsMJI) {
1794 if (Def == Use || AliasingRegs(Def, Use)) {
1795 int DefIdx = MJI->findRegisterDefOperandIdx(Def,
nullptr);
1811 if (!MJI->isBundled() && !MJI->isDebugInstr())
1822bool HexagonGlobalSchedulerImpl::canThisMIBeMoved(
1824 bool &MovingDependentOp,
int &
Cost) {
1828 MovingDependentOp =
false;
1841 for (--MII; MII->isBundled(); --MII)
1842 if (MII->isBundle())
1846 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1850 if (isCompoundPair(&*MII,
MI)) {
1863 for (--MII; MII->isBundled(); --MII)
1864 if (MII->isBundle())
1868 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1883 if (MIisDualJumpCandidate(
MI, WorkPoint)) {
1888 MovingDependentOp =
true;
1898 unsigned dist_looplabel =
1899 BlockToInstOffset.
find(
MI->getOperand(0).getMBB())->second;
1900 unsigned dist_newloop0 =
1901 BlockToInstOffset.
find(WorkPoint->getParent())->second;
1904 (unsigned)std::abs((
long long)dist_looplabel - dist_newloop0) +
1906 const HexagonInstrInfo *HII = (
const HexagonInstrInfo *)
TII;
1909 << Distance <<
" outside branch range.";);
1912 LLVM_DEBUG(
dbgs() <<
"\nloopN can be moved since Distance: " << Distance
1913 <<
" within branch range.";);
1918 std::map<MachineInstr *, std::vector<unsigned>>::const_iterator DefIter =
1920 MachineBasicBlock *
MBB =
MI->getParent();
1921 for (
unsigned i = 0; DefIter != MIDefSet.end() && i < DefIter->second.size();
1928 if (
MI->isBundled()) {
1937 for (--MII; MII->isBundled(); --MII)
1938 if (MII->isBundle())
1942 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
1944 if (MII->isDebugInstr())
1946 if (MIsAreDependent(&*MII,
MI)) {
1955 IsDualJumpSecondCandidate(&*MII) ||
MI->isBranch()) {
1957 MovingDependentOp =
true;
1961 LLVM_DEBUG(
dbgs() <<
"\t\tDependent, and do not allow for now.\n");
1972bool HexagonGlobalSchedulerImpl::doesMIDefinesPredicate(
1973 MachineInstr *
MI, SmallVector<unsigned, 4> &Defs) {
1974 bool defsPredicate =
false;
1977 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
1978 const MachineOperand &MO =
MI->getOperand(i);
1988 assert(Register::isPhysicalRegister(
Reg));
1991 const TargetRegisterClass *RC = QRI->getMinimalPhysRegClass(
Reg);
1992 if (RC == &Hexagon::PredRegsRegClass) {
1993 defsPredicate =
true;
1998 return defsPredicate;
2006bool HexagonGlobalSchedulerImpl::NeedToNewify(
2008 MachineInstr *TargetPacket = NULL) {
2010 SmallVector<unsigned, 4> DefsA;
2011 SmallVector<unsigned, 4> DefsB;
2012 SmallVector<unsigned, 8> UsesB;
2023 if (TargetPacket && !TargetPacket->
isBundled()) {
2024 if (doesMIDefinesPredicate(TargetPacket, DefsA)) {
2025 for (SmallVector<unsigned, 4>::iterator IA = DefsA.
begin(),
2028 for (SmallVector<unsigned, 8>::iterator IB = UsesB.
begin(),
2040 for (--MII; MII->isBundled(); --MII)
2041 if (MII->isBundle())
2052 for (++MII; MII != BBEnd && MII->isBundled() && !MII->isBundle(); ++MII) {
2055 if (doesMIDefinesPredicate(&*MII, DefsA)) {
2056 for (SmallVector<unsigned, 4>::iterator IA = DefsA.
begin(),
2059 for (SmallVector<unsigned, 8>::iterator IB = UsesB.
begin(),
2079bool HexagonGlobalSchedulerImpl::CanNewifiedBeUsedInBundle(
2081 MachineInstr *TargetPacket) {
2083 if (!TargetPacket || !TargetPacket->
isBundled())
2087 for (--MII; MII->isBundled(); --MII)
2088 if (MII->isBundle())
2092 for (++MII; MII != BBEnd && MII->isBundled() && !MII->isBundle(); ++MII) {
2097 SmallVector<unsigned, 4> DefsA;
2098 if (!doesMIDefinesPredicate(&*MII, DefsA))
2100 for (
auto &IA : DefsA)
2109void HexagonGlobalSchedulerImpl::setUsedRegs(BitVector &Set,
unsigned Reg) {
2111 for (MCSubRegIterator SubRegs(
Reg, QRI); SubRegs.isValid(); ++SubRegs)
2112 Set.reset(*SubRegs);
2116bool HexagonGlobalSchedulerImpl::AliasingRegs(
unsigned RegA,
unsigned RegB) {
2120 for (MCSubRegIterator SubRegs(RegA, QRI); SubRegs.isValid(); ++SubRegs)
2121 if (RegB == *SubRegs)
2124 for (MCSubRegIterator SubRegs(RegB, QRI); SubRegs.isValid(); ++SubRegs)
2125 if (RegA == *SubRegs)
2133 if (
MI->isDebugInstr())
2136 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2149 if (
MI->isDebugInstr())
2152 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2165void HexagonGlobalSchedulerImpl::updateKillAlongThePath(
2166 MachineBasicBlock *HomeBB, MachineBasicBlock *OriginBB,
2171 std::vector<MachineInstr *> &backtrack) {
2173 MachineInstr *
MI = &*Head;
2174 MachineBasicBlock *CurrentBB = OriginBB;
2175 SmallSet<unsigned, 8> KilledUseSet;
2177 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2178 const MachineOperand &MO =
MI->getOperand(i);
2190 if (KilledUseSet.
empty())
2200 <<
")kills. From BB (" << OriginBB->
getNumber() <<
")\n");
2202 assert(!backtrack.empty() &&
"Empty back track");
2208 for (
signed i = backtrack.size() - 1; i >= 0; --i) {
2210 << backtrack[i]->
getParent()->getNumber() <<
")\t";
2211 backtrack[i]->dump());
2212 if (CurrentBB != backtrack[i]->
getParent()) {
2214 <<
") to(" << backtrack[i]->getParent()->getNumber()
2220 if (*SI == CurrentBB)
2227 E = (*SI)->livein_end();
2229 if (KilledUseSet.
count((*I).PhysReg)) {
2231 <<
") is LiveIn along side exit.\n");
2232 KilledUseSet.
erase((*I).PhysReg);
2235 if (KilledUseSet.
empty())
2239 CurrentBB = backtrack[i]->getParent();
2243 if (backtrack[i] == &*TargetPacket)
2249 if (backtrack[i] == &*SourcePacket)
2253 if (backtrack[i]->isDebugInstr())
2259 SmallVector<unsigned, 4> Defs;
2260 SmallVector<unsigned, 8>
Uses;
2261 MachineInstr *MIU = backtrack[i];
2264 for (SmallVector<unsigned, 8>::iterator IA =
Uses.begin(), IAE =
Uses.end();
2266 if (KilledUseSet.
count(*IA)) {
2278 for (++MII; MII != End && MII->isInsideBundle(); ++MII)
2283 KilledUseSet.
erase(*IA);
2286 if (KilledUseSet.
empty())
2294void HexagonGlobalSchedulerImpl::addInstructionToExistingBundle(
2300 std::vector<MachineInstr *> &backtrack) {
2307 if (Outcast->isBundle() && Outcast->isBundledWithSucc())
2308 Outcast->unbundleFromSucc();
2315 if (memShufDisabled)
2323 for (
unsigned i = 0; i < backtrack.size(); ++i)
2324 if (backtrack[i] == &*Outcast)
2325 backtrack[i] = &*Head;
2328 if (NextMI == Outcast)
2331 TargetPacket = Head;
2332 HomeBB->
erase(Outcast);
2337void HexagonGlobalSchedulerImpl::removeInstructionFromExistingBundle(
2342 std::vector<MachineInstr *> &backtrack) {
2344 if (HomeBB->
empty()) {
2350 if (!SourceLocation->isBundle()) {
2351 LLVM_DEBUG(
dbgs() <<
"\t\t\tOriginal instruction was not bundled.\n\t\t\t";
2352 SourceLocation->dump());
2357 for (
unsigned i = 0; i < backtrack.size(); ++i) {
2358 if (backtrack[i] == &*SourceLocation) {
2360 assert((backtrack[i] == backtrack.back()) &&
"Lost back track");
2361 backtrack.pop_back();
2364 if (NextMI == SourceLocation)
2375 LLVM_DEBUG(
dbgs() <<
"\t\t\t[Rem] SourceLocation after bundle update: ";
2381 if (!SourceLocation->isBundledWithSucc()) {
2382 assert(!Head->isBundledWithSucc() && !Head->isBundledWithPred() &&
2388 unsigned BBSizeWithDbg = 0;
2392 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I) {
2394 if (!
I->isDebugInstr())
2405 if (Outcast->isBundle() && Outcast->isBundledWithSucc())
2406 Outcast->unbundleFromSucc();
2419 if (memShufDisabled)
2423 }
else if (
Size == 1) {
2425 if (BBSizeWithDbg > 1) {
2429 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I) {
2430 I->unbundleFromPred();
2432 if (!
I->isDebugInstr())
2440 if (Head->isBundledWithPred())
2441 Head->unbundleFromPred();
2442 if (Head->isBundledWithSucc())
2443 Head->unbundleFromSucc();
2450 SourceLocation = Head;
2454 for (
unsigned i = 0; i < backtrack.size(); ++i)
2455 if (backtrack[i] == &*Outcast)
2456 backtrack[i] = &*Head;
2459 if (NextMI == Outcast)
2462 HomeBB->
erase(Outcast);
2470 SE =
MBB->succ_end();
2472 LLVM_DEBUG(
dbgs() <<
"\tSuccessor BB (" << (*SI)->getNumber() <<
"):");
2474 E = (*SI)->livein_end();
2489 if (!
MBBI->isDebugInstr())
2499 if (!
MI || !
MI->isBranch() ||
MI->isBundle())
2502 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
2512bool HexagonGlobalSchedulerImpl::AnalyzeBBBranches(MachineBasicBlock *
MBB,
2513 MachineBasicBlock *&
TBB,
2514 MachineInstr *&FirstTerm,
2515 MachineBasicBlock *&FBB,
2516 MachineInstr *&SecondTerm) {
2539 if (MII->isBranch())
2543 while (MII != MIE) {
2544 if (!MII->isBundle() && MII->isBranch()) {
2555 LLVM_DEBUG(
dbgs() <<
"\n\t\tCannot analyze BB with indirect branch.");
2558 if ((FirstTerm && FirstTerm->
getOpcode() == Hexagon::J2_jump &&
2560 (SecondTerm && SecondTerm->
getOpcode() == Hexagon::J2_jump &&
2563 dbgs() <<
"\n\t\tCannot analyze BB with a branch out of function.");
2570 LLVM_DEBUG(
dbgs() <<
"\t\tFail to analyze with analyzeBranch.\n");
2572 else dbgs() <<
"None\n";);
2589 if (FirstTerm && SecondTerm &&
2598 }
else if (SecondTerm && SecondTerm->
getOpcode() == Hexagon::J2_jump &&
2611 <<
") FBB(" << FBB->
getNumber() <<
").\n");
2626 assert(MBBIter != MF.
end() &&
"I give up.");
2633 else if (FBB ==
S1) {
2639 MBBIter = MF.
begin();
2642 assert(MBBIter != MF.
end() &&
"Malformed BB with invalid successors");
2650 <<
") FBB(" << FBB->
getNumber() <<
").\n");
2654 assert(!FirstTerm &&
"Bad BB");
2658 if (!FBB && SecondTerm) {
2674 LLVM_DEBUG(
dbgs() <<
"Possibly the layout successor is an empty BB");
2678 LLVM_DEBUG(
dbgs() <<
"Malformed branch with useless branch condition";);
2681 }
else if (
TBB && !FBB) {
2697 else dbgs() <<
"\t\tFinal FBB(None)\n";);
2742 if (!Pred->isSuccessor(&
MBB))
2744 Pred->ReplaceUsesOfBlockWith(&
MBB, MFBB);
2755 bool RemoveLSIfPresent =
false;
2757 LLVM_DEBUG(
dbgs() <<
"\nNew firstterm conditional jump added to HomeBB";);
2761 LLVM_DEBUG(
dbgs() <<
"\nNew secondterm conditional jump added to HomeBB";);
2765 LLVM_DEBUG(
dbgs() <<
"\nBranch destination for pulled instruction is BB#"
2766 << Dest->getNumber(););
2771 LLVM_DEBUG(
dbgs() <<
"\nNew firstterm unconditional jump added to HomeBB";);
2774 RemoveLSIfPresent =
true;
2777 dbgs() <<
"\nNew secondterm unconditional jump added to HomeBB";);
2780 RemoveLSIfPresent =
true;
2787 if (RemoveLSIfPresent) {
2792 LLVM_DEBUG(
dbgs() <<
"\nRemoving LayoutSucc BB#" << HomeBBLS->getNumber()
2793 <<
"from list of successors";);
2802MachineInstr *HexagonGlobalSchedulerImpl::MoveAndUpdateLiveness(
2803 BasicBlockRegion *CurrentRegion, MachineBasicBlock *HomeBB,
2804 MachineInstr *InstrToMove,
bool NeedToNewify,
unsigned DepReg,
2805 bool MovingDependentOp, MachineBasicBlock *OriginBB,
2810 std::vector<MachineInstr *> &backtrack) {
2812 dbgs() <<
"\n...............[MoveAndUpdateLiveness]..............\n");
2815 OriginalInstruction->
dump());
2829 HomeBB->
erase(kill_it);
2840 std::list<MachineBasicBlock *> WorkList;
2843 for (std::vector<MachineInstr *>::iterator RI = backtrack.begin(),
2844 RIE = backtrack.end();
2846 WorkList.push_back((*RI)->getParent());
2855 TargetHead->getParent()->instr_end();
2856 bool LastInstructionInBundle =
false;
2858 TargetPacket, &*OutcastFrom, LastInstructionInBundle);
2866 MIBundleBuilder Bundle(&*TargetHead);
2876 if (OriginalInstruction->
getIterator() == TargetTail) {
2883 if (OutcastFrom->isBundledWithSucc()) {
2886 }
else if (OutcastFrom->isBundledWithPred()) {
2887 OutcastFrom->unbundleFromPred();
2889 HomeBB->
splice(MII, OriginBB, OutcastFrom);
2890 if (!MII->isBundledWithPred())
2891 MII->bundleWithPred();
2892 if (!LastInstructionInBundle && !MII->isBundledWithSucc())
2893 MII->bundleWithSucc();
2895 if (!MIIToPred->isBundledWithSucc())
2896 MIIToPred->bundleWithSucc();
2914 updateKillAlongThePath(HomeBB, OriginBB, MII, TargetTail, SourceLocation,
2915 TargetPacket, backtrack);
2924 DemoteToDotOld(&*MII);
2934 if (!
Cond.empty()) {
2939 assert((DepReg < std::numeric_limits<unsigned>::max()) &&
2940 "Invalid pred reg value");
2942 <<
printReg(DepReg, QRI) <<
").\n");
2944 MII->setDesc(QII->get(NewOpcode));
2949 for (
unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
2950 MachineOperand &MO = MII->getOperand(i);
2955 if (DepReg == MO.
getReg())
2959 LLVM_DEBUG(
dbgs() <<
"\t\t\tNew predicated form:\t"; MII->dump());
2962 updateKillAlongThePath(HomeBB, OriginBB, MII, TargetTail, SourceLocation,
2963 TargetPacket, backtrack);
2967 addInstructionToExistingBundle(HomeBB, TargetHead, TargetTail, MII,
2968 TargetPacket, NextMI, backtrack);
2971 removeInstructionFromExistingBundle(OriginBB, ++OriginalHead, OriginalTail,
2972 SourceLocation, NextMI, MovingDependentOp,
2985 QII->
isEndLoopN(OriginalHead->getOpcode())) {
2991 if (OriginBB->
begin() !=
I) {
2993 if (
I->isBundled()) {
2994 if (!
I->isBundledWithSucc())
2995 I->bundleWithSucc();
2996 if (!OriginalHead->isBundledWithPred())
2997 OriginalHead->bundleWithPred();
3002 }
else if (MovingDependentOp &&
3004 if (OriginalHead->isBundled()) {
3006 J != OriginalTail && J->isInsideBundle() && !J->isBundle(); ++J) {
3008 if (MIsHaveTrueDependency(OriginalInstruction, &*J) &&
3011 DemoteToDotOld(&*J);
3016 if (MIsHaveTrueDependency(OriginalInstruction, &*OriginalHead) &&
3019 OriginalHead->dump());
3020 DemoteToDotOld(&*OriginalHead);
3033 for (std::list<MachineBasicBlock *>::iterator BBI = WorkList.begin(),
3034 BBIE = WorkList.end();
3035 BBI != BBIE; BBI++) {
3041 MachineBasicBlock *BB = WorkList.back();
3042 WorkList.pop_back();
3044 }
while (!WorkList.empty());
3047 if (OriginBB == HomeBB)
3048 return &*TargetHead;
3051 MachineBasicBlock *HomeTBB, *HomeFBB;
3052 MachineInstr *FTA = NULL, *STA = NULL;
3053 bool HomeBBAnalyzed = !AnalyzeBBBranches(HomeBB, HomeTBB, FTA, HomeFBB, STA);
3054 if (MII->isBranch()) {
3055 if (HomeBBAnalyzed) {
3056 UpdateCFG(HomeBB, OriginBB, &*MII, HomeTBB, HomeFBB, FTA, STA, MBPI);
3071 EmptyBBs.push_back(OriginBB);
3073 return &*TargetHead;
3077 MachineBasicBlock *CommonFBB = *OriginBB->
succ_begin();
3083 assert((OriginBB->
succ_size() == 2) &&
"Underimplemented 3way branch.");
3084 MachineBasicBlock *OriginTBB, *OriginFBB;
3085 MachineInstr *FTB = NULL, *STB = NULL;
3088 if (HomeBBAnalyzed &&
3089 !AnalyzeBBBranches(OriginBB, OriginTBB, FTB, OriginFBB, STB)) {
3090 assert(OriginFBB &&
"Missing Origin FBB");
3091 if (HomeFBB == OriginBB) {
3093 if (HomeTBB == OriginTBB) {
3096 }
else if (HomeTBB == OriginFBB) {
3107 }
else if (HomeTBB == OriginBB) {
3109 if (HomeFBB == OriginTBB) {
3112 }
else if (HomeFBB == OriginFBB) {
3134 return &*TargetHead;
3140HexagonGlobalSchedulerImpl::findInsertPositionInBundle(
3149 assert(MII->isBundle() &&
"Missing insert location");
3150 bool isDualJumpSecondCandidate = IsDualJumpSecondCandidate(
MI);
3151 LastInBundle =
false;
3153 for (++MII; MII != BBEnd && MII->isInsideBundle() && !MII->isBundle();
3155 if (MII->isBranch() && (FirstBranch == BBEnd))
3159 if (isDualJumpSecondCandidate && IsDualJumpFirstCandidate(&*MII))
3160 DualJumpFirstCandidate = MII;
3161 LastBundledInstruction = MII;
3164 if (DualJumpFirstCandidate != BBEnd) {
3166 ++DualJumpFirstCandidate;
3167 if (DualJumpFirstCandidate == BBEnd ||
3168 DualJumpFirstCandidate == LastBundledInstruction)
3169 LastInBundle =
true;
3170 return DualJumpFirstCandidate;
3171 }
else if (FirstBranch != BBEnd) {
3176 }
else if (LastBundledInstruction != BBEnd) {
3177 LastInBundle =
true;
3178 return ++LastBundledInstruction;
3189 MachineInstr *
MI,
bool DeleteOldCopy) {
3191 MachineBasicBlock *CurrentBB =
MI->getParent();
3193 assert(CurrentBB &&
"Corrupt instruction");
3200 MachineInstr *NewMI =
MI->getParent()->getParent()->CloneMachineInstr(
MI);
3207 if (DeleteOldCopy) {
3212 CurrentBB->
erase(kill_it);
3219 DemoteToDotOld(NewMI);
3224 if (TargetPacket->getParent() ==
MBB) {
3227 if (MII->isBundled()) {
3228 bool LastInBundle =
false;
3230 findInsertPositionInBundle(TargetPacket, NewMI, LastInBundle);
3231 MIBundleBuilder Bundle(&*TargetPacket);
3232 Bundle.insert(InsertBefore, NewMI);
3239 while (MII->isDebugInstr())
3242 if (MII->isBundled()) {
3243 MIBundleBuilder Bundle(&*MII);
3244 Bundle.insert(++MII, NewMI);
3252bool HexagonGlobalSchedulerImpl::MIsCondAssign(MachineInstr *BMI,
3254 SmallVector<unsigned, 4> &Defs) {
3258 SmallVector<unsigned, 4> CondDefs;
3259 SmallVector<unsigned, 8> CondUses;
3262 for (SmallVector<unsigned, 4>::iterator
ID = Defs.
begin(), IDE = Defs.
end();
3264 for (SmallVector<unsigned, 4>::iterator CID = CondDefs.
begin(),
3265 CIDE = CondDefs.
end();
3266 CID != CIDE; ++CID) {
3267 if (AliasingRegs(*CID, *
ID)) {
3281template <
typename ElemType,
typename IndexType>
3283 std::map<ElemType, std::vector<IndexType>> &Set1,
3284 std::map<ElemType, std::vector<IndexType>> &Set2,
3285 std::pair<std::vector<IndexType>, std::vector<IndexType>> &UnionSet,
3286 unsigned union_size = 100) {
3288 typename std::map<ElemType, std::vector<IndexType>>
::iterator PosIter_t;
3289 typedef typename std::vector<IndexType>::iterator IndexIter_t;
3290 std::vector<IndexType> &Union1 = UnionSet.first;
3291 std::vector<IndexType> &Union2 = UnionSet.second;
3292 Union1.resize(union_size, 0);
3293 Union2.resize(union_size, 0);
3295 typename std::vector<ElemType>::iterator iter =
Range.begin();
3296 while (iter !=
Range.end()) {
3297 if ((*iter)->isDebugInstr()) {
3302 PosIter_t set1_pos = Set1.find(*iter);
3303 assert(set1_pos != Set1.end() &&
3304 "Set1 should contain an entry for each element in Range.");
3305 IndexIter_t set1idx = set1_pos->second.begin();
3306 while (set1idx != set1_pos->second.end()) {
3307 Union1[*set1idx] = 1;
3310 PosIter_t set2_pos = Set2.find(*iter);
3311 assert(set2_pos != Set2.end() &&
3312 "Set2 should contain an entry for each element in Range.");
3313 IndexIter_t set2idx = set2_pos->second.begin();
3314 while (set2idx != set2_pos->second.end()) {
3315 Union2[*set2idx] = 1;
3332 MI->unbundleFromPred();
3341bool HexagonGlobalSchedulerImpl::canMIBeSpeculated(
3342 MachineInstr *
MI, MachineBasicBlock *ToBB, MachineBasicBlock *FromBB,
3343 std::vector<MachineInstr *> &backtrack) {
3366 if (!
MI->isDereferenceableInvariantLoad())
3371 SmallVector<unsigned, 4> Defs;
3372 SmallVector<unsigned, 8>
Uses;
3376 for (
unsigned R : Defs)
3389 LLVM_DEBUG(
dbgs() <<
"\tTarget succesor BB to check:\n"; (*SI)->dump());
3392 SIE = (*SI)->succ_end();
3393 SII != SIE; ++SII)(*SII)
3396 E = (*SI)->livein_end();
3398 for (SmallVector<unsigned, 4>::iterator
ID = Defs.begin(),
3401 if (AliasingRegs((*I).PhysReg, *
ID))
3408 E = (*SI)->instr_end();
3410 if (BI->isBundle() || BI->isDebugInstr())
3413 if (MIsCondAssign(&*BI,
MI, Defs))
3421 std::vector<MachineBasicBlock *> PathBB;
3422 for (
unsigned i = 0; i < backtrack.size(); ++i) {
3424 MachineBasicBlock *
MBB = backtrack[i]->getParent();
3425 if ((
MBB != FromBB) &&
3426 (std::find(PathBB.begin(), PathBB.end(),
MBB) == PathBB.end()))
3427 PathBB.push_back(
MBB);
3429 bool WaitingForTargetPacket =
true;
3431 std::vector<MachineInstr *> TraversalRange;
3439 for (
unsigned i = 0; i < PathBB.size(); ++i) {
3440 for (MII = PathBB[i]->instr_begin(); MII != PathBB[i]->instr_end(); ++MII) {
3444 if (backtrack[0] == &*MII)
3445 WaitingForTargetPacket =
false;
3446 if (WaitingForTargetPacket)
3448 if (MII->isBundle())
3455 if (MII->isCall() || MII->isReturn() ||
3456 (MII->getOpcode() == Hexagon::J2_jump && !MII->getOperand(0).isMBB()))
3459 TraversalRange.push_back(&*MII);
3465 std::pair<std::vector<unsigned>, std::vector<unsigned>> RangeDefUse;
3466 Unify(TraversalRange, MIDefSet, MIUseSet, RangeDefUse, QRI->getNumRegs());
3468 for (
unsigned j = 0;
j <
Uses.size(); ++
j)
3469 if (RangeDefUse.first[
Uses[j]]) {
3470 LLVM_DEBUG(
dbgs() <<
"\n\t\tUnresolved dependency along path to HOME for "
3476 for (
unsigned j = 0;
j < Defs.size(); ++
j)
3477 if (RangeDefUse.first[Defs[j]] || RangeDefUse.second[Defs[j]]) {
3478 LLVM_DEBUG(
dbgs() <<
"\n\t\tUnresolved dependency along path to HOME for "
3501bool HexagonGlobalSchedulerImpl::MoveMItoBundle(
3502 BasicBlockRegion *CurrentRegion,
3507 std::vector<MachineInstr *> &backtrack,
bool MovingDependentOp,
3508 bool PathInRegion) {
3509 MachineBasicBlock *HomeBB = TargetPacket->getParent();
3510 MachineBasicBlock *OriginBB = InstrToMove->
getParent();
3511 MachineBasicBlock *CurrentBB = OriginBB;
3512 MachineBasicBlock *CleanupBB = OriginBB;
3513 MachineBasicBlock *PreviousBB = OriginBB;
3514 MachineInstr *OriginalInstructionToMove = &*InstrToMove;
3516 assert(HomeBB &&
"Missing HomeBB");
3517 assert(OriginBB &&
"Missing OriginBB");
3519 LLVM_DEBUG(
dbgs() <<
"\n.........[MoveMItoBundle]..............\n");
3520 LLVM_DEBUG(
dbgs() <<
"\t\tInstrToMove :\t"; InstrToMove->dump());
3527 if (HomeBB == OriginBB) {
3543 for (
unsigned i = 0; i < backtrack.size(); ++i) {
3546 << backtrack[i]->
getParent()->getNumber() <<
")\t";
3547 backtrack[i]->dump());
3551 bool NeedCleanup =
false;
3552 bool NeedToPredicate =
false;
3553 bool MINeedToNewify =
false;
3554 unsigned DepReg = std::numeric_limits<unsigned>::max();
3555 bool isDualJump =
false;
3558 std::vector<MachineInstr *> PullUpPath;
3560 PullUpPath = backtrack;
3562 PullUpPath.push_back(&*TargetPacket);
3563 PullUpPath.push_back(&*InstrToMove);
3569 for (std::vector<MachineInstr *>::reverse_iterator RI = backtrack.rbegin(),
3570 RIE = backtrack.rend();
3574 MachineInstr *MIWH = *RI;
3577 InstrToMove->dump());
3579 CleanupBB->
erase(InstrToMove);
3582 if (canCauseStall(&*InstrToMove, MIWH)) {
3584 CleanupBB->
erase(InstrToMove);
3594 bool isBranchMIWH =
isBranch(MIWH);
3595 if (((&*SourceLocation != MIWH) && isBranchMIWH) ||
3599 PreviousBB = CurrentBB;
3603 MachineBasicBlock *PredTBB = NULL;
3604 MachineBasicBlock *PredFBB = NULL;
3615 if (!canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3618 CleanupBB->
erase(InstrToMove);
3622 SpeculatedIns.insert(
3623 std::make_pair(OriginalInstructionToMove, OriginBB));
3624 LLVM_DEBUG(
dbgs() <<
"\nSpeculatedInsToMove"; InstrToMove->dump());
3632 if (NeedToPredicate) {
3634 <<
"\tUnderimplemented pred for speculative move.\n");
3636 CleanupBB->
erase(InstrToMove);
3640 insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove, NeedCleanup);
3642 NeedToPredicate =
false;
3643 assert(!NeedToPredicate &&
"Need to handle predication for this case");
3644 CleanupBB = CurrentBB;
3648 bool LocalNeedPredication =
true;
3650 if (!isBranchMIWH && !PredTBB) {
3651 LLVM_DEBUG(
dbgs() <<
"\tDo not need predicate for this case.\n");
3652 LocalNeedPredication =
false;
3655 if (IsDualJumpSecondCandidate(&*InstrToMove) &&
3656 IsDualJumpFirstCandidate(TargetPacket)) {
3659 }
else if (LocalNeedPredication && (PredFBB != PreviousBB)) {
3665 if (PreviousBB != PredTBB) {
3670 CleanupBB->
erase(InstrToMove);
3675 <<
")InvertCondition("
3676 << (PreviousBB != PredTBB) <<
")\n");
3681 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3684 NeedToPredicate =
true;
3685 CleanupBB = CurrentBB;
3687 if (PredCond.
empty() &&
3690 InstrToMove->dump());
3697 isJumpOutOfRange(&*InstrToMove)) &&
3698 !tryAllocateResourcesForConstExt(&*InstrToMove,
false)) {
3701 <<
"\tEI Could not be added to the packet.\n");
3702 CleanupBB->
erase(InstrToMove);
3706 if (!ResourceTracker->canReserveResources(*InstrToMove) ||
3707 !shouldAddToPacket(*InstrToMove)) {
3710 CurrentBB->
erase(InstrToMove);
3715 if (NeedToNewify(InstrToMove, &DepReg, &*TargetPacket)) {
3716 if (isNewifiable(InstrToMove, DepReg, &*TargetPacket)) {
3717 MINeedToNewify =
true;
3719 <<
printReg(DepReg, QRI) <<
").\n");
3722 InstrToMove->dump());
3723 CleanupBB->
erase(InstrToMove);
3731 if (!
Cond.empty() && (
Cond.size() == 2)) {
3732 MIUseSet[OriginalInstructionToMove].push_back(
Cond[1].
getReg());
3736 "Update MIUseSet for new-value compare jumps");
3740 InstrToMove->dump());
3741 bool DistantSpeculation =
false;
3742 std::vector<MachineInstr *> NonPredPullUpPath;
3747 while (btidx < backtrack.size()) {
3748 const MachineBasicBlock *btBB = backtrack[btidx]->getParent();
3749 if ((btBB == PreviousBB) || (btBB == CurrentBB))
3750 NonPredPullUpPath.push_back(backtrack[btidx]);
3754 if (PreviousBB != CurrentBB) {
3755 if (*(PreviousBB->
pred_begin()) != CurrentBB) {
3757 DistantSpeculation =
true;
3759 <<
"\n\tMI not in immediate successor of BB#"
3760 << CurrentBB->
getNumber() <<
", MI is in BB#"
3764 "Region with a side entry");
3767 if (DistantSpeculation ||
3768 InstrToMove->mayLoad() || InstrToMove->mayStore() ||
3769 InstrToMove->hasUnmodeledSideEffects() ||
3770 !canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3771 NonPredPullUpPath)) {
3772 CleanupBB->
erase(InstrToMove);
3776 NeedToPredicate =
false;
3777 SpeculatedIns.insert(
3778 std::make_pair(OriginalInstructionToMove, OriginBB));
3780 InstrToMove->dump());
3787 InstrToMove->dump());
3790 InstrToMove->mayLoad() || InstrToMove->mayStore() ||
3791 InstrToMove->hasUnmodeledSideEffects() ||
3792 !canMIBeSpeculated(&*InstrToMove, CurrentBB, PreviousBB,
3795 CleanupBB->
erase(InstrToMove);
3799 SpeculatedIns.insert(
3800 std::make_pair(OriginalInstructionToMove, OriginBB));
3802 InstrToMove->dump());
3805 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3808 CleanupBB = CurrentBB;
3813 <<
"\tCurrentBB:" << CurrentBB->
getNumber()
3814 <<
"\tPreviousBB:" << PreviousBB->
getNumber();
3816 <<
"\tPredFBB:" << PredFBB->
getNumber(););
3820 if (IsDualJumpSecondCandidate(&*InstrToMove)) {
3822 LLVM_DEBUG(
dbgs() <<
"\tUnderimplemented dual jump formation.\n");
3824 CleanupBB->
erase(InstrToMove);
3831 CleanupBB->
erase(InstrToMove);
3834 SpeculatedIns.insert(
3835 std::make_pair(OriginalInstructionToMove, OriginBB));
3837 InstrToMove->dump());
3839 InstrToMove = insertTempCopy(CurrentBB, TargetPacket, &*InstrToMove,
3842 NeedToPredicate =
false;
3843 CleanupBB = CurrentBB;
3851 if (MIWH == backtrack.front()) {
3862 if (!(MovingDependentOp && (MIWH == &*SourceLocation)) &&
3863 !canReorderMIs(MIWH, &*InstrToMove)) {
3865 CleanupBB->
erase(InstrToMove);
3872 isJumpOutOfRange(&*InstrToMove)) {
3873 if (!tryAllocateResourcesForConstExt(&*InstrToMove))
3882 if (MovingDependentOp)
dbgs() <<
"dependent op";
dbgs() <<
": ";
3883 InstrToMove->dump();
dbgs() <<
"To BB:\n"; HomeBB->
dump();
3884 dbgs() <<
"From BB:\n"; OriginBB->
dump());
3888 HexagonNumPullUps++;
3890 HexagonNumDualJumps++;
3896 insertTempCopy(HomeBB, TargetPacket, &*InstrToMove, NeedCleanup);
3904 if (!TargetPacket->isBundle()) {
3907 std::next(InstrToMove));
3914 for (
unsigned i = 0; i < backtrack.size(); ++i)
3915 if (backtrack[i] == &*TargetPacket)
3916 backtrack[i] = &*MII;
3919 if (NextMI == TargetPacket)
3925 MoveAndUpdateLiveness(CurrentRegion, HomeBB, &*InstrToMove, MINeedToNewify,
3926 DepReg, MovingDependentOp, OriginBB,
3927 OriginalInstructionToMove, PredCond, SourceLocation,
3928 TargetPacket, NextMI, backtrack);
3937bool HexagonGlobalSchedulerImpl::isBranchWithinRegion(
3938 BasicBlockRegion *CurrentRegion, MachineInstr *
MI) {
3939 assert(
MI &&
MI->isBranch() &&
"Missing call info");
3941 MachineBasicBlock *
MBB =
MI->getParent();
3943 <<
") Branch instr:\t";
3953 MachineBasicBlock *NextRegionBB;
3954 MachineBasicBlock *
TBB, *FBB;
3955 MachineInstr *FirstTerm = NULL;
3956 MachineInstr *SecondTerm = NULL;
3958 if (AnalyzeBBBranches(
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
3991 else dbgs() <<
"None\n";);
4003 if (!NextRegionBB) {
4012 if (
MI == FirstTerm) {
4014 <<
") NextBB in the region(" << NextRegionBB->
getNumber()
4016 return (
TBB == NextRegionBB);
4018 assert(FBB &&
"Corrupt BB layout");
4022 if ((
MI != SecondTerm)) {
4023 LLVM_DEBUG(
dbgs() <<
"\t\tDual terminator not matching SecondTerm.\n");
4028 <<
") NextBB in the region(" << NextRegionBB->
getNumber()
4030 return (FBB == NextRegionBB);
4037bool HexagonGlobalSchedulerImpl::isJumpOutOfRange(MachineInstr *UnCond,
4038 MachineInstr *
Cond) {
4039 if (!UnCond || !UnCond->
isBranch())
4042 MachineBasicBlock *UnCondBB = UnCond->
getParent();
4049 unsigned InstOffset = BlockToInstOffset[UnCondBB];
4050 unsigned Distance = 0;
4057 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4068 if (
TBB && (
Cond == FirstTerm)) {
4070 (unsigned)std::abs((
long long)InstOffset - BlockToInstOffset[
TBB]) +
4079MachineInstr *HexagonGlobalSchedulerImpl::findBundleAndBranch(
4084 MachineInstr *CondBranch = NULL;
4088 MII != MBBEnd; ++MII) {
4089 MachineInstr *
MI = &*MII;
4090 if (MII->isConditionalBranch()) {
4097 if (!MII->isBundled())
4100 for (--MII; MII->isBundled(); --MII)
4101 if (MII->isBundle()) {
4113bool HexagonGlobalSchedulerImpl::pullUpPeelBBLoop(MachineBasicBlock *PredBB,
4114 MachineBasicBlock *LoopBB) {
4117 if (!LoopBB || !PredBB)
4132 MachineBasicBlock *SuccBB = NULL;
4136 if (*SI != LoopBB) {
4145 MachineInstr *PredCondBranch = NULL;
4146 PredCondBranch = findBundleAndBranch(PredBB, PredBundle);
4147 if (!PredCondBranch)
4149 if (PredBundle == PredBB->
end())
4157 while (FMI->isDebugInstr())
4160 MachineInstr *RegMI = &*FMI;
4164 if (TfrOpcode != Hexagon::A2_tfr && TfrOpcode != Hexagon::A2_tfr)
4173 BasicBlockRegion PUR(BasicBlockRegion(
TII, QRI, PredBB));
4178 if (!ResourcesAvailableInBundle(&PUR, PredBundle))
4181 CurrentState.HomeBundle);
4184 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4192 MachineBasicBlock *LTBB = NULL, *LFBB = NULL;
4202 MachineInstr *InstrToMove =
4203 &*insertTempCopy(PredBB, PredBundle, RegMI,
false);
4204 if (!canAddMIToThisPacket(InstrToMove, PredBundlePkt)) {
4216 unsigned DepReg = 0;
4217 if (NeedToNewify(InstrToMove->
getIterator(), &DepReg, &*PredBundle) &&
4218 !isNewifiable(InstrToMove->
getIterator(), DepReg, &*PredBundle)) {
4229 InstrToMove->
setDesc(QII->get(NewOpcode));
4230 if (!incrementalAddToPacket(*InstrToMove)) {
4237 MachineInstr *LoopCondBranch = NULL;
4238 LoopCondBranch = findBundleAndBranch(LoopBB, LoopBundle);
4239 if (!LoopCondBranch)
4241 if (LoopBundle == LoopBB->
end())
4247 if (!ResourcesAvailableInBundle(&PUR, LoopBundle))
4250 CurrentState.HomeBundle);
4253 MachineInstr *InstrToSink =
4254 &*insertTempCopy(LoopBB, LoopBundle, RegMI,
false);
4255 if (!canAddMIToThisPacket(InstrToSink, LoopBundlePkt)) {
4269 if (NeedToNewify(InstrToSink->
getIterator(), &DepReg, &*LoopBundle) &&
4270 !isNewifiable(InstrToSink->
getIterator(), DepReg, &*LoopBundle)) {
4280 InstrToSink->
setDesc(QII->get(NewOpcode));
4281 if (!incrementalAddToPacket(*InstrToSink)) {
4303bool HexagonGlobalSchedulerImpl::performPullUpCFG(MachineFunction &Fn) {
4306 if (std::next(
F.begin()) ==
F.end())
4313 MachineBasicBlock *PrevBlock = NULL;
4314 MachineBasicBlock *JumpBlock = NULL;
4317 MachineBasicBlock *FallBlock = &*
MBB;
4318 if (PrevBlock && JumpBlock) {
4319 Changed |= pullUpPeelBBLoop(PrevBlock, JumpBlock);
4321 PrevBlock = JumpBlock;
4322 JumpBlock = FallBlock;
4327void HexagonGlobalSchedulerImpl::GenUseDefChain(MachineFunction &Fn) {
4328 std::vector<unsigned> Defs;
4329 std::vector<unsigned>
Uses;
4333 MIter != MBBIter->instr_end(); ++MIter) {
4334 if (MIter->isBundle() || MIter->isDebugInstr())
4337 MIUseDefSet(&*MIter, Defs,
Uses);
4339 for (
unsigned i = 0; i < Defs.size(); ++i)
dbgs()
4342 for (
unsigned i = 0; i <
Uses.size(); ++i)
dbgs()
4344 MIDefSet[&*MIter] = Defs;
4345 MIUseSet[&*MIter] =
Uses;
4361MachineBasicBlock *HexagonGlobalSchedulerImpl::optimizeBranches(
4362 MachineBasicBlock *
MBB, MachineBasicBlock *
TBB, MachineInstr *FirstTerm,
4363 MachineBasicBlock *FBB) {
4375 if (TBBMIb->
getOpcode() == Hexagon::J2_jump &&
4378 if (
TBB == NewTarget)
4383 int64_t InstOffset =
4385 unsigned Distance = (unsigned)std::abs(
4386 InstOffset - BlockToInstOffset.
find(NewTarget)->second);
4389 <<
" out of range.");
4422 if (FBBMIb->
getOpcode() == Hexagon::J2_jump &&
4431 int64_t InstOffset =
4433 unsigned Distance = (unsigned)std::abs(
4434 InstOffset - BlockToInstOffset.
find(NewTarget)->second);
4437 <<
" out of range.");
4456bool HexagonGlobalSchedulerImpl::performExposedOptimizations(
4457 MachineFunction &Fn) {
4463 std::vector<MachineBasicBlock *>::iterator ebb = EmptyBBs.begin();
4464 while (ebb != EmptyBBs.end()) {
4467 <<
") from parent.\n");
4468 (*ebb)->eraseFromParent();
4471 MachineBasicBlock *
TBB = NULL, *FBB = NULL;
4472 MachineInstr *FirstTerm = NULL, *SecondTerm = NULL;
4474 SmallVector<MachineBasicBlock *, 4> Erase;
4476 for (MachineBasicBlock &
MBB : Fn) {
4478 AnalyzeBBBranches(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4485 if (
TBB && FirstTerm &&
4486 removeRedundantBranches(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4491 if (FirstTerm && SecondTerm &&
4492 optimizeDualJumps(&
MBB,
TBB, FirstTerm, FBB, SecondTerm)) {
4497 if (
TBB && FBB && FirstTerm && !SecondTerm) {
4498 MachineBasicBlock *MBBToErase =
4499 optimizeBranches(&
MBB,
TBB, FirstTerm, FBB);
4507 for (MachineBasicBlock *
MBB : Erase)
4515bool HexagonGlobalSchedulerImpl::removeRedundantBranches(
4516 MachineBasicBlock *
MBB, MachineBasicBlock *
TBB, MachineInstr *FirstTerm,
4517 MachineBasicBlock *FBB, MachineInstr *SecondTerm) {
4518 bool Analyzed =
false;
4520 MachineInstr *Head = NULL, *ToErase = NULL;
4521 if (!FBB && (FirstTerm->
getOpcode() == Hexagon::J2_jump) &&
4525 dbgs() <<
"\nRemoving Uncond. jump to the layout successor in BB#"
4527 ToErase = FirstTerm;
4528 }
else if (SecondTerm && (
TBB == FBB) &&
4529 (SecondTerm->
getOpcode() == Hexagon::J2_jump)) {
4538 if (++FirstTermIter == SecondTermIter) {
4539 LLVM_DEBUG(
dbgs() <<
"\nRemoving multiple branching to same target in BB#"
4543 ToErase = FirstTerm;
4545 }
else if (SecondTerm && (SecondTerm->
getOpcode() == Hexagon::J2_jump) &&
4551 ToErase = SecondTerm;
4558 LLVM_DEBUG(
dbgs() <<
"\nRemoving Cond. jump to the layout successor in BB#"
4560 ToErase = SecondTerm;
4564 if (ToErase->isBundled()) {
4566 ToErase->eraseFromBundle();
4569 ToErase->eraseFromParent();
4583bool HexagonGlobalSchedulerImpl::optimizeDualJumps(MachineBasicBlock *
MBB,
4584 MachineBasicBlock *
TBB,
4585 MachineInstr *FirstTerm,
4586 MachineBasicBlock *FBB,
4587 MachineInstr *SecondTerm) {
4590 bool Analyzed =
false;
4593 (SecondTerm->
getOpcode() == Hexagon::J2_jump)) {
4605 MachineInstr *
SI = &*SII;
4606 std::map<MachineInstr *, MachineBasicBlock *>::iterator MIMoved;
4607 MIMoved = SpeculatedIns.find(SI);
4608 if ((MIMoved != SpeculatedIns.end()) &&
4609 (MIMoved->second !=
SI->getParent())) {
4622 int64_t InstOffset =
4625 (unsigned)std::abs(InstOffset - BlockToInstOffset.
find(FBB)->second) +
4629 <<
" out of range.");
4643 MachineInstr *SecondHead, *FirstHead;
4654 else if (!FirstHead) {
4658 }
else if (FirstHead == SecondHead) {
4660 assert((FirstHead && SecondHead) &&
"Unbundled Instruction");
4662 if (SecondHead->getBundleSize() < 2)
4676bool HexagonGlobalSchedulerImpl::ResourcesAvailableInBundle(
4677 BasicBlockRegion *CurrentRegion,
4682 if (!TargetPacket->isBundle()) {
4683 if (ignoreInstruction(&*MII) || isSoloInstruction(*MII))
4688 if (MII->isBranch() && !isBranchWithinRegion(CurrentRegion, &*MII))
4694 initPacketizerState();
4695 ResourceTracker->clearResources();
4696 CurrentState.addHomeLocation(MII);
4697 return incrementalAddToPacket(*MII);
4703 initPacketizerState();
4704 ResourceTracker->clearResources();
4705 CurrentState.addHomeLocation(MII);
4707 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
4708 if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
4709 MII->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
4710 MII->getOpcode() == TargetOpcode::CFI_INSTRUCTION || MII->isEHLabel())
4723 if (MII->isBranch() && !isBranchWithinRegion(CurrentRegion, &*MII))
4726 if (!incrementalAddToPacket(*MII))
4729 return ResourceTracker->canReserveResources(*Nop);
4733bool HexagonGlobalSchedulerImpl::isCompoundPair(MachineInstr *MIa,
4734 MachineInstr *MIb) {
4741 (Opcb == Hexagon::A2_tfr || Opcb == Hexagon::A2_tfrsi))
4745 (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
4754inline bool HexagonGlobalSchedulerImpl::multipleBranchesFromToBB(
4755 MachineBasicBlock *BB)
const {
4759 return ((Jumpers.
size() == 1) && !Jumpers[0]->isUnconditionalBranch());
4764bool HexagonGlobalSchedulerImpl::findPullUpCandidates(
4767 std::vector<MachineInstr *> &backtrack,
unsigned MaxCandidates = 1) {
4769 const HexagonInstrInfo *QII = (
const HexagonInstrInfo *)
TII;
4770 MachineBasicBlock *FromThisBB = FromHere->getParent();
4771 bool MovingDependentOp =
false;
4775 if (CurrentState.haveCandidates() >= MaxCandidates)
4781 if (FromHere->isBundle()) {
4783 for (++MII; MII != FromThisBB->
instr_end() && MII->isInsideBundle();
4785 if (MII->isDebugInstr())
4788 << MII->getParent()->getNumber() <<
"): ";
4792 if (!canThisMIBeMoved(&*MII, WorkPoint, MovingDependentOp,
CostBenefit))
4796 if (canAddMIToThisPacket(&*InstrToMove, CurrentState.HomeBundle)) {
4801 if (MII->isCompare())
4804 for (
unsigned i = 0; i < CurrentState.HomeBundle.size(); i++) {
4805 if (QII->
isDuplexPair(*CurrentState.HomeBundle[i], *MII)) {
4809 if (isCompoundPair(CurrentState.HomeBundle[i], &*MII)) {
4815 CurrentState.addPullUpCandidate(InstrToMove, WorkPoint, backtrack,
4824 else if (canThisMIBeMoved(&*FromHere, WorkPoint, MovingDependentOp,
4827 if (canAddMIToThisPacket(&*InstrToMove, CurrentState.HomeBundle)) {
4830 if (InstrToMove->isCompare())
4836 for (
unsigned i = 0; i < CurrentState.HomeBundle.size(); i++) {
4837 if (QII->
isDuplexPair(*CurrentState.HomeBundle[i], *InstrToMove)) {
4841 if (isCompoundPair(CurrentState.HomeBundle[i], &*InstrToMove)) {
4847 CurrentState.addPullUpCandidate(InstrToMove, WorkPoint, backtrack,
4850 LLVM_DEBUG(
dbgs() <<
"\tNo resources for single in the target packet.\n");
4858bool HexagonGlobalSchedulerImpl::tryMultipleInstructions(
4860 std::vector<BasicBlockRegion *>::iterator &CurrentRegion,
4867 bool MovingDependentOp =
false;
4868 std::vector<MachineInstr *> backtrack;
4872 std::sort(CurrentState.PullUpCandidates.begin(),
4873 CurrentState.PullUpCandidates.end(), PullUpCandidateSorter());
4876 for (SmallVector<PullUpCandidate *, 4>::iterator
4877 I = CurrentState.PullUpCandidates.begin(),
4878 E = CurrentState.PullUpCandidates.end();
4880 (*I)->populate(MII, WorkPoint, backtrack, MovingDependentOp);
4882 MachineBasicBlock *FromThisBB = MII->
getParent();
4883 MachineBasicBlock *ToThisBB = WorkPoint->getParent();
4886 LLVM_DEBUG(
dbgs() <<
"\tDependent(" << MovingDependentOp <<
") FromBB("
4888 << ToThisBB->
getNumber() <<
") to this packet:\n";
4892 if (MII->isInsideBundle()) {
4893 while (!FromHereII->isBundle())
4899 if (MoveMItoBundle(*CurrentRegion, MII, NextMI, WorkPoint, FromHere,
4900 backtrack, MovingDependentOp, PathInRegion)) {
4906 FromThisBBEnd = FromThisBB->
end();
4907 ToThisBBEnd = ToThisBB->
end();
4921 if (MoveMItoBundle(*CurrentRegion, MII, NextMI, WorkPoint, FromHere,
4922 backtrack, MovingDependentOp, PathInRegion)) {
4929 FromThisBBEnd = FromThisBB->
end();
4930 ToThisBBEnd = ToThisBB->
end();
4957bool HexagonGlobalSchedulerImpl::performPullUp() {
4958 std::vector<MachineInstr *> backtrack;
4964 for (std::vector<BasicBlockRegion *>::iterator
4965 CurrentRegion = PullUpRegions.begin(),
4966 E = PullUpRegions.end();
4967 CurrentRegion !=
E; ++CurrentRegion) {
4969 LLVM_DEBUG(
dbgs() <<
"\n\nRegion with(" << (*CurrentRegion)->size()
4977 for (
auto ToThisBB = (*CurrentRegion)->getRootMBB(),
4978 LastBBInRegion = (*CurrentRegion)->getLastMBB();
4979 ToThisBB != LastBBInRegion; ++ToThisBB) {
4983 if (multipleBranchesFromToBB(*ToThisBB))
4986 auto FromThisBB = ToThisBB;
4991 << (*ToThisBB)->getNumber() <<
")\n";
4992 (*ToThisBB)->dump());
4995 while (
MI != ToThisBBEnd) {
5001 while (ResourcesAvailableInBundle(*CurrentRegion, WorkPoint)) {
5003 << (*ToThisBB)->getNumber() <<
"):\n";
5017 FromThisBB = ToThisBB;
5018 FromHere = WorkPoint;
5020 FromThisBBEnd = (*FromThisBB)->end();
5027 backtrack.push_back(&*
I);
5029 FromThisBB = ToThisBB;
5031 FromHere = (*FromThisBB)->begin();
5032 FromThisBBEnd = (*FromThisBB)->end();
5039 backtrack.push_back(&*
I);
5046 if (FromHere == FromThisBBEnd) {
5050 LastBBInRegion = (*CurrentRegion)->getLastMBB();
5051 if (FromThisBB == LastBBInRegion)
5055 (*FromThisBB)->dump());
5056 FromThisBBEnd = (*FromThisBB)->end();
5057 FromHere = (*FromThisBB)->begin();
5058 if (FromThisBBEnd == FromHere)
5062 if ((*FromHere).isDebugInstr()) {
5067 backtrack.push_back(&*FromHere);
5068 if (!findPullUpCandidates(WorkPoint, FromHere, backtrack,
5074 if (!tryMultipleInstructions( WorkPoint, CurrentRegion,
MI,
5075 ToThisBBEnd, FromThisBBEnd))
5080 LastBBInRegion = (*CurrentRegion)->getLastMBB();
5093 std::vector<std::pair<MachineBasicBlock *, MachineBasicBlock *>>
5095 UnlikelyWork.reserve((*CurrentRegion)->size());
5096 for (
auto ToIt = (*CurrentRegion)->getRootMBB(),
5097 End = (*CurrentRegion)->getLastMBB();
5098 ToIt != End; ++ToIt) {
5099 MachineBasicBlock *ToBB = *ToIt;
5100 MachineBasicBlock *SecondBest = getNextPURBB(ToBB,
true);
5102 UnlikelyWork.emplace_back(ToBB, SecondBest);
5105 for (
auto [ToBB, SecondBest] : UnlikelyWork) {
5110 (*CurrentRegion)->addBBtoRegion(SecondBest);
5118 while (
MI != ToThisBBEnd) {
5124 while (ResourcesAvailableInBundle(*CurrentRegion, WorkPoint)) {
5129 FromHere = SecondBest->
begin();
5130 FromThisBBEnd = SecondBest->
end();
5138 backtrack.push_back(&*
I);
5143 if (FromHere == FromThisBBEnd) {
5145 <<
"\tOnly do one successor for the second try\n");
5148 if ((*FromHere).isDebugInstr()) {
5153 backtrack.push_back(&*FromHere);
5154 if (!findPullUpCandidates(WorkPoint, FromHere, backtrack,
5160 if (!tryMultipleInstructions( WorkPoint, CurrentRegion,
MI,
5161 ToThisBBEnd, FromThisBBEnd,
false))
5170bool HexagonGlobalSchedulerImpl::incrementalAddToPacket(MachineInstr &
MI) {
5172 LLVM_DEBUG(
dbgs() <<
"\t[AddToPacket] (" << CurrentPacketMIs.size()
5176 if (!ResourceTracker->canReserveResources(
MI) || !shouldAddToPacket(
MI))
5179 ResourceTracker->reserveResources(
MI);
5180 CurrentPacketMIs.push_back(&
MI);
5181 CurrentState.HomeBundle.push_back(&
MI);
5184 isJumpOutOfRange(&
MI)) {
5190 if (ResourceTracker->canReserveResources(*Ext)) {
5191 ResourceTracker->reserveResources(*Ext);
5192 LLVM_DEBUG(
dbgs() <<
"\t[AddToPacket] (" << CurrentPacketMIs.size()
5193 <<
") adding:\t immext_i\n");
5194 CurrentPacketMIs.push_back(Ext);
5195 CurrentState.HomeBundle.push_back(Ext);
5205void HexagonGlobalSchedulerImpl::checkBundleCounts(MachineFunction &Fn) {
5209 unsigned BundleLimit = 4;
5212 MBBi != MBBe; ++MBBi) {
5215 ME = MBBi->instr_end();
5217 if (
MI->isBundle()) {
5223 for (++MII; MII != End && MII->isInsideBundle(); ++MII) {
5224 if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
5225 MII->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
5226 MII->getOpcode() == TargetOpcode::CFI_INSTRUCTION ||
5227 MII->isEHLabel() || QII->
isEndLoopN(MII->getOpcode())) {
5237 assert(0 &&
"Bundle size exceeded");
5246unsigned HexagonGlobalSchedulerImpl::countCompounds(MachineFunction &Fn) {
5247 unsigned CompoundCount = 0;
5248 [[maybe_unused]]
unsigned DuplexCount = 0;
5249 [[maybe_unused]]
unsigned InstOffset = 0;
5260 if (
MI->isDebugInstr())
5262 if (
MI->isBundle()) {
5265 MachineInstr *FirstCompound = NULL, *SecondCompound = NULL;
5266 MachineInstr *FirstDuplex = NULL, *SecondDuplex = NULL;
5269 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle();
5271 if (MII->isDebugInstr())
5274 InstOffset += QII->
getSize(*MII);
5276 if (!FirstCompound) {
5277 FirstCompound = &*MII;
5280 SecondCompound = &*MII;
5286 FirstDuplex = &*MII;
5289 SecondDuplex = &*MII;
5296 if (SecondCompound) {
5297 if (isCompoundPair(FirstCompound, SecondCompound)) {
5298 LLVM_DEBUG(
dbgs() <<
"Compound pair (" << CompoundCount <<
")\n");
5319 LLVM_DEBUG(
dbgs() <<
"Total compound(" << CompoundCount <<
") duplex("
5320 << DuplexCount <<
")\n");
5321 return CompoundCount;
5329 return new HexagonGlobalScheduler();
unsigned const MachineRegisterInfo * MRI
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, TargetLibraryInfo &TLI)
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
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.
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 eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
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.
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,...
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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()
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
FuncUnits getUnits() const
Returns the choice of FUs.