42#define DEBUG_TYPE "opt-addr-mode"
61 StringRef getPassName()
const override {
62 return "Optimize addressing mode of load/store";
65 void getAnalysisUsage(AnalysisUsage &AU)
const override {
72 bool runOnMachineFunction(MachineFunction &MF)
override;
75 using MISetType = DenseSet<MachineInstr *>;
76 using InstrEvalMap = DenseMap<MachineInstr *, bool>;
77 DenseSet<MachineInstr *> ProcessedAddiInsts;
79 MachineRegisterInfo *MRI =
nullptr;
80 const TargetRegisterInfo *TRI =
nullptr;
81 const HexagonInstrInfo *HII =
nullptr;
82 const HexagonRegisterInfo *HRI =
nullptr;
83 MachineDominatorTree *MDT =
nullptr;
84 DataFlowGraph *DFG =
nullptr;
86 Liveness *LV =
nullptr;
89 bool processBlock(NodeAddr<BlockNode *> BA);
90 bool xformUseMI(MachineInstr *TfrMI, MachineInstr *
UseMI,
91 NodeAddr<UseNode *> UseN,
unsigned UseMOnum);
92 bool processAddBases(NodeAddr<StmtNode *> AddSN, MachineInstr *AddMI);
93 bool usedInLoadStore(NodeAddr<StmtNode *> CurrentInstSN, int64_t NewOffset);
94 bool findFirstReachedInst(
96 std::vector<std::pair<NodeAddr<StmtNode *>, NodeAddr<UseNode *>>>
98 NodeAddr<StmtNode *> &UseSN);
99 bool updateAddBases(MachineInstr *CurrentMI, MachineInstr *FirstReachedMI,
101 bool processAddUses(NodeAddr<StmtNode *> AddSN, MachineInstr *AddMI,
103 bool updateAddUses(MachineInstr *AddMI, MachineInstr *
UseMI);
104 bool analyzeUses(
unsigned DefR,
const NodeList &UNodeList,
105 InstrEvalMap &InstrEvalResult,
short &SizeInc);
106 bool hasRepForm(MachineInstr &
MI,
unsigned TfrDefR);
107 bool canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN, MachineInstr &
MI,
109 bool isSafeToExtLR(NodeAddr<StmtNode *> SN, MachineInstr *
MI,
110 unsigned LRExtReg,
const NodeList &UNodeList);
111 void getAllRealUses(NodeAddr<StmtNode *> SN,
NodeList &UNodeList);
112 bool allValidCandidates(NodeAddr<StmtNode *> SA,
NodeList &UNodeList);
113 short getBaseWithLongOffset(
const MachineInstr &
MI)
const;
114 bool changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
116 bool changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
unsigned ImmOpNum);
117 bool changeAddAsl(NodeAddr<UseNode *> AddAslUN, MachineInstr *AddAslMI,
118 const MachineOperand &ImmOp,
unsigned ImmOpNum);
119 bool isValidOffset(MachineInstr *
MI,
int Offset);
120 unsigned getBaseOpPosition(MachineInstr *
MI);
121 unsigned getOffsetOpPosition(MachineInstr *
MI);
126char HexagonOptAddrMode::ID = 0;
129 "Optimize addressing mode",
false,
false)
135bool HexagonOptAddrMode::hasRepForm(
MachineInstr &
MI,
unsigned TfrDefR) {
142 MachineOperand StOp = MI.getOperand(MI.getNumOperands() - 1);
143 if (StOp.isReg() && StOp.getReg() == TfrDefR)
149 return (HII->changeAddrMode_rr_ur(
MI) >= 0);
152 return (HII->changeAddrMode_io_abs(
MI) >= 0);
171 const MachineOperand &
OffsetOp =
MI.getOperand(3);
175 Register OffsetReg =
MI.getOperand(2).getReg();
176 RegisterRef OffsetRR;
178 for (NodeAddr<UseNode *> UA : AddAslSN.
Addr->members_if(DFG->
IsUse, *DFG)) {
179 RegisterRef RR = UA.Addr->getRegRef(*DFG);
180 if (OffsetReg == RR.
Reg) {
182 OffsetRegRD = UA.Addr->getReachingDef();
186 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
187 NodeAddr<UseNode *> UA = *
I;
188 NodeAddr<InstrNode *>
IA = UA.
Addr->getOwner(*DFG);
192 if ((DFG->
IsDef(AA) && AA.
Id != OffsetRegRD) ||
193 AA.
Addr->getReachingDef() != OffsetRegRD)
196 MachineInstr &
UseMI = *NodeAddr<StmtNode *>(IA).Addr->getCode();
197 NodeAddr<DefNode *> OffsetRegDN = DFG->
addr<DefNode *>(OffsetRegRD);
200 MI.getParent() !=
UseMI.getParent())
203 const MCInstrDesc &UseMID =
UseMI.getDesc();
206 getBaseWithLongOffset(
UseMI) < 0)
214 for (
auto &Mo :
UseMI.operands())
219 if (!
UseMI.getParent()->isLiveIn(OffsetReg) &&
220 MI.getParent() !=
UseMI.getParent()) {
222 <<
" is NOT live in to MBB "
223 <<
UseMI.getParent()->getName() <<
"\n");
230bool HexagonOptAddrMode::allValidCandidates(NodeAddr<StmtNode *> SA,
232 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
233 NodeAddr<UseNode *> UN = *
I;
234 RegisterRef UR = UN.
Addr->getRegRef(*DFG);
239 dbgs() <<
"*** Unable to collect all reaching defs for use ***\n"
240 << PrintNode<UseNode*>(UN, *DFG) <<
'\n'
241 <<
"The program's complexity may exceed the limits.\n";
245 const auto &ReachingDefs =
P.first;
246 if (ReachingDefs.size() > 1) {
248 dbgs() <<
"*** Multiple Reaching Defs found!!! ***\n";
249 for (
auto DI : ReachingDefs) {
250 NodeAddr<UseNode *>
DA = DFG->
addr<UseNode *>(DI);
251 NodeAddr<StmtNode *> TempIA =
DA.Addr->getOwner(*DFG);
252 dbgs() <<
"\t\t[Reaching Def]: "
262void HexagonOptAddrMode::getAllRealUses(NodeAddr<StmtNode *> SA,
264 for (NodeAddr<DefNode *> DA : SA.
Addr->members_if(DFG->
IsDef, *DFG)) {
266 <<
Print<NodeAddr<DefNode *>>(DA, *DFG) <<
"\n");
267 RegisterRef DR =
DA.Addr->getRegRef(*DFG);
271 for (
auto UI : UseSet) {
272 NodeAddr<UseNode *> UA = DFG->
addr<UseNode *>(UI);
274 NodeAddr<StmtNode *> TempIA = UA.
Addr->getOwner(*DFG);
275 dbgs() <<
"\t\t\t[Reached Use]: "
280 NodeAddr<PhiNode *> PA = UA.
Addr->getOwner(*DFG);
285 if (!phiUse.empty()) {
286 for (
auto I : phiUse) {
289 auto phiUseSet =
I.second;
290 for (
auto phiUI : phiUseSet) {
291 NodeAddr<UseNode *> phiUA = DFG->
addr<UseNode *>(phiUI.first);
292 UNodeList.push_back(phiUA);
297 UNodeList.push_back(UA);
302bool HexagonOptAddrMode::isSafeToExtLR(NodeAddr<StmtNode *> SN,
303 MachineInstr *
MI,
unsigned LRExtReg,
309 for (NodeAddr<UseNode *> UA : SN.
Addr->members_if(DFG->
IsUse, *DFG)) {
310 RegisterRef RR = UA.
Addr->getRegRef(*DFG);
311 if (LRExtReg == RR.
Reg) {
313 LRExtRegRD = UA.
Addr->getReachingDef();
317 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
318 NodeAddr<UseNode *> UA = *
I;
319 NodeAddr<InstrNode *>
IA = UA.
Addr->getOwner(*DFG);
325 if ((DFG->
IsDef(AA) && AA.
Id != LRExtRegRD) ||
326 AA.
Addr->getReachingDef() != LRExtRegRD) {
328 dbgs() <<
"isSafeToExtLR: Returning false; another reaching def\n");
338 MachineInstr *
UseMI = NodeAddr<StmtNode *>(IA).Addr->getCode();
339 NodeAddr<DefNode *> LRExtRegDN = DFG->
addr<DefNode *>(LRExtRegRD);
348 <<
" is NOT live in to MBB "
356bool HexagonOptAddrMode::isValidOffset(MachineInstr *
MI,
int Offset) {
360 switch (
MI->getOpcode()) {
361 case Hexagon::V6_vgathermh_pseudo:
362 case Hexagon::V6_vgathermw_pseudo:
363 case Hexagon::V6_vgathermhw_pseudo:
364 case Hexagon::V6_vgathermhq_pseudo:
365 case Hexagon::V6_vgathermwq_pseudo:
366 case Hexagon::V6_vgathermhwq_pseudo:
372 if ((AlignMask &
Offset) == 0)
382 unsigned AlignMask = 0;
384 case HexagonII::MemAccessSize::DoubleWordAccess:
387 case HexagonII::MemAccessSize::WordAccess:
390 case HexagonII::MemAccessSize::HalfWordAccess:
393 case HexagonII::MemAccessSize::ByteAccess:
400 if ((AlignMask &
Offset) != 0)
405unsigned HexagonOptAddrMode::getBaseOpPosition(MachineInstr *
MI) {
406 const MCInstrDesc &MID =
MI->getDesc();
407 switch (
MI->getOpcode()) {
411 case Hexagon::V6_vgathermh_pseudo:
412 case Hexagon::V6_vgathermw_pseudo:
413 case Hexagon::V6_vgathermhw_pseudo:
414 case Hexagon::V6_vgathermhq_pseudo:
415 case Hexagon::V6_vgathermwq_pseudo:
416 case Hexagon::V6_vgathermhwq_pseudo:
423unsigned HexagonOptAddrMode::getOffsetOpPosition(MachineInstr *
MI) {
426 "Looking for an offset in non-BaseImmOffset addressing mode instruction");
428 const MCInstrDesc &MID =
MI->getDesc();
429 switch (
MI->getOpcode()) {
433 case Hexagon::V6_vgathermh_pseudo:
434 case Hexagon::V6_vgathermw_pseudo:
435 case Hexagon::V6_vgathermhw_pseudo:
436 case Hexagon::V6_vgathermhq_pseudo:
437 case Hexagon::V6_vgathermwq_pseudo:
438 case Hexagon::V6_vgathermhwq_pseudo:
445bool HexagonOptAddrMode::usedInLoadStore(NodeAddr<StmtNode *> CurrentInstSN,
449 getAllRealUses(CurrentInstSN, LoadStoreUseList);
450 bool FoundLoadStoreUse =
false;
451 for (NodeAddr<UseNode *> UN : LoadStoreUseList) {
452 NodeAddr<StmtNode *> SN = UN.
Addr->getOwner(*DFG);
453 MachineInstr *LoadStoreMI = SN.
Addr->getCode();
454 const MCInstrDesc &MID = LoadStoreMI->
getDesc();
456 isValidOffset(LoadStoreMI, NewOffset)) {
457 FoundLoadStoreUse =
true;
461 return FoundLoadStoreUse;
464bool HexagonOptAddrMode::findFirstReachedInst(
466 std::vector<std::pair<NodeAddr<StmtNode *>, NodeAddr<UseNode *>>> &AddiList,
467 NodeAddr<StmtNode *> &UseSN) {
480 MachineBasicBlock *CurrentMBB = AddMI->
getParent();
481 for (
auto &InstIter : *CurrentMBB) {
483 if (InstIter.getOpcode() == Hexagon::A2_addi) {
484 auto Iter =
llvm::find_if(AddiList, [&InstIter](
const auto &SUPair) {
485 return SUPair.first.Addr->getCode() == &InstIter;
487 if (Iter != AddiList.end()) {
521bool HexagonOptAddrMode::processAddBases(NodeAddr<StmtNode *> AddSN,
522 MachineInstr *AddMI) {
526 LLVM_DEBUG(
dbgs() <<
"\n\t\t[Processing Addi]: " << *AddMI <<
"\n");
529 [](
const MachineInstr *
MI,
530 const DenseSet<MachineInstr *> &ProcessedAddiInsts) ->
bool {
533 LLVM_DEBUG(
dbgs() <<
"\t\t\tAddi already found in ProcessedAddiInsts: "
534 << *
MI <<
"\n\t\t\tSkipping...");
540 if (Processed(AddMI, ProcessedAddiInsts))
542 ProcessedAddiInsts.
insert(AddMI);
549 std::vector<std::pair<NodeAddr<StmtNode *>, NodeAddr<UseNode *>>> AddiList;
553 for (NodeAddr<UseNode *> UA : AddSN.
Addr->members_if(DFG->
IsUse, *DFG)) {
554 RegisterRef URR = UA.
Addr->getRegRef(*DFG);
555 if (BaseReg != URR.
Reg)
558 UAReachingDefID = UA.
Addr->getReachingDef();
559 NodeAddr<DefNode *> UADef = DFG->
addr<DefNode *>(UAReachingDefID);
561 LLVM_DEBUG(
dbgs() <<
"\t\t\t Could not find reachingDef. Skipping...\n");
566 NodeAddr<DefNode *> UAReachingDef = DFG->
addr<DefNode *>(UAReachingDefID);
567 NodeAddr<StmtNode *> ReachingDefStmt = UAReachingDef.
Addr->getOwner(*DFG);
571 MachineInstr *ReachingDefInstr = ReachingDefStmt.Addr->getCode();
579 getAllRealUses(ReachingDefStmt, AddiUseList);
580 for (NodeAddr<UseNode *> UN : AddiUseList) {
581 NodeAddr<StmtNode *> SN = UN.
Addr->getOwner(*DFG);
582 MachineInstr *
MI = SN.
Addr->getCode();
585 if (
MI->getOpcode() == Hexagon::A2_addi &&
586 !(
MI != AddMI && Processed(
MI, ProcessedAddiInsts))) {
587 AddiList.push_back({SN, UN});
595 if (AddiList.size() <= 1)
598 NodeAddr<StmtNode *> FirstReachedUseSN;
600 if (!findFirstReachedInst(AddMI, AddiList, FirstReachedUseSN))
606 NodeAddr<DefNode *> FirstReachedUseDN =
607 FirstReachedUseSN.
Addr->members_if(DFG->
IsDef, *DFG).front();
609 MachineInstr *FirstReachedMI = FirstReachedUseSN.
Addr->getCode();
610 const MachineOperand FirstReachedMIImmOp = FirstReachedMI->
getOperand(2);
611 if (!FirstReachedMIImmOp.
isImm())
614 for (
auto &
I : AddiList) {
615 NodeAddr<StmtNode *> CurrentInstSN =
I.first;
616 NodeAddr<UseNode *> CurrentInstUN =
I.second;
618 MachineInstr *CurrentMI = CurrentInstSN.
Addr->getCode();
619 MachineOperand &CurrentMIImmOp = CurrentMI->
getOperand(2);
625 if (!CurrentMIImmOp.
isImm())
628 NewOffset = CurrentMIImmOp.
getImm() - FirstReachedMIImmOp.
getImm();
631 if (CurrentMI == FirstReachedMI) {
645 if (!usedInLoadStore(CurrentInstSN, NewOffset)) {
651 RegisterRef FirstReachedDefRR = FirstReachedUseDN.
Addr->getRegRef(*DFG);
652 NodeAddr<InstrNode *> CurrentAddiIN = CurrentInstUN.
Addr->getOwner(*DFG);
653 NodeAddr<RefNode *> NearestAA =
655 if ((DFG->
IsDef(NearestAA) && NearestAA.
Id != FirstReachedUseDN.
Id) ||
656 (!DFG->
IsDef(NearestAA) &&
657 NearestAA.
Addr->getReachingDef() != FirstReachedUseDN.
Id)) {
659 LLVM_DEBUG(
dbgs() <<
"\t\t\tCould not modify below Addi since the first "
660 "defined Addi register was redefined\n");
664 MachineOperand CurrentMIBaseOp = CurrentMI->
getOperand(1);
671 Changed |= updateAddBases(CurrentMI, FirstReachedMI, NewOffset);
674 CurrentInstUN.
Addr->linkToDef(CurrentInstUN.
Id, FirstReachedUseDN);
680bool HexagonOptAddrMode::updateAddBases(MachineInstr *CurrentMI,
681 MachineInstr *FirstReachedMI,
683 LLVM_DEBUG(
dbgs() <<
"[About to modify the Addi]: " << *CurrentMI <<
"\n");
684 const MachineOperand FirstReachedDef = FirstReachedMI->
getOperand(0);
687 MachineOperand &CurrentMIBaseOp = CurrentMI->
getOperand(1);
688 MachineOperand &CurrentMIImmOp = CurrentMI->
getOperand(2);
690 CurrentMIBaseOp.
setReg(FirstDefRegister);
693 CurrentMIImmOp.
setImm(NewOffset);
694 ProcessedAddiInsts.
insert(CurrentMI);
695 MRI->clearKillFlags(FirstDefRegister);
699bool HexagonOptAddrMode::processAddUses(NodeAddr<StmtNode *> AddSN,
705 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
706 NodeAddr<UseNode *> UN = *
I;
707 NodeAddr<StmtNode *> SN = UN.
Addr->getOwner(*DFG);
708 MachineInstr *
MI = SN.
Addr->getCode();
709 const MCInstrDesc &MID =
MI->getDesc();
714 MachineOperand BaseOp =
MI->getOperand(getBaseOpPosition(
MI));
719 MachineOperand
OffsetOp =
MI->getOperand(getOffsetOpPosition(
MI));
724 if (!isValidOffset(
MI, newOffset))
734 if (!isSafeToExtLR(AddSN, AddMI, BaseReg, UNodeList))
741 for (NodeAddr<UseNode *> UA : AddSN.
Addr->members_if(DFG->
IsUse, *DFG)) {
742 RegisterRef RR = UA.
Addr->getRegRef(*DFG);
743 if (BaseReg == RR.
Reg)
744 LRExtRegRD = UA.
Addr->getReachingDef();
750 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
751 NodeAddr<UseNode *> UseN = *
I;
753 "Found a PhiRef node as a real reached use!!");
755 NodeAddr<StmtNode *> OwnerN = UseN.
Addr->getOwner(*DFG);
756 MachineInstr *
UseMI = OwnerN.
Addr->getCode();
758 <<
">]: " << *
UseMI <<
"\n");
764 NodeAddr<DefNode *> LRExtRegDN = DFG->
addr<DefNode *>(LRExtRegRD);
765 UseN.
Addr->linkToDef(UseN.
Id, LRExtRegDN);
774bool HexagonOptAddrMode::updateAddUses(MachineInstr *AddMI,
775 MachineInstr *
UseMI) {
776 const MachineOperand ImmOp = AddMI->
getOperand(2);
777 const MachineOperand AddRegOp = AddMI->
getOperand(1);
786 MRI->clearKillFlags(NewReg);
791bool HexagonOptAddrMode::analyzeUses(
unsigned tfrDefR,
793 InstrEvalMap &InstrEvalResult,
795 bool KeepTfr =
false;
796 bool HasRepInstr =
false;
797 InstrEvalResult.clear();
799 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
800 bool CanBeReplaced =
false;
801 NodeAddr<UseNode *> UN = *
I;
802 NodeAddr<StmtNode *> SN = UN.
Addr->getOwner(*DFG);
803 MachineInstr &
MI = *SN.
Addr->getCode();
804 const MCInstrDesc &MID =
MI.getDesc();
806 if (!hasRepForm(
MI, tfrDefR)) {
811 CanBeReplaced =
true;
812 }
else if (
MI.getOpcode() == Hexagon::S2_addasl_rrri) {
816 getAllRealUses(SN, AddaslUseList);
818 if (allValidCandidates(SN, AddaslUseList) &&
819 canRemoveAddasl(SN,
MI, AddaslUseList)) {
820 SizeInc += AddaslUseList.size();
822 CanBeReplaced =
true;
832 InstrEvalResult[&
MI] = CanBeReplaced;
833 HasRepInstr |= CanBeReplaced;
843bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
846 MachineBasicBlock *BB = OldMI->
getParent();
852 MachineInstrBuilder MIB;
857 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
868 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
871 const GlobalValue *GV = ImmOp.
getGlobal();
882 }
else if (ImmOpNum == 2) {
885 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
898 for (
unsigned i = OpStart; i < OpEnd; ++i)
904bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
907 unsigned OpStart = 0;
909 MachineBasicBlock *BB = OldMI->
getParent();
913 MachineInstrBuilder MIB;
917 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
927 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
929 const GlobalValue *GV = ImmOp.
getGlobal();
938 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
949 for (
unsigned i = OpStart; i < OpEnd; ++i)
956short HexagonOptAddrMode::getBaseWithLongOffset(
const MachineInstr &
MI)
const {
964bool HexagonOptAddrMode::changeAddAsl(NodeAddr<UseNode *> AddAslUN,
965 MachineInstr *AddAslMI,
966 const MachineOperand &ImmOp,
968 NodeAddr<StmtNode *> SA = AddAslUN.
Addr->getOwner(*DFG);
973 getAllRealUses(SA, UNodeList);
975 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
976 NodeAddr<UseNode *> UseUN = *
I;
978 "Can't transform this 'AddAsl' instruction!");
980 NodeAddr<StmtNode *> UseIA = UseUN.
Addr->getOwner(*DFG);
982 <<
Print<NodeAddr<InstrNode *>>(UseIA, *DFG) <<
"\n");
983 MachineInstr *
UseMI = UseIA.
Addr->getCode();
985 <<
">]: " << *
UseMI <<
"\n");
991 short NewOpCode = getBaseWithLongOffset(*
UseMI);
992 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
998 MachineInstrBuilder MIB =
1005 const GlobalValue *GV = ImmOp.
getGlobal();
1012 const GlobalValue *GV = ImmOp.
getGlobal();
1020 for (
unsigned i = OpStart; i < OpEnd; ++i)
1028bool HexagonOptAddrMode::xformUseMI(MachineInstr *TfrMI, MachineInstr *
UseMI,
1029 NodeAddr<UseNode *> UseN,
1030 unsigned UseMOnum) {
1031 const MachineOperand ImmOp = TfrMI->
getOperand(1);
1047bool HexagonOptAddrMode::processBlock(NodeAddr<BlockNode *> BA) {
1050 for (
auto IA : BA.
Addr->members(*DFG)) {
1054 NodeAddr<StmtNode *> SA =
IA;
1055 MachineInstr *
MI = SA.
Addr->getCode();
1056 if ((
MI->getOpcode() != Hexagon::A2_tfrsi ||
1057 !
MI->getOperand(1).isGlobal()) &&
1058 (
MI->getOpcode() != Hexagon::A2_addi ||
1063 <<
"]: " << *
MI <<
"\n\t[InstrNode]: "
1064 <<
Print<NodeAddr<InstrNode *>>(IA, *DFG) <<
'\n');
1066 if (
MI->getOpcode() == Hexagon::A2_addi)
1069 getAllRealUses(SA, UNodeList);
1071 if (!allValidCandidates(SA, UNodeList))
1084 if (
MI->getOpcode() == Hexagon::A2_addi) {
1085 Changed |= processAddUses(SA,
MI, UNodeList);
1091 InstrEvalMap InstrEvalResult;
1095 if (!analyzeUses(DefR, UNodeList, InstrEvalResult, SizeInc))
1100 bool KeepTfr =
false;
1102 LLVM_DEBUG(
dbgs() <<
"\t[Total reached uses] : " << UNodeList.size()
1105 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
1106 NodeAddr<UseNode *> UseN = *
I;
1108 "Found a PhiRef node as a real reached use!!");
1110 NodeAddr<StmtNode *> OwnerN = UseN.
Addr->getOwner(*DFG);
1111 MachineInstr *
UseMI = OwnerN.
Addr->getCode();
1113 <<
">]: " << *
UseMI <<
"\n");
1117 for (
unsigned j = 0;
j < NumOperands - 1; ++
j) {
1119 if (
op.isReg() &&
op.isUse() && DefR ==
op.getReg())
1128 bool Xformed =
false;
1129 if (UseMOnum >= 0 && InstrEvalResult[
UseMI])
1130 Xformed = xformUseMI(
MI,
UseMI, UseN, UseMOnum);
1132 KeepTfr |= !Xformed;
1140bool HexagonOptAddrMode::runOnMachineFunction(MachineFunction &MF) {
1148 <<
": too many basic blocks\n");
1156 HII = HST.getInstrInfo();
1157 HRI = HST.getRegisterInfo();
1158 const auto &MDF = getAnalysis<MachineDominanceFrontier>();
1159 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1161 DataFlowGraph
G(MF, *HII, *HRI, *MDT, MDF);
1167 Liveness
L(*
MRI, *DFG);
1172 ProcessedAddiInsts.
clear();
1173 NodeAddr<FuncNode *> FA = DFG->
getFunc();
1175 <<
Print<NodeAddr<FuncNode *>>(FA, *DFG) <<
"\n");
1177 for (NodeAddr<BlockNode *> BA : FA.
Addr->members(*DFG))
1181 MI->eraseFromParent();
1198 return new HexagonOptAddrMode();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static cl::opt< int > CodeGrowthLimit("hexagon-amode-growth-limit", cl::Hidden, cl::init(0), cl::desc("Code growth limit for address mode " "optimization"))
cl::opt< unsigned > RDFFuncBlockLimit
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
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.
unsigned getAddrMode(const MachineInstr &MI) const
bool isValidOffset(unsigned Opcode, int Offset, const TargetRegisterInfo *TRI, bool Extend=true) const
bool isConstExtended(const MachineInstr &MI) const
short changeAddrMode_rr_ur(short Opc) const
unsigned getMemAccessSize(const MachineInstr &MI) const
short changeAddrMode_io_abs(short Opc) const
short changeAddrMode_rr_io(short Opc) const
bool isHVXVec(const MachineInstr &MI) const
short changeAddrMode_io_rr(short Opc) const
Describe properties that are true of each instruction in the target description file.
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
Instructions::iterator instr_iterator
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.
Analysis pass which computes a MachineDominatorTree.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
const GlobalValue * getGlobal() const
void setImplicit(bool Val=true)
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned getTargetFlags() const
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
int64_t getOffset() const
Return the offset from the symbol in this operand.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
Print(const T &, const DataFlowGraph &) -> Print< T >
std::set< NodeId > NodeSet
SmallVector< Node, 4 > NodeList
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createHexagonOptAddrMode()
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
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.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
static bool IsDef(const Node BA)
static bool IsUse(const Node BA)
const PhysicalRegisterInfo & getPRI() const
static bool IsCode(const Node BA)
std::unordered_map< RegisterId, DefStack > DefStackMap
NodeAddr< T > addr(NodeId N) const
const RefMap & getRealUses(NodeId P) const
NodeAddr< RefNode * > getNearestAliasedRef(RegisterRef RefRR, NodeAddr< InstrNode * > IA)
Find the nearest ref node aliased to RefRR, going upwards in the data flow, starting from the instruc...
std::pair< NodeSet, bool > getAllReachingDefsRec(RegisterRef RefRR, NodeAddr< RefNode * > RefA, NodeSet &Visited, const NodeSet &Defs)
std::unordered_map< RegisterId, NodeRefSet > RefMap
NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr< DefNode * > DefA, const RegisterAggr &DefRRs)
bool alias(RegisterRef RA, RegisterRef RB) const