44#define DEBUG_TYPE "opt-addr-mode"
63 StringRef getPassName()
const override {
64 return "Optimize addressing mode of load/store";
67 void getAnalysisUsage(AnalysisUsage &AU)
const override {
70 AU.
addRequired<MachineDominanceFrontierWrapperPass>();
77 using MISetType = DenseSet<MachineInstr *>;
78 using InstrEvalMap = DenseMap<MachineInstr *, bool>;
79 DenseSet<MachineInstr *> ProcessedAddiInsts;
81 MachineRegisterInfo *MRI =
nullptr;
82 const TargetRegisterInfo *TRI =
nullptr;
83 const HexagonInstrInfo *HII =
nullptr;
84 const HexagonRegisterInfo *HRI =
nullptr;
85 MachineDominatorTree *MDT =
nullptr;
86 DataFlowGraph *DFG =
nullptr;
88 Liveness *LV =
nullptr;
92 bool xformUseMI(MachineInstr *TfrMI, MachineInstr *
UseMI,
93 NodeAddr<UseNode *> UseN,
unsigned UseMOnum);
94 bool processAddBases(NodeAddr<StmtNode *> AddSN, MachineInstr *AddMI);
95 bool usedInLoadStore(NodeAddr<StmtNode *> CurrentInstSN, int64_t NewOffset);
96 bool findFirstReachedInst(
98 std::vector<std::pair<NodeAddr<StmtNode *>, NodeAddr<UseNode *>>>
100 NodeAddr<StmtNode *> &UseSN);
101 bool updateAddBases(MachineInstr *CurrentMI, MachineInstr *FirstReachedMI,
103 bool processAddUses(NodeAddr<StmtNode *> AddSN, MachineInstr *AddMI,
105 bool updateAddUses(MachineInstr *AddMI, MachineInstr *
UseMI);
106 bool analyzeUses(
unsigned DefR,
const NodeList &UNodeList,
107 InstrEvalMap &InstrEvalResult,
short &SizeInc);
108 bool hasRepForm(MachineInstr &
MI,
unsigned TfrDefR);
109 bool canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN, MachineInstr &
MI,
111 bool isSafeToExtLR(NodeAddr<StmtNode *> SN, MachineInstr *
MI,
114 bool allValidCandidates(NodeAddr<StmtNode *> SA,
NodeList &UNodeList);
115 short getBaseWithLongOffset(
const MachineInstr &
MI)
const;
116 bool changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
118 bool changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
unsigned ImmOpNum);
119 bool changeAddAsl(NodeAddr<UseNode *> AddAslUN, MachineInstr *AddAslMI,
120 const MachineOperand &ImmOp,
unsigned ImmOpNum);
121 bool isValidOffset(MachineInstr *
MI,
int Offset);
122 unsigned getBaseOpPosition(MachineInstr *
MI);
123 unsigned getOffsetOpPosition(MachineInstr *
MI);
128char HexagonOptAddrMode::ID = 0;
131 "Optimize addressing mode",
false,
false)
137bool HexagonOptAddrMode::hasRepForm(
MachineInstr &
MI,
unsigned TfrDefR) {
144 MachineOperand StOp = MI.getOperand(MI.getNumOperands() - 1);
145 if (StOp.isReg() && StOp.getReg() == TfrDefR)
151 return (HII->changeAddrMode_rr_ur(
MI) >= 0);
154 return (HII->changeAddrMode_io_abs(
MI) >= 0);
173 const MachineOperand &
OffsetOp =
MI.getOperand(3);
177 Register OffsetReg =
MI.getOperand(2).getReg();
178 RegisterRef OffsetRR;
180 for (NodeAddr<UseNode *> UA : AddAslSN.
Addr->members_if(DFG->
IsUse, *DFG)) {
181 RegisterRef RR = UA.Addr->getRegRef(*DFG);
182 if (OffsetReg == RR.
asMCReg()) {
184 OffsetRegRD = UA.Addr->getReachingDef();
188 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
189 NodeAddr<UseNode *> UA = *
I;
190 NodeAddr<InstrNode *>
IA = UA.
Addr->getOwner(*DFG);
194 if ((DFG->
IsDef(AA) && AA.
Id != OffsetRegRD) ||
195 AA.
Addr->getReachingDef() != OffsetRegRD)
198 MachineInstr &
UseMI = *NodeAddr<StmtNode *>(IA).Addr->getCode();
199 NodeAddr<DefNode *> OffsetRegDN = DFG->
addr<DefNode *>(OffsetRegRD);
202 MI.getParent() !=
UseMI.getParent())
205 const MCInstrDesc &UseMID =
UseMI.getDesc();
208 getBaseWithLongOffset(
UseMI) < 0)
216 for (
auto &Mo :
UseMI.operands())
221 if (!
UseMI.getParent()->isLiveIn(OffsetReg) &&
224 <<
" is NOT live in to MBB "
225 <<
UseMI.getParent()->getName() <<
"\n");
232bool HexagonOptAddrMode::allValidCandidates(NodeAddr<StmtNode *> SA,
234 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
235 NodeAddr<UseNode *> UN = *
I;
236 RegisterRef UR = UN.
Addr->getRegRef(*DFG);
241 dbgs() <<
"*** Unable to collect all reaching defs for use ***\n"
242 << PrintNode<UseNode*>(UN, *DFG) <<
'\n'
243 <<
"The program's complexity may exceed the limits.\n";
247 const auto &ReachingDefs =
P.first;
248 if (ReachingDefs.size() > 1) {
250 dbgs() <<
"*** Multiple Reaching Defs found!!! ***\n";
251 for (
auto DI : ReachingDefs) {
252 NodeAddr<UseNode *>
DA = DFG->
addr<UseNode *>(DI);
253 NodeAddr<StmtNode *> TempIA =
DA.Addr->getOwner(*DFG);
254 dbgs() <<
"\t\t[Reaching Def]: "
264void HexagonOptAddrMode::getAllRealUses(NodeAddr<StmtNode *> SA,
266 for (NodeAddr<DefNode *> DA : SA.
Addr->members_if(DFG->
IsDef, *DFG)) {
268 <<
Print<NodeAddr<DefNode *>>(DA, *DFG) <<
"\n");
269 RegisterRef DR =
DA.Addr->getRegRef(*DFG);
273 for (
auto UI : UseSet) {
274 NodeAddr<UseNode *> UA = DFG->
addr<UseNode *>(UI);
276 NodeAddr<StmtNode *> TempIA = UA.
Addr->getOwner(*DFG);
277 dbgs() <<
"\t\t\t[Reached Use]: "
282 NodeAddr<PhiNode *> PA = UA.
Addr->getOwner(*DFG);
287 if (!phiUse.
empty()) {
288 for (
auto I : phiUse) {
291 auto phiUseSet =
I.second;
292 for (
auto phiUI : phiUseSet) {
293 NodeAddr<UseNode *> phiUA = DFG->
addr<UseNode *>(phiUI.first);
294 UNodeList.push_back(phiUA);
299 UNodeList.push_back(UA);
304bool HexagonOptAddrMode::isSafeToExtLR(NodeAddr<StmtNode *> SN,
311 for (NodeAddr<UseNode *> UA : SN.
Addr->members_if(DFG->
IsUse, *DFG)) {
312 RegisterRef RR = UA.
Addr->getRegRef(*DFG);
313 if (LRExtReg == RR.
asMCReg()) {
315 LRExtRegRD = UA.
Addr->getReachingDef();
319 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
320 NodeAddr<UseNode *> UA = *
I;
321 NodeAddr<InstrNode *>
IA = UA.
Addr->getOwner(*DFG);
327 if ((DFG->
IsDef(AA) && AA.
Id != LRExtRegRD) ||
328 AA.
Addr->getReachingDef() != LRExtRegRD) {
330 dbgs() <<
"isSafeToExtLR: Returning false; another reaching def\n");
340 MachineInstr *
UseMI = NodeAddr<StmtNode *>(IA).Addr->getCode();
341 NodeAddr<DefNode *> LRExtRegDN = DFG->
addr<DefNode *>(LRExtRegRD);
350 <<
" is NOT live in to MBB "
358bool HexagonOptAddrMode::isValidOffset(MachineInstr *
MI,
int Offset) {
362 switch (
MI->getOpcode()) {
363 case Hexagon::V6_vgathermh_pseudo:
364 case Hexagon::V6_vgathermw_pseudo:
365 case Hexagon::V6_vgathermhw_pseudo:
366 case Hexagon::V6_vgathermhq_pseudo:
367 case Hexagon::V6_vgathermwq_pseudo:
368 case Hexagon::V6_vgathermhwq_pseudo:
374 if ((AlignMask &
Offset) == 0)
384 unsigned AlignMask = 0;
386 case HexagonII::MemAccessSize::DoubleWordAccess:
389 case HexagonII::MemAccessSize::WordAccess:
392 case HexagonII::MemAccessSize::HalfWordAccess:
395 case HexagonII::MemAccessSize::ByteAccess:
402 if ((AlignMask &
Offset) != 0)
407unsigned HexagonOptAddrMode::getBaseOpPosition(MachineInstr *
MI) {
408 const MCInstrDesc &MID =
MI->getDesc();
409 switch (
MI->getOpcode()) {
413 case Hexagon::V6_vgathermh_pseudo:
414 case Hexagon::V6_vgathermw_pseudo:
415 case Hexagon::V6_vgathermhw_pseudo:
416 case Hexagon::V6_vgathermhq_pseudo:
417 case Hexagon::V6_vgathermwq_pseudo:
418 case Hexagon::V6_vgathermhwq_pseudo:
425unsigned HexagonOptAddrMode::getOffsetOpPosition(MachineInstr *
MI) {
428 "Looking for an offset in non-BaseImmOffset addressing mode instruction");
430 const MCInstrDesc &MID =
MI->getDesc();
431 switch (
MI->getOpcode()) {
435 case Hexagon::V6_vgathermh_pseudo:
436 case Hexagon::V6_vgathermw_pseudo:
437 case Hexagon::V6_vgathermhw_pseudo:
438 case Hexagon::V6_vgathermhq_pseudo:
439 case Hexagon::V6_vgathermwq_pseudo:
440 case Hexagon::V6_vgathermhwq_pseudo:
447bool HexagonOptAddrMode::usedInLoadStore(NodeAddr<StmtNode *> CurrentInstSN,
452 bool FoundLoadStoreUse =
false;
453 for (NodeAddr<UseNode *> UN : LoadStoreUseList) {
454 NodeAddr<StmtNode *> SN = UN.
Addr->getOwner(*DFG);
455 MachineInstr *LoadStoreMI = SN.
Addr->getCode();
456 const MCInstrDesc &MID = LoadStoreMI->
getDesc();
458 isValidOffset(LoadStoreMI, NewOffset)) {
459 FoundLoadStoreUse =
true;
463 return FoundLoadStoreUse;
466bool HexagonOptAddrMode::findFirstReachedInst(
468 std::vector<std::pair<NodeAddr<StmtNode *>, NodeAddr<UseNode *>>> &AddiList,
469 NodeAddr<StmtNode *> &UseSN) {
482 MachineBasicBlock *CurrentMBB = AddMI->
getParent();
483 for (
auto &InstIter : *CurrentMBB) {
485 if (InstIter.getOpcode() == Hexagon::A2_addi) {
486 auto Iter =
llvm::find_if(AddiList, [&InstIter](
const auto &SUPair) {
487 return SUPair.first.Addr->getCode() == &InstIter;
489 if (Iter != AddiList.end()) {
523bool HexagonOptAddrMode::processAddBases(NodeAddr<StmtNode *> AddSN,
524 MachineInstr *AddMI) {
528 LLVM_DEBUG(
dbgs() <<
"\n\t\t[Processing Addi]: " << *AddMI <<
"\n");
531 [](
const MachineInstr *
MI,
532 const DenseSet<MachineInstr *> &ProcessedAddiInsts) ->
bool {
535 LLVM_DEBUG(
dbgs() <<
"\t\t\tAddi already found in ProcessedAddiInsts: "
536 << *
MI <<
"\n\t\t\tSkipping...");
542 if (Processed(AddMI, ProcessedAddiInsts))
544 ProcessedAddiInsts.
insert(AddMI);
551 std::vector<std::pair<NodeAddr<StmtNode *>, NodeAddr<UseNode *>>> AddiList;
555 for (NodeAddr<UseNode *> UA : AddSN.
Addr->members_if(DFG->
IsUse, *DFG)) {
556 RegisterRef URR = UA.
Addr->getRegRef(*DFG);
560 UAReachingDefID = UA.
Addr->getReachingDef();
561 NodeAddr<DefNode *> UADef = DFG->
addr<DefNode *>(UAReachingDefID);
563 LLVM_DEBUG(
dbgs() <<
"\t\t\t Could not find reachingDef. Skipping...\n");
568 NodeAddr<DefNode *> UAReachingDef = DFG->
addr<DefNode *>(UAReachingDefID);
569 NodeAddr<StmtNode *> ReachingDefStmt = UAReachingDef.
Addr->getOwner(*DFG);
573 MachineInstr *ReachingDefInstr = ReachingDefStmt.Addr->getCode();
582 for (NodeAddr<UseNode *> UN : AddiUseList) {
583 NodeAddr<StmtNode *> SN = UN.
Addr->getOwner(*DFG);
584 MachineInstr *
MI = SN.
Addr->getCode();
587 if (
MI->getOpcode() == Hexagon::A2_addi &&
588 !(
MI != AddMI && Processed(
MI, ProcessedAddiInsts))) {
589 AddiList.push_back({SN, UN});
597 if (AddiList.size() <= 1)
600 NodeAddr<StmtNode *> FirstReachedUseSN;
602 if (!findFirstReachedInst(AddMI, AddiList, FirstReachedUseSN))
608 NodeAddr<DefNode *> FirstReachedUseDN =
609 FirstReachedUseSN.
Addr->members_if(DFG->
IsDef, *DFG).front();
611 MachineInstr *FirstReachedMI = FirstReachedUseSN.
Addr->getCode();
612 const MachineOperand FirstReachedMIImmOp = FirstReachedMI->
getOperand(2);
613 if (!FirstReachedMIImmOp.
isImm())
616 for (
auto &
I : AddiList) {
617 NodeAddr<StmtNode *> CurrentInstSN =
I.first;
618 NodeAddr<UseNode *> CurrentInstUN =
I.second;
620 MachineInstr *CurrentMI = CurrentInstSN.
Addr->getCode();
621 MachineOperand &CurrentMIImmOp = CurrentMI->
getOperand(2);
627 if (!CurrentMIImmOp.
isImm())
630 NewOffset = CurrentMIImmOp.
getImm() - FirstReachedMIImmOp.
getImm();
633 if (CurrentMI == FirstReachedMI) {
647 if (!usedInLoadStore(CurrentInstSN, NewOffset))
652 RegisterRef FirstReachedDefRR = FirstReachedUseDN.
Addr->getRegRef(*DFG);
653 NodeAddr<InstrNode *> CurrentAddiIN = CurrentInstUN.
Addr->getOwner(*DFG);
654 NodeAddr<RefNode *> NearestAA =
656 if ((DFG->
IsDef(NearestAA) && NearestAA.
Id != FirstReachedUseDN.
Id) ||
657 (!DFG->
IsDef(NearestAA) &&
658 NearestAA.
Addr->getReachingDef() != FirstReachedUseDN.
Id)) {
660 LLVM_DEBUG(
dbgs() <<
"\t\t\tCould not modify below Addi since the first "
661 "defined Addi register was redefined\n");
665 MachineOperand CurrentMIBaseOp = CurrentMI->
getOperand(1);
672 Changed |= updateAddBases(CurrentMI, FirstReachedMI, NewOffset);
675 CurrentInstUN.
Addr->linkToDef(CurrentInstUN.
Id, FirstReachedUseDN);
681bool HexagonOptAddrMode::updateAddBases(MachineInstr *CurrentMI,
682 MachineInstr *FirstReachedMI,
684 LLVM_DEBUG(
dbgs() <<
"[About to modify the Addi]: " << *CurrentMI <<
"\n");
685 const MachineOperand FirstReachedDef = FirstReachedMI->
getOperand(0);
688 MachineOperand &CurrentMIBaseOp = CurrentMI->
getOperand(1);
689 MachineOperand &CurrentMIImmOp = CurrentMI->
getOperand(2);
691 CurrentMIBaseOp.
setReg(FirstDefRegister);
694 CurrentMIImmOp.
setImm(NewOffset);
705 I->clearRegisterKills(FirstDefRegister,
TRI);
707 ProcessedAddiInsts.
insert(CurrentMI);
711bool HexagonOptAddrMode::processAddUses(NodeAddr<StmtNode *> AddSN,
717 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
718 NodeAddr<UseNode *> UN = *
I;
719 NodeAddr<StmtNode *> SN = UN.
Addr->getOwner(*DFG);
720 MachineInstr *
MI = SN.
Addr->getCode();
721 const MCInstrDesc &MID =
MI->getDesc();
726 MachineOperand BaseOp =
MI->getOperand(getBaseOpPosition(
MI));
731 MachineOperand
OffsetOp =
MI->getOperand(getOffsetOpPosition(
MI));
736 if (!isValidOffset(
MI, newOffset))
749 if (!isSafeToExtLR(AddSN, AddMI, BaseReg, UNodeList))
755 for (NodeAddr<UseNode *> UA : AddSN.
Addr->members_if(DFG->
IsUse, *DFG)) {
756 RegisterRef RR = UA.
Addr->getRegRef(*DFG);
758 LRExtRegRD = UA.
Addr->getReachingDef();
764 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
765 NodeAddr<UseNode *> UseN = *
I;
767 "Found a PhiRef node as a real reached use!!");
769 NodeAddr<StmtNode *> OwnerN = UseN.
Addr->getOwner(*DFG);
770 MachineInstr *
UseMI = OwnerN.
Addr->getCode();
772 <<
">]: " << *
UseMI <<
"\n");
778 NodeAddr<DefNode *> LRExtRegDN = DFG->
addr<DefNode *>(LRExtRegRD);
779 UseN.
Addr->linkToDef(UseN.
Id, LRExtRegDN);
788bool HexagonOptAddrMode::updateAddUses(MachineInstr *AddMI,
789 MachineInstr *
UseMI) {
790 const MachineOperand ImmOp = AddMI->
getOperand(2);
791 const MachineOperand AddRegOp = AddMI->
getOperand(1);
804bool HexagonOptAddrMode::analyzeUses(
unsigned tfrDefR,
806 InstrEvalMap &InstrEvalResult,
808 bool KeepTfr =
false;
809 bool HasRepInstr =
false;
810 InstrEvalResult.clear();
812 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
813 bool CanBeReplaced =
false;
814 NodeAddr<UseNode *> UN = *
I;
815 NodeAddr<StmtNode *> SN = UN.
Addr->getOwner(*DFG);
816 MachineInstr &
MI = *SN.
Addr->getCode();
817 const MCInstrDesc &MID =
MI.getDesc();
819 if (!hasRepForm(
MI, tfrDefR)) {
824 CanBeReplaced =
true;
825 }
else if (
MI.getOpcode() == Hexagon::S2_addasl_rrri) {
831 if (allValidCandidates(SN, AddaslUseList) &&
832 canRemoveAddasl(SN,
MI, AddaslUseList)) {
833 SizeInc += AddaslUseList.size();
835 CanBeReplaced =
true;
845 InstrEvalResult[&
MI] = CanBeReplaced;
846 HasRepInstr |= CanBeReplaced;
856bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
859 MachineBasicBlock *BB = OldMI->
getParent();
865 MachineInstrBuilder MIB;
870 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
881 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
884 const GlobalValue *GV = ImmOp.
getGlobal();
895 }
else if (ImmOpNum == 2) {
898 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
911 for (
unsigned i = OpStart; i < OpEnd; ++i)
917bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
920 unsigned OpStart = 0;
922 MachineBasicBlock *BB = OldMI->
getParent();
926 MachineInstrBuilder MIB;
930 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
940 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
942 const GlobalValue *GV = ImmOp.
getGlobal();
951 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
962 for (
unsigned i = OpStart; i < OpEnd; ++i)
969short HexagonOptAddrMode::getBaseWithLongOffset(
const MachineInstr &
MI)
const {
977bool HexagonOptAddrMode::changeAddAsl(NodeAddr<UseNode *> AddAslUN,
978 MachineInstr *AddAslMI,
979 const MachineOperand &ImmOp,
981 NodeAddr<StmtNode *> SA = AddAslUN.
Addr->getOwner(*DFG);
988 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
989 NodeAddr<UseNode *> UseUN = *
I;
991 "Can't transform this 'AddAsl' instruction!");
993 NodeAddr<StmtNode *> UseIA = UseUN.
Addr->getOwner(*DFG);
995 <<
Print<NodeAddr<InstrNode *>>(UseIA, *DFG) <<
"\n");
996 MachineInstr *
UseMI = UseIA.
Addr->getCode();
998 <<
">]: " << *
UseMI <<
"\n");
1004 short NewOpCode = getBaseWithLongOffset(*
UseMI);
1005 assert(NewOpCode >= 0 &&
"Invalid New opcode\n");
1011 MachineInstrBuilder MIB =
1018 const GlobalValue *GV = ImmOp.
getGlobal();
1025 const GlobalValue *GV = ImmOp.
getGlobal();
1033 for (
unsigned i = OpStart; i < OpEnd; ++i)
1041bool HexagonOptAddrMode::xformUseMI(MachineInstr *TfrMI, MachineInstr *
UseMI,
1042 NodeAddr<UseNode *> UseN,
1043 unsigned UseMOnum) {
1044 const MachineOperand ImmOp = TfrMI->
getOperand(1);
1060bool HexagonOptAddrMode::processBlock(NodeAddr<BlockNode *> BA) {
1063 for (
auto IA : BA.
Addr->members(*DFG)) {
1067 NodeAddr<StmtNode *> SA =
IA;
1068 MachineInstr *
MI = SA.
Addr->getCode();
1069 if ((
MI->getOpcode() != Hexagon::A2_tfrsi ||
1070 !
MI->getOperand(1).isGlobal()) &&
1071 (
MI->getOpcode() != Hexagon::A2_addi ||
1076 <<
"]: " << *
MI <<
"\n\t[InstrNode]: "
1077 <<
Print<NodeAddr<InstrNode *>>(IA, *DFG) <<
'\n');
1079 if (
MI->getOpcode() == Hexagon::A2_addi)
1084 if (!allValidCandidates(SA, UNodeList))
1097 if (
MI->getOpcode() == Hexagon::A2_addi) {
1098 Changed |= processAddUses(SA,
MI, UNodeList);
1104 InstrEvalMap InstrEvalResult;
1108 if (!analyzeUses(DefR, UNodeList, InstrEvalResult, SizeInc))
1113 bool KeepTfr =
false;
1115 LLVM_DEBUG(
dbgs() <<
"\t[Total reached uses] : " << UNodeList.size()
1118 for (
auto I = UNodeList.rbegin(),
E = UNodeList.rend();
I !=
E; ++
I) {
1119 NodeAddr<UseNode *> UseN = *
I;
1121 "Found a PhiRef node as a real reached use!!");
1123 NodeAddr<StmtNode *> OwnerN = UseN.
Addr->getOwner(*DFG);
1124 MachineInstr *
UseMI = OwnerN.
Addr->getCode();
1126 <<
">]: " << *
UseMI <<
"\n");
1130 for (
unsigned j = 0;
j < NumOperands - 1; ++
j) {
1132 if (
op.isReg() &&
op.isUse() && DefR ==
op.getReg())
1141 bool Xformed =
false;
1142 if (UseMOnum >= 0 && InstrEvalResult[
UseMI])
1143 Xformed = xformUseMI(
MI,
UseMI, UseN, UseMOnum);
1145 KeepTfr |= !Xformed;
1161 <<
": too many basic blocks\n");
1169 HII = HST.getInstrInfo();
1170 HRI = HST.getRegisterInfo();
1171 const auto &MDF = getAnalysis<MachineDominanceFrontierWrapperPass>().getMDF();
1172 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1174 DataFlowGraph
G(MF, *HII, *HRI, *MDT, MDF);
1180 Liveness
L(*
MRI, *DFG);
1185 ProcessedAddiInsts.
clear();
1186 NodeAddr<FuncNode *> FA = DFG->
getFunc();
1188 <<
Print<NodeAddr<FuncNode *>>(FA, *DFG) <<
"\n");
1190 for (NodeAddr<BlockNode *> BA : FA.
Addr->members(*DFG))
1194 MI->eraseFromParent();
1215 constexpr unsigned MaxLiveInSweeps = 8;
1216 for (
unsigned Sweep = 0; Sweep != MaxLiveInSweeps; ++Sweep) {
1217 bool AnyChanged =
false;
1218 for (MachineBasicBlock *
MBB : Candidates)
1235 return new HexagonOptAddrMode();
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
static void getAllRealUses(NodeAddr< DefNode * > DA, NodeSet &UNodeSet, Liveness *L, DataFlowGraph *G, bool comprehensive=false)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
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)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
MachineRegisterInfo & MRI
static bool processBlock(MachineBasicBlock &MBB, const SystemZInstrInfo *TII, const TargetRegisterInfo *TRI)
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 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
bool isValidOffset(unsigned Opcode, int Offset, bool Extend=true) 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.
bool isEHPad() const
Returns true if the block is a landing pad.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI bool isEntryBlock() const
Returns true if this is the entry block of the function.
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.
void push_back(const T &Elt)
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.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto post_order(const T &G)
Post-order traversal of a graph.
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 recomputeLiveIns(MachineBasicBlock &MBB)
Convenience function for recomputing live-in's for a MBB.
static bool IsDef(const Node BA)
static bool IsUse(const Node BA)
const PhysicalRegisterInfo & getPRI() const
static bool IsCode(const Node BA)
DenseMap< RegisterId, DefStack > DefStackMap
NodeAddr< T > addr(NodeId N) const
const RefMap & getRealUses(NodeId P) const
LLVM_ABI 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...
DenseMap< RegisterId, NodeRefSet > RefMap
LLVM_ABI std::pair< NodeSet, bool > getAllReachingDefsRec(RegisterRef RefRR, NodeAddr< RefNode * > RefA, NodeSet &Visited, const NodeSet &Defs)
LLVM_ABI NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr< DefNode * > DefA, const RegisterAggr &DefRRs)
LLVM_ABI bool alias(RegisterRef RA, RegisterRef RB) const
constexpr MCRegister asMCReg() const