1 //===--- HexagonOptAddrMode.cpp -------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // This implements a Hexagon-specific pass to optimize addressing mode for
10 // load/store instructions.
11 //===----------------------------------------------------------------------===//
12 
13 #define DEBUG_TYPE "opt-addr-mode"
14 
15 #include "HexagonTargetMachine.h"
16 #include "RDFGraph.h"
17 #include "RDFLiveness.h"
18 
19 #include "llvm/ADT/DenseSet.h"
20 #include "llvm/CodeGen/MachineBasicBlock.h"
21 #include "llvm/CodeGen/MachineDominanceFrontier.h"
22 #include "llvm/CodeGen/MachineDominators.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/Passes.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include "llvm/Target/TargetInstrInfo.h"
31 #include "llvm/Target/TargetMachine.h"
32 #include "llvm/Target/TargetRegisterInfo.h"
33 
34 static cl::opt<int> CodeGrowthLimit("hexagon-amode-growth-limit",
35   cl::Hidden, cl::init(0), cl::desc("Code growth limit for address mode "
36   "optimization"));
37 
38 using namespace llvm;
39 using namespace rdf;
40 
41 namespace llvm {
42   FunctionPass *createHexagonOptAddrMode();
43   void initializeHexagonOptAddrModePass(PassRegistry &);
44 }
45 
46 namespace {
47 class HexagonOptAddrMode : public MachineFunctionPass {
48 public:
49   static char ID;
50   HexagonOptAddrMode()
51       : MachineFunctionPass(ID), HII(0), MDT(0), DFG(0), LV(0) {
52     PassRegistry &R = *PassRegistry::getPassRegistry();
53     initializeHexagonOptAddrModePass(R);
54   }
55   StringRef getPassName() const override {
56     return "Optimize addressing mode of load/store";
57   }
58   void getAnalysisUsage(AnalysisUsage &AU) const override {
59     MachineFunctionPass::getAnalysisUsage(AU);
60     AU.addRequired<MachineDominatorTree>();
61     AU.addRequired<MachineDominanceFrontier>();
62     AU.setPreservesAll();
63   }
64   bool runOnMachineFunction(MachineFunction &MF) override;
65 
66 private:
67   typedef DenseSet<MachineInstr *> MISetType;
68   typedef DenseMap<MachineInstr *, bool> InstrEvalMap;
69   const HexagonInstrInfo *HII;
70   MachineDominatorTree *MDT;
71   DataFlowGraph *DFG;
72   DataFlowGraph::DefStackMap DefM;
73   std::map<RegisterRef, std::map<NodeId, NodeId>> RDefMap;
74   Liveness *LV;
75   MISetType Deleted;
76 
77   bool processBlock(NodeAddr<BlockNode *> BA);
78   bool xformUseMI(MachineInstr *TfrMI, MachineInstr *UseMI,
79                   NodeAddr<UseNode *> UseN, unsigned UseMOnum);
80   bool analyzeUses(unsigned DefR, const NodeList &UNodeList,
81                    InstrEvalMap &InstrEvalResult, short &SizeInc);
82   bool hasRepForm(MachineInstr &MI, unsigned TfrDefR);
83   bool canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN, MachineInstr &MI,
84                        const NodeList &UNodeList);
85   void getAllRealUses(NodeAddr<StmtNode *> SN, NodeList &UNodeList);
86   bool allValidCandidates(NodeAddr<StmtNode *> SA, NodeList &UNodeList);
87   short getBaseWithLongOffset(const MachineInstr &MI) const;
88   void updateMap(NodeAddr<InstrNode *> IA);
89   bool constructDefMap(MachineBasicBlock *B);
90   bool changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
91                    unsigned ImmOpNum);
92   bool changeLoad(MachineInstr *OldMI, MachineOperand ImmOp, unsigned ImmOpNum);
93   bool changeAddAsl(NodeAddr<UseNode *> AddAslUN, MachineInstr *AddAslMI,
94                     const MachineOperand &ImmOp, unsigned ImmOpNum);
95 };
96 }
97 
98 char HexagonOptAddrMode::ID = 0;
99 
100 INITIALIZE_PASS_BEGIN(HexagonOptAddrMode, "opt-amode",
101                       "Optimize addressing mode", false, false)
102 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
103 INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
104 INITIALIZE_PASS_END(HexagonOptAddrMode, "opt-amode", "Optimize addressing mode",
105                     false, false)
106 
107 bool HexagonOptAddrMode::hasRepForm(MachineInstr &MI, unsigned TfrDefR) {
108   const MCInstrDesc &MID = MI.getDesc();
109 
110   if ((!MID.mayStore() && !MID.mayLoad()) || HII->isPredicated(MI))
111     return false;
112 
113   if (MID.mayStore()) {
114     MachineOperand StOp = MI.getOperand(MI.getNumOperands() - 1);
115     if (StOp.isReg() && StOp.getReg() == TfrDefR)
116       return false;
117   }
118 
119   if (HII->getAddrMode(MI) == HexagonII::BaseRegOffset)
120     // Tranform to Absolute plus register offset.
121     return (HII->getBaseWithLongOffset(MI) >= 0);
122   else if (HII->getAddrMode(MI) == HexagonII::BaseImmOffset)
123     // Tranform to absolute addressing mode.
124     return (HII->getAbsoluteForm(MI) >= 0);
125 
126   return false;
127 }
128 
129 // Check if addasl instruction can be removed. This is possible only
130 // if it's feeding to only load/store instructions with base + register
131 // offset as these instruction can be tranformed to use 'absolute plus
132 // shifted register offset'.
133 // ex:
134 // Rs = ##foo
135 // Rx = addasl(Rs, Rt, #2)
136 // Rd = memw(Rx + #28)
137 // Above three instructions can be replaced with Rd = memw(Rt<<#2 + ##foo+28)
138 
139 bool HexagonOptAddrMode::canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN,
140                                          MachineInstr &MI,
141                                          const NodeList &UNodeList) {
142   // check offset size in addasl. if 'offset > 3' return false
143   const MachineOperand &OffsetOp = MI.getOperand(3);
144   if (!OffsetOp.isImm() || OffsetOp.getImm() > 3)
145     return false;
146 
147   unsigned OffsetReg = MI.getOperand(2).getReg();
148   RegisterRef OffsetRR;
149   NodeId OffsetRegRD = 0;
150   for (NodeAddr<UseNode *> UA : AddAslSN.Addr->members_if(DFG->IsUse, *DFG)) {
151     RegisterRef RR = UA.Addr->getRegRef(*DFG);
152     if (OffsetReg == RR.Reg) {
153       OffsetRR = RR;
154       OffsetRegRD = UA.Addr->getReachingDef();
155     }
156   }
157 
158   for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
159     NodeAddr<UseNode *> UA = *I;
160     NodeAddr<InstrNode *> IA = UA.Addr->getOwner(*DFG);
161     if ((UA.Addr->getFlags() & NodeAttrs::PhiRef) ||
162         RDefMap[OffsetRR][IA.Id] != OffsetRegRD)
163       return false;
164 
165     MachineInstr &UseMI = *NodeAddr<StmtNode *>(IA).Addr->getCode();
166     NodeAddr<DefNode *> OffsetRegDN = DFG->addr<DefNode *>(OffsetRegRD);
167     // Reaching Def to an offset register can't be a phi.
168     if ((OffsetRegDN.Addr->getFlags() & NodeAttrs::PhiRef) &&
169         MI.getParent() != UseMI.getParent())
170     return false;
171 
172     const MCInstrDesc &UseMID = UseMI.getDesc();
173     if ((!UseMID.mayLoad() && !UseMID.mayStore()) ||
174         HII->getAddrMode(UseMI) != HexagonII::BaseImmOffset ||
175         getBaseWithLongOffset(UseMI) < 0)
176       return false;
177 
178     // Addasl output can't be a store value.
179     if (UseMID.mayStore() && UseMI.getOperand(2).isReg() &&
180         UseMI.getOperand(2).getReg() == MI.getOperand(0).getReg())
181       return false;
182 
183     for (auto &Mo : UseMI.operands())
184       if (Mo.isFI())
185         return false;
186   }
187   return true;
188 }
189 
190 bool HexagonOptAddrMode::allValidCandidates(NodeAddr<StmtNode *> SA,
191                                             NodeList &UNodeList) {
192   for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
193     NodeAddr<UseNode *> UN = *I;
194     RegisterRef UR = UN.Addr->getRegRef(*DFG);
195     NodeSet Visited, Defs;
196     const auto &ReachingDefs = LV->getAllReachingDefsRec(UR, UN, Visited, Defs);
197     if (ReachingDefs.size() > 1) {
198       DEBUG({
199         dbgs() << "*** Multiple Reaching Defs found!!! ***\n";
200         for (auto DI : ReachingDefs) {
201           NodeAddr<UseNode *> DA = DFG->addr<UseNode *>(DI);
202           NodeAddr<StmtNode *> TempIA = DA.Addr->getOwner(*DFG);
203           dbgs() << "\t\t[Reaching Def]: "
204                  << Print<NodeAddr<InstrNode *>>(TempIA, *DFG) << "\n";
205         }
206       });
207       return false;
208     }
209   }
210   return true;
211 }
212 
213 void HexagonOptAddrMode::getAllRealUses(NodeAddr<StmtNode *> SA,
214                                         NodeList &UNodeList) {
215   for (NodeAddr<DefNode *> DA : SA.Addr->members_if(DFG->IsDef, *DFG)) {
216     DEBUG(dbgs() << "\t\t[DefNode]: " << Print<NodeAddr<DefNode *>>(DA, *DFG)
217                  << "\n");
218     RegisterRef DR = DFG->normalizeRef(DA.Addr->getRegRef(*DFG));
219 
220     auto UseSet = LV->getAllReachedUses(DR, DA);
221 
222     for (auto UI : UseSet) {
223       NodeAddr<UseNode *> UA = DFG->addr<UseNode *>(UI);
224       DEBUG({
225         NodeAddr<StmtNode *> TempIA = UA.Addr->getOwner(*DFG);
226         dbgs() << "\t\t\t[Reached Use]: "
227                << Print<NodeAddr<InstrNode *>>(TempIA, *DFG) << "\n";
228       });
229 
230       if (UA.Addr->getFlags() & NodeAttrs::PhiRef) {
231         NodeAddr<PhiNode *> PA = UA.Addr->getOwner(*DFG);
232         NodeId id = PA.Id;
233         const Liveness::RefMap &phiUse = LV->getRealUses(id);
234         DEBUG(dbgs() << "\t\t\t\tphi real Uses"
235                      << Print<Liveness::RefMap>(phiUse, *DFG) << "\n");
236         if (phiUse.size() > 0) {
237           for (auto I : phiUse) {
238             if (DR.Reg != I.first)
239               continue;
240             auto phiUseSet = I.second;
241             for (auto phiUI : phiUseSet) {
242               NodeAddr<UseNode *> phiUA = DFG->addr<UseNode *>(phiUI.first);
243               UNodeList.push_back(phiUA);
244             }
245           }
246         }
247       } else
248         UNodeList.push_back(UA);
249     }
250   }
251 }
252 
253 bool HexagonOptAddrMode::analyzeUses(unsigned tfrDefR,
254                                      const NodeList &UNodeList,
255                                      InstrEvalMap &InstrEvalResult,
256                                      short &SizeInc) {
257   bool KeepTfr = false;
258   bool HasRepInstr = false;
259   InstrEvalResult.clear();
260 
261   for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
262     bool CanBeReplaced = false;
263     NodeAddr<UseNode *> UN = *I;
264     NodeAddr<StmtNode *> SN = UN.Addr->getOwner(*DFG);
265     MachineInstr &MI = *SN.Addr->getCode();
266     const MCInstrDesc &MID = MI.getDesc();
267     if ((MID.mayLoad() || MID.mayStore())) {
268       if (!hasRepForm(MI, tfrDefR)) {
269         KeepTfr = true;
270         continue;
271       }
272       SizeInc++;
273       CanBeReplaced = true;
274     } else if (MI.getOpcode() == Hexagon::S2_addasl_rrri) {
275       NodeList AddaslUseList;
276 
277       DEBUG(dbgs() << "\nGetting ReachedUses for === " << MI << "\n");
278       getAllRealUses(SN, AddaslUseList);
279       // Process phi nodes.
280       if (allValidCandidates(SN, AddaslUseList) &&
281           canRemoveAddasl(SN, MI, AddaslUseList)) {
282         SizeInc += AddaslUseList.size();
283         SizeInc -= 1; // Reduce size by 1 as addasl itself can be removed.
284         CanBeReplaced = true;
285       } else
286         SizeInc++;
287     } else
288       // Currently, only load/store and addasl are handled.
289       // Some other instructions to consider -
290       // A2_add -> A2_addi
291       // M4_mpyrr_addr -> M4_mpyrr_addi
292       KeepTfr = true;
293 
294     InstrEvalResult[&MI] = CanBeReplaced;
295     HasRepInstr |= CanBeReplaced;
296   }
297 
298   // Reduce total size by 2 if original tfr can be deleted.
299   if (!KeepTfr)
300     SizeInc -= 2;
301 
302   return HasRepInstr;
303 }
304 
305 bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
306                                     unsigned ImmOpNum) {
307   bool Changed = false;
308   MachineBasicBlock *BB = OldMI->getParent();
309   auto UsePos = MachineBasicBlock::iterator(OldMI);
310   MachineBasicBlock::instr_iterator InsertPt = UsePos.getInstrIterator();
311   ++InsertPt;
312   unsigned OpStart;
313   unsigned OpEnd = OldMI->getNumOperands();
314   MachineInstrBuilder MIB;
315 
316   if (ImmOpNum == 1) {
317     if (HII->getAddrMode(*OldMI) == HexagonII::BaseRegOffset) {
318       short NewOpCode = HII->getBaseWithLongOffset(*OldMI);
319       assert(NewOpCode >= 0 && "Invalid New opcode\n");
320       MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
321       MIB.addOperand(OldMI->getOperand(0));
322       MIB.addOperand(OldMI->getOperand(2));
323       MIB.addOperand(OldMI->getOperand(3));
324       MIB.addOperand(ImmOp);
325       OpStart = 4;
326       Changed = true;
327     } else if (HII->getAddrMode(*OldMI) == HexagonII::BaseImmOffset) {
328       short NewOpCode = HII->getAbsoluteForm(*OldMI);
329       assert(NewOpCode >= 0 && "Invalid New opcode\n");
330       MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode))
331                 .addOperand(OldMI->getOperand(0));
332       const GlobalValue *GV = ImmOp.getGlobal();
333       int64_t Offset = ImmOp.getOffset() + OldMI->getOperand(2).getImm();
334 
335       MIB.addGlobalAddress(GV, Offset, ImmOp.getTargetFlags());
336       OpStart = 3;
337       Changed = true;
338     } else
339       Changed = false;
340 
341     DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
342     DEBUG(dbgs() << "[TO]: " << MIB << "\n");
343   } else if (ImmOpNum == 2 && OldMI->getOperand(3).getImm() == 0) {
344     short NewOpCode = HII->xformRegToImmOffset(*OldMI);
345     assert(NewOpCode >= 0 && "Invalid New opcode\n");
346     MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
347     MIB.addOperand(OldMI->getOperand(0));
348     MIB.addOperand(OldMI->getOperand(1));
349     MIB.addOperand(ImmOp);
350     OpStart = 4;
351     Changed = true;
352     DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
353     DEBUG(dbgs() << "[TO]: " << MIB << "\n");
354   }
355 
356   if (Changed)
357     for (unsigned i = OpStart; i < OpEnd; ++i)
358       MIB.addOperand(OldMI->getOperand(i));
359 
360   return Changed;
361 }
362 
363 bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
364                                      unsigned ImmOpNum) {
365   bool Changed = false;
366   unsigned OpStart;
367   unsigned OpEnd = OldMI->getNumOperands();
368   MachineBasicBlock *BB = OldMI->getParent();
369   auto UsePos = MachineBasicBlock::iterator(OldMI);
370   MachineBasicBlock::instr_iterator InsertPt = UsePos.getInstrIterator();
371   ++InsertPt;
372   MachineInstrBuilder MIB;
373   if (ImmOpNum == 0) {
374     if (HII->getAddrMode(*OldMI) == HexagonII::BaseRegOffset) {
375       short NewOpCode = HII->getBaseWithLongOffset(*OldMI);
376       assert(NewOpCode >= 0 && "Invalid New opcode\n");
377       MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
378       MIB.addOperand(OldMI->getOperand(1));
379       MIB.addOperand(OldMI->getOperand(2));
380       MIB.addOperand(ImmOp);
381       MIB.addOperand(OldMI->getOperand(3));
382       OpStart = 4;
383     } else if (HII->getAddrMode(*OldMI) == HexagonII::BaseImmOffset) {
384       short NewOpCode = HII->getAbsoluteForm(*OldMI);
385       assert(NewOpCode >= 0 && "Invalid New opcode\n");
386       MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
387       const GlobalValue *GV = ImmOp.getGlobal();
388       int64_t Offset = ImmOp.getOffset() + OldMI->getOperand(1).getImm();
389       MIB.addGlobalAddress(GV, Offset, ImmOp.getTargetFlags());
390       MIB.addOperand(OldMI->getOperand(2));
391       OpStart = 3;
392     }
393     Changed = true;
394     DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
395     DEBUG(dbgs() << "[TO]: " << MIB << "\n");
396   } else if (ImmOpNum == 1 && OldMI->getOperand(2).getImm() == 0) {
397     short NewOpCode = HII->xformRegToImmOffset(*OldMI);
398     assert(NewOpCode >= 0 && "Invalid New opcode\n");
399     MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
400     MIB.addOperand(OldMI->getOperand(0));
401     MIB.addOperand(ImmOp);
402     MIB.addOperand(OldMI->getOperand(1));
403     OpStart = 2;
404     Changed = true;
405     DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
406     DEBUG(dbgs() << "[TO]: " << MIB << "\n");
407   }
408   if (Changed)
409     for (unsigned i = OpStart; i < OpEnd; ++i)
410       MIB.addOperand(OldMI->getOperand(i));
411 
412   return Changed;
413 }
414 
415 short HexagonOptAddrMode::getBaseWithLongOffset(const MachineInstr &MI) const {
416   if (HII->getAddrMode(MI) == HexagonII::BaseImmOffset) {
417     short TempOpCode = HII->getBaseWithRegOffset(MI);
418     return HII->getBaseWithLongOffset(TempOpCode);
419   } else
420     return HII->getBaseWithLongOffset(MI);
421 }
422 
423 bool HexagonOptAddrMode::changeAddAsl(NodeAddr<UseNode *> AddAslUN,
424                                       MachineInstr *AddAslMI,
425                                       const MachineOperand &ImmOp,
426                                       unsigned ImmOpNum) {
427   NodeAddr<StmtNode *> SA = AddAslUN.Addr->getOwner(*DFG);
428 
429   DEBUG(dbgs() << "Processing addasl :" << *AddAslMI << "\n");
430 
431   NodeList UNodeList;
432   getAllRealUses(SA, UNodeList);
433 
434   for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
435     NodeAddr<UseNode *> UseUN = *I;
436     assert(!(UseUN.Addr->getFlags() & NodeAttrs::PhiRef) &&
437            "Can't transform this 'AddAsl' instruction!");
438 
439     NodeAddr<StmtNode *> UseIA = UseUN.Addr->getOwner(*DFG);
440     DEBUG(dbgs() << "[InstrNode]: " << Print<NodeAddr<InstrNode *>>(UseIA, *DFG)
441                  << "\n");
442     MachineInstr *UseMI = UseIA.Addr->getCode();
443     DEBUG(dbgs() << "[MI <BB#" << UseMI->getParent()->getNumber()
444                  << ">]: " << *UseMI << "\n");
445     const MCInstrDesc &UseMID = UseMI->getDesc();
446     assert(HII->getAddrMode(*UseMI) == HexagonII::BaseImmOffset);
447 
448     auto UsePos = MachineBasicBlock::iterator(UseMI);
449     MachineBasicBlock::instr_iterator InsertPt = UsePos.getInstrIterator();
450     short NewOpCode = getBaseWithLongOffset(*UseMI);
451     assert(NewOpCode >= 0 && "Invalid New opcode\n");
452 
453     unsigned OpStart;
454     unsigned OpEnd = UseMI->getNumOperands();
455 
456     MachineBasicBlock *BB = UseMI->getParent();
457     MachineInstrBuilder MIB =
458         BuildMI(*BB, InsertPt, UseMI->getDebugLoc(), HII->get(NewOpCode));
459     // change mem(Rs + # ) -> mem(Rt << # + ##)
460     if (UseMID.mayLoad()) {
461       MIB.addOperand(UseMI->getOperand(0));
462       MIB.addOperand(AddAslMI->getOperand(2));
463       MIB.addOperand(AddAslMI->getOperand(3));
464       const GlobalValue *GV = ImmOp.getGlobal();
465       MIB.addGlobalAddress(GV, UseMI->getOperand(2).getImm(),
466                            ImmOp.getTargetFlags());
467       OpStart = 3;
468     } else if (UseMID.mayStore()) {
469       MIB.addOperand(AddAslMI->getOperand(2));
470       MIB.addOperand(AddAslMI->getOperand(3));
471       const GlobalValue *GV = ImmOp.getGlobal();
472       MIB.addGlobalAddress(GV, UseMI->getOperand(1).getImm(),
473                            ImmOp.getTargetFlags());
474       MIB.addOperand(UseMI->getOperand(2));
475       OpStart = 3;
476     } else
477       llvm_unreachable("Unhandled instruction");
478 
479     for (unsigned i = OpStart; i < OpEnd; ++i)
480       MIB.addOperand(UseMI->getOperand(i));
481 
482     Deleted.insert(UseMI);
483   }
484 
485   return true;
486 }
487 
488 bool HexagonOptAddrMode::xformUseMI(MachineInstr *TfrMI, MachineInstr *UseMI,
489                                     NodeAddr<UseNode *> UseN,
490                                     unsigned UseMOnum) {
491   const MachineOperand ImmOp = TfrMI->getOperand(1);
492   const MCInstrDesc &MID = UseMI->getDesc();
493   unsigned Changed = false;
494   if (MID.mayLoad())
495     Changed = changeLoad(UseMI, ImmOp, UseMOnum);
496   else if (MID.mayStore())
497     Changed = changeStore(UseMI, ImmOp, UseMOnum);
498   else if (UseMI->getOpcode() == Hexagon::S2_addasl_rrri)
499     Changed = changeAddAsl(UseN, UseMI, ImmOp, UseMOnum);
500 
501   if (Changed)
502     Deleted.insert(UseMI);
503 
504   return Changed;
505 }
506 
507 bool HexagonOptAddrMode::processBlock(NodeAddr<BlockNode *> BA) {
508   bool Changed = false;
509 
510   for (auto IA : BA.Addr->members(*DFG)) {
511     if (!DFG->IsCode<NodeAttrs::Stmt>(IA))
512       continue;
513 
514     NodeAddr<StmtNode *> SA = IA;
515     MachineInstr *MI = SA.Addr->getCode();
516     if (MI->getOpcode() != Hexagon::A2_tfrsi ||
517         !MI->getOperand(1).isGlobal())
518       continue;
519 
520     DEBUG(dbgs() << "[Analyzing A2_tfrsi]: " << *MI << "\n");
521     DEBUG(dbgs() << "\t[InstrNode]: " << Print<NodeAddr<InstrNode *>>(IA, *DFG)
522                  << "\n");
523 
524     NodeList UNodeList;
525     getAllRealUses(SA, UNodeList);
526 
527     if (!allValidCandidates(SA, UNodeList))
528       continue;
529 
530     short SizeInc = 0;
531     unsigned DefR = MI->getOperand(0).getReg();
532     InstrEvalMap InstrEvalResult;
533 
534     // Analyze all uses and calculate increase in size. Perform the optimization
535     // only if there is no increase in size.
536     if (!analyzeUses(DefR, UNodeList, InstrEvalResult, SizeInc))
537       continue;
538     if (SizeInc > CodeGrowthLimit)
539       continue;
540 
541     bool KeepTfr = false;
542 
543     DEBUG(dbgs() << "\t[Total reached uses] : " << UNodeList.size() << "\n");
544     DEBUG(dbgs() << "\t[Processing Reached Uses] ===\n");
545     for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
546       NodeAddr<UseNode *> UseN = *I;
547       assert(!(UseN.Addr->getFlags() & NodeAttrs::PhiRef) &&
548              "Found a PhiRef node as a real reached use!!");
549 
550       NodeAddr<StmtNode *> OwnerN = UseN.Addr->getOwner(*DFG);
551       MachineInstr *UseMI = OwnerN.Addr->getCode();
552       DEBUG(dbgs() << "\t\t[MI <BB#" << UseMI->getParent()->getNumber()
553                    << ">]: " << *UseMI << "\n");
554 
555       int UseMOnum = -1;
556       unsigned NumOperands = UseMI->getNumOperands();
557       for (unsigned j = 0; j < NumOperands - 1; ++j) {
558         const MachineOperand &op = UseMI->getOperand(j);
559         if (op.isReg() && op.isUse() && DefR == op.getReg())
560           UseMOnum = j;
561       }
562       assert(UseMOnum >= 0 && "Invalid reached use!");
563 
564       if (InstrEvalResult[UseMI])
565         // Change UseMI if replacement is possible.
566         Changed |= xformUseMI(MI, UseMI, UseN, UseMOnum);
567       else
568         KeepTfr = true;
569     }
570     if (!KeepTfr)
571       Deleted.insert(MI);
572   }
573   return Changed;
574 }
575 
576 void HexagonOptAddrMode::updateMap(NodeAddr<InstrNode *> IA) {
577   RegisterSet RRs;
578   for (NodeAddr<RefNode *> RA : IA.Addr->members(*DFG))
579     RRs.insert(RA.Addr->getRegRef(*DFG));
580   bool Common = false;
581   for (auto &R : RDefMap) {
582     if (!RRs.count(R.first))
583       continue;
584     Common = true;
585     break;
586   }
587   if (!Common)
588     return;
589 
590   for (auto &R : RDefMap) {
591     auto F = DefM.find(R.first.Reg);
592     if (F == DefM.end() || F->second.empty())
593       continue;
594     R.second[IA.Id] = F->second.top()->Id;
595   }
596 }
597 
598 bool HexagonOptAddrMode::constructDefMap(MachineBasicBlock *B) {
599   bool Changed = false;
600   auto BA = DFG->getFunc().Addr->findBlock(B, *DFG);
601   DFG->markBlock(BA.Id, DefM);
602 
603   for (NodeAddr<InstrNode *> IA : BA.Addr->members(*DFG)) {
604     updateMap(IA);
605     DFG->pushDefs(IA, DefM);
606   }
607 
608   MachineDomTreeNode *N = MDT->getNode(B);
609   for (auto I : *N)
610     Changed |= constructDefMap(I->getBlock());
611 
612   DFG->releaseBlock(BA.Id, DefM);
613   return Changed;
614 }
615 
616 bool HexagonOptAddrMode::runOnMachineFunction(MachineFunction &MF) {
617   bool Changed = false;
618   auto &HST = MF.getSubtarget<HexagonSubtarget>();
619   auto &MRI = MF.getRegInfo();
620   HII = HST.getInstrInfo();
621   const auto &MDF = getAnalysis<MachineDominanceFrontier>();
622   MDT = &getAnalysis<MachineDominatorTree>();
623   const auto &TRI = *MF.getSubtarget().getRegisterInfo();
624   const TargetOperandInfo TOI(*HII);
625 
626   DataFlowGraph G(MF, *HII, TRI, *MDT, MDF, TOI);
627   G.build();
628   DFG = &G;
629 
630   Liveness L(MRI, *DFG);
631   L.computePhiInfo();
632   LV = &L;
633 
634   constructDefMap(&DFG->getMF().front());
635 
636   Deleted.clear();
637   NodeAddr<FuncNode *> FA = DFG->getFunc();
638   DEBUG(dbgs() << "==== [RefMap#]=====:\n "
639                << Print<NodeAddr<FuncNode *>>(FA, *DFG) << "\n");
640 
641   for (NodeAddr<BlockNode *> BA : FA.Addr->members(*DFG))
642     Changed |= processBlock(BA);
643 
644   for (auto MI : Deleted)
645     MI->eraseFromParent();
646 
647   if (Changed) {
648     G.build();
649     L.computeLiveIns();
650     L.resetLiveIns();
651     L.resetKills();
652   }
653 
654   return Changed;
655 }
656 
657 //===----------------------------------------------------------------------===//
658 //                         Public Constructor Functions
659 //===----------------------------------------------------------------------===//
660 
661 FunctionPass *llvm::createHexagonOptAddrMode() {
662   return new HexagonOptAddrMode();
663 }
664