LLVM  14.0.0git
HexagonOptAddrMode.cpp
Go to the documentation of this file.
1 //===- HexagonOptAddrMode.cpp ---------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // This implements a Hexagon-specific pass to optimize addressing mode for
9 // load/store instructions.
10 //===----------------------------------------------------------------------===//
11 
12 #include "HexagonInstrInfo.h"
13 #include "HexagonSubtarget.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/DenseSet.h"
17 #include "llvm/ADT/StringRef.h"
27 #include "llvm/CodeGen/RDFGraph.h"
31 #include "llvm/InitializePasses.h"
32 #include "llvm/MC/MCInstrDesc.h"
33 #include "llvm/Pass.h"
35 #include "llvm/Support/Debug.h"
38 #include <cassert>
39 #include <cstdint>
40 
41 #define DEBUG_TYPE "opt-addr-mode"
42 
43 using namespace llvm;
44 using namespace rdf;
45 
46 static cl::opt<int> CodeGrowthLimit("hexagon-amode-growth-limit",
47  cl::Hidden, cl::init(0), cl::desc("Code growth limit for address mode "
48  "optimization"));
49 
50 namespace llvm {
51 
54 
55 } // end namespace llvm
56 
57 namespace {
58 
59 class HexagonOptAddrMode : public MachineFunctionPass {
60 public:
61  static char ID;
62 
63  HexagonOptAddrMode() : MachineFunctionPass(ID) {}
64 
65  StringRef getPassName() const override {
66  return "Optimize addressing mode of load/store";
67  }
68 
69  void getAnalysisUsage(AnalysisUsage &AU) const override {
73  AU.setPreservesAll();
74  }
75 
76  bool runOnMachineFunction(MachineFunction &MF) override;
77 
78 private:
79  using MISetType = DenseSet<MachineInstr *>;
80  using InstrEvalMap = DenseMap<MachineInstr *, bool>;
81 
82  MachineRegisterInfo *MRI = nullptr;
83  const HexagonInstrInfo *HII = nullptr;
84  const HexagonRegisterInfo *HRI = nullptr;
85  MachineDominatorTree *MDT = nullptr;
86  DataFlowGraph *DFG = nullptr;
88  Liveness *LV = nullptr;
89  MISetType Deleted;
90 
91  bool processBlock(NodeAddr<BlockNode *> BA);
92  bool xformUseMI(MachineInstr *TfrMI, MachineInstr *UseMI,
93  NodeAddr<UseNode *> UseN, unsigned UseMOnum);
94  bool processAddUses(NodeAddr<StmtNode *> AddSN, MachineInstr *AddMI,
95  const NodeList &UNodeList);
96  bool updateAddUses(MachineInstr *AddMI, MachineInstr *UseMI);
97  bool analyzeUses(unsigned DefR, const NodeList &UNodeList,
98  InstrEvalMap &InstrEvalResult, short &SizeInc);
99  bool hasRepForm(MachineInstr &MI, unsigned TfrDefR);
100  bool canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN, MachineInstr &MI,
101  const NodeList &UNodeList);
102  bool isSafeToExtLR(NodeAddr<StmtNode *> SN, MachineInstr *MI,
103  unsigned LRExtReg, const NodeList &UNodeList);
104  void getAllRealUses(NodeAddr<StmtNode *> SN, NodeList &UNodeList);
105  bool allValidCandidates(NodeAddr<StmtNode *> SA, NodeList &UNodeList);
106  short getBaseWithLongOffset(const MachineInstr &MI) const;
107  bool changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
108  unsigned ImmOpNum);
109  bool changeLoad(MachineInstr *OldMI, MachineOperand ImmOp, unsigned ImmOpNum);
110  bool changeAddAsl(NodeAddr<UseNode *> AddAslUN, MachineInstr *AddAslMI,
111  const MachineOperand &ImmOp, unsigned ImmOpNum);
112  bool isValidOffset(MachineInstr *MI, int Offset);
113  unsigned getBaseOpPosition(MachineInstr *MI);
114  unsigned getOffsetOpPosition(MachineInstr *MI);
115 };
116 
117 } // end anonymous namespace
118 
119 char HexagonOptAddrMode::ID = 0;
120 
121 INITIALIZE_PASS_BEGIN(HexagonOptAddrMode, "amode-opt",
122  "Optimize addressing mode", false, false)
125 INITIALIZE_PASS_END(HexagonOptAddrMode, "amode-opt", "Optimize addressing mode",
127 
128 bool HexagonOptAddrMode::hasRepForm(MachineInstr &MI, unsigned TfrDefR) {
129  const MCInstrDesc &MID = MI.getDesc();
130 
131  if ((!MID.mayStore() && !MID.mayLoad()) || HII->isPredicated(MI))
132  return false;
133 
134  if (MID.mayStore()) {
135  MachineOperand StOp = MI.getOperand(MI.getNumOperands() - 1);
136  if (StOp.isReg() && StOp.getReg() == TfrDefR)
137  return false;
138  }
139 
140  if (HII->getAddrMode(MI) == HexagonII::BaseRegOffset)
141  // Tranform to Absolute plus register offset.
142  return (HII->changeAddrMode_rr_ur(MI) >= 0);
143  else if (HII->getAddrMode(MI) == HexagonII::BaseImmOffset)
144  // Tranform to absolute addressing mode.
145  return (HII->changeAddrMode_io_abs(MI) >= 0);
146 
147  return false;
148 }
149 
150 // Check if addasl instruction can be removed. This is possible only
151 // if it's feeding to only load/store instructions with base + register
152 // offset as these instruction can be tranformed to use 'absolute plus
153 // shifted register offset'.
154 // ex:
155 // Rs = ##foo
156 // Rx = addasl(Rs, Rt, #2)
157 // Rd = memw(Rx + #28)
158 // Above three instructions can be replaced with Rd = memw(Rt<<#2 + ##foo+28)
159 
160 bool HexagonOptAddrMode::canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN,
161  MachineInstr &MI,
162  const NodeList &UNodeList) {
163  // check offset size in addasl. if 'offset > 3' return false
164  const MachineOperand &OffsetOp = MI.getOperand(3);
165  if (!OffsetOp.isImm() || OffsetOp.getImm() > 3)
166  return false;
167 
168  Register OffsetReg = MI.getOperand(2).getReg();
169  RegisterRef OffsetRR;
170  NodeId OffsetRegRD = 0;
171  for (NodeAddr<UseNode *> UA : AddAslSN.Addr->members_if(DFG->IsUse, *DFG)) {
172  RegisterRef RR = UA.Addr->getRegRef(*DFG);
173  if (OffsetReg == RR.Reg) {
174  OffsetRR = RR;
175  OffsetRegRD = UA.Addr->getReachingDef();
176  }
177  }
178 
179  for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
180  NodeAddr<UseNode *> UA = *I;
181  NodeAddr<InstrNode *> IA = UA.Addr->getOwner(*DFG);
182  if (UA.Addr->getFlags() & NodeAttrs::PhiRef)
183  return false;
184  NodeAddr<RefNode*> AA = LV->getNearestAliasedRef(OffsetRR, IA);
185  if ((DFG->IsDef(AA) && AA.Id != OffsetRegRD) ||
186  AA.Addr->getReachingDef() != OffsetRegRD)
187  return false;
188 
189  MachineInstr &UseMI = *NodeAddr<StmtNode *>(IA).Addr->getCode();
190  NodeAddr<DefNode *> OffsetRegDN = DFG->addr<DefNode *>(OffsetRegRD);
191  // Reaching Def to an offset register can't be a phi.
192  if ((OffsetRegDN.Addr->getFlags() & NodeAttrs::PhiRef) &&
193  MI.getParent() != UseMI.getParent())
194  return false;
195 
196  const MCInstrDesc &UseMID = UseMI.getDesc();
197  if ((!UseMID.mayLoad() && !UseMID.mayStore()) ||
198  HII->getAddrMode(UseMI) != HexagonII::BaseImmOffset ||
199  getBaseWithLongOffset(UseMI) < 0)
200  return false;
201 
202  // Addasl output can't be a store value.
203  if (UseMID.mayStore() && UseMI.getOperand(2).isReg() &&
204  UseMI.getOperand(2).getReg() == MI.getOperand(0).getReg())
205  return false;
206 
207  for (auto &Mo : UseMI.operands())
208  if (Mo.isFI())
209  return false;
210  }
211  return true;
212 }
213 
214 bool HexagonOptAddrMode::allValidCandidates(NodeAddr<StmtNode *> SA,
215  NodeList &UNodeList) {
216  for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
217  NodeAddr<UseNode *> UN = *I;
218  RegisterRef UR = UN.Addr->getRegRef(*DFG);
219  NodeSet Visited, Defs;
220  const auto &P = LV->getAllReachingDefsRec(UR, UN, Visited, Defs);
221  if (!P.second) {
222  LLVM_DEBUG({
223  dbgs() << "*** Unable to collect all reaching defs for use ***\n"
224  << PrintNode<UseNode*>(UN, *DFG) << '\n'
225  << "The program's complexity may exceed the limits.\n";
226  });
227  return false;
228  }
229  const auto &ReachingDefs = P.first;
230  if (ReachingDefs.size() > 1) {
231  LLVM_DEBUG({
232  dbgs() << "*** Multiple Reaching Defs found!!! ***\n";
233  for (auto DI : ReachingDefs) {
234  NodeAddr<UseNode *> DA = DFG->addr<UseNode *>(DI);
235  NodeAddr<StmtNode *> TempIA = DA.Addr->getOwner(*DFG);
236  dbgs() << "\t\t[Reaching Def]: "
237  << Print<NodeAddr<InstrNode *>>(TempIA, *DFG) << "\n";
238  }
239  });
240  return false;
241  }
242  }
243  return true;
244 }
245 
246 void HexagonOptAddrMode::getAllRealUses(NodeAddr<StmtNode *> SA,
247  NodeList &UNodeList) {
248  for (NodeAddr<DefNode *> DA : SA.Addr->members_if(DFG->IsDef, *DFG)) {
249  LLVM_DEBUG(dbgs() << "\t\t[DefNode]: "
250  << Print<NodeAddr<DefNode *>>(DA, *DFG) << "\n");
251  RegisterRef DR = DA.Addr->getRegRef(*DFG);
252 
253  auto UseSet = LV->getAllReachedUses(DR, DA);
254 
255  for (auto UI : UseSet) {
256  NodeAddr<UseNode *> UA = DFG->addr<UseNode *>(UI);
257  LLVM_DEBUG({
258  NodeAddr<StmtNode *> TempIA = UA.Addr->getOwner(*DFG);
259  dbgs() << "\t\t\t[Reached Use]: "
260  << Print<NodeAddr<InstrNode *>>(TempIA, *DFG) << "\n";
261  });
262 
263  if (UA.Addr->getFlags() & NodeAttrs::PhiRef) {
264  NodeAddr<PhiNode *> PA = UA.Addr->getOwner(*DFG);
265  NodeId id = PA.Id;
266  const Liveness::RefMap &phiUse = LV->getRealUses(id);
267  LLVM_DEBUG(dbgs() << "\t\t\t\tphi real Uses"
268  << Print<Liveness::RefMap>(phiUse, *DFG) << "\n");
269  if (!phiUse.empty()) {
270  for (auto I : phiUse) {
271  if (!DFG->getPRI().alias(RegisterRef(I.first), DR))
272  continue;
273  auto phiUseSet = I.second;
274  for (auto phiUI : phiUseSet) {
275  NodeAddr<UseNode *> phiUA = DFG->addr<UseNode *>(phiUI.first);
276  UNodeList.push_back(phiUA);
277  }
278  }
279  }
280  } else
281  UNodeList.push_back(UA);
282  }
283  }
284 }
285 
286 bool HexagonOptAddrMode::isSafeToExtLR(NodeAddr<StmtNode *> SN,
287  MachineInstr *MI, unsigned LRExtReg,
288  const NodeList &UNodeList) {
289  RegisterRef LRExtRR;
290  NodeId LRExtRegRD = 0;
291  // Iterate through all the UseNodes in SN and find the reaching def
292  // for the LRExtReg.
293  for (NodeAddr<UseNode *> UA : SN.Addr->members_if(DFG->IsUse, *DFG)) {
294  RegisterRef RR = UA.Addr->getRegRef(*DFG);
295  if (LRExtReg == RR.Reg) {
296  LRExtRR = RR;
297  LRExtRegRD = UA.Addr->getReachingDef();
298  }
299  }
300 
301  for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
302  NodeAddr<UseNode *> UA = *I;
303  NodeAddr<InstrNode *> IA = UA.Addr->getOwner(*DFG);
304  // The reaching def of LRExtRR at load/store node should be same as the
305  // one reaching at the SN.
306  if (UA.Addr->getFlags() & NodeAttrs::PhiRef)
307  return false;
308  NodeAddr<RefNode*> AA = LV->getNearestAliasedRef(LRExtRR, IA);
309  if ((DFG->IsDef(AA) && AA.Id != LRExtRegRD) ||
310  AA.Addr->getReachingDef() != LRExtRegRD) {
311  LLVM_DEBUG(
312  dbgs() << "isSafeToExtLR: Returning false; another reaching def\n");
313  return false;
314  }
315 
316  MachineInstr *UseMI = NodeAddr<StmtNode *>(IA).Addr->getCode();
317  NodeAddr<DefNode *> LRExtRegDN = DFG->addr<DefNode *>(LRExtRegRD);
318  // Reaching Def to LRExtReg can't be a phi.
319  if ((LRExtRegDN.Addr->getFlags() & NodeAttrs::PhiRef) &&
320  MI->getParent() != UseMI->getParent())
321  return false;
322  }
323  return true;
324 }
325 
326 bool HexagonOptAddrMode::isValidOffset(MachineInstr *MI, int Offset) {
327  if (HII->isHVXVec(*MI)) {
328  // only HVX vgather instructions handled
329  // TODO: extend the pass to other vector load/store operations
330  switch (MI->getOpcode()) {
331  case Hexagon::V6_vgathermh_pseudo:
332  case Hexagon::V6_vgathermw_pseudo:
333  case Hexagon::V6_vgathermhw_pseudo:
334  case Hexagon::V6_vgathermhq_pseudo:
335  case Hexagon::V6_vgathermwq_pseudo:
336  case Hexagon::V6_vgathermhwq_pseudo:
337  return HII->isValidOffset(MI->getOpcode(), Offset, HRI, false);
338  default:
339  return false;
340  }
341  }
342 
343  if (HII->getAddrMode(*MI) != HexagonII::BaseImmOffset)
344  return false;
345 
346  unsigned AlignMask = 0;
347  switch (HII->getMemAccessSize(*MI)) {
349  AlignMask = 0x7;
350  break;
352  AlignMask = 0x3;
353  break;
355  AlignMask = 0x1;
356  break;
358  AlignMask = 0x0;
359  break;
360  default:
361  return false;
362  }
363 
364  if ((AlignMask & Offset) != 0)
365  return false;
366  return HII->isValidOffset(MI->getOpcode(), Offset, HRI, false);
367 }
368 
369 unsigned HexagonOptAddrMode::getBaseOpPosition(MachineInstr *MI) {
370  const MCInstrDesc &MID = MI->getDesc();
371  switch (MI->getOpcode()) {
372  // vgather pseudos are mayLoad and mayStore
373  // hence need to explicitly specify Base and
374  // Offset operand positions
375  case Hexagon::V6_vgathermh_pseudo:
376  case Hexagon::V6_vgathermw_pseudo:
377  case Hexagon::V6_vgathermhw_pseudo:
378  case Hexagon::V6_vgathermhq_pseudo:
379  case Hexagon::V6_vgathermwq_pseudo:
380  case Hexagon::V6_vgathermhwq_pseudo:
381  return 0;
382  default:
383  return MID.mayLoad() ? 1 : 0;
384  }
385 }
386 
387 unsigned HexagonOptAddrMode::getOffsetOpPosition(MachineInstr *MI) {
388  assert(
389  (HII->getAddrMode(*MI) == HexagonII::BaseImmOffset) &&
390  "Looking for an offset in non-BaseImmOffset addressing mode instruction");
391 
392  const MCInstrDesc &MID = MI->getDesc();
393  switch (MI->getOpcode()) {
394  // vgather pseudos are mayLoad and mayStore
395  // hence need to explicitly specify Base and
396  // Offset operand positions
397  case Hexagon::V6_vgathermh_pseudo:
398  case Hexagon::V6_vgathermw_pseudo:
399  case Hexagon::V6_vgathermhw_pseudo:
400  case Hexagon::V6_vgathermhq_pseudo:
401  case Hexagon::V6_vgathermwq_pseudo:
402  case Hexagon::V6_vgathermhwq_pseudo:
403  return 1;
404  default:
405  return MID.mayLoad() ? 2 : 1;
406  }
407 }
408 
409 bool HexagonOptAddrMode::processAddUses(NodeAddr<StmtNode *> AddSN,
410  MachineInstr *AddMI,
411  const NodeList &UNodeList) {
412 
413  Register AddDefR = AddMI->getOperand(0).getReg();
414  Register BaseReg = AddMI->getOperand(1).getReg();
415  for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
416  NodeAddr<UseNode *> UN = *I;
417  NodeAddr<StmtNode *> SN = UN.Addr->getOwner(*DFG);
418  MachineInstr *MI = SN.Addr->getCode();
419  const MCInstrDesc &MID = MI->getDesc();
420  if ((!MID.mayLoad() && !MID.mayStore()) ||
421  HII->getAddrMode(*MI) != HexagonII::BaseImmOffset)
422  return false;
423 
424  MachineOperand BaseOp = MI->getOperand(getBaseOpPosition(MI));
425 
426  if (!BaseOp.isReg() || BaseOp.getReg() != AddDefR)
427  return false;
428 
429  MachineOperand OffsetOp = MI->getOperand(getOffsetOpPosition(MI));
430  if (!OffsetOp.isImm())
431  return false;
432 
433  int64_t newOffset = OffsetOp.getImm() + AddMI->getOperand(2).getImm();
434  if (!isValidOffset(MI, newOffset))
435  return false;
436 
437  // Since we'll be extending the live range of Rt in the following example,
438  // make sure that is safe. another definition of Rt doesn't exist between 'add'
439  // and load/store instruction.
440  //
441  // Ex: Rx= add(Rt,#10)
442  // memw(Rx+#0) = Rs
443  // will be replaced with => memw(Rt+#10) = Rs
444  if (!isSafeToExtLR(AddSN, AddMI, BaseReg, UNodeList))
445  return false;
446  }
447 
448  NodeId LRExtRegRD = 0;
449  // Iterate through all the UseNodes in SN and find the reaching def
450  // for the LRExtReg.
451  for (NodeAddr<UseNode *> UA : AddSN.Addr->members_if(DFG->IsUse, *DFG)) {
452  RegisterRef RR = UA.Addr->getRegRef(*DFG);
453  if (BaseReg == RR.Reg)
454  LRExtRegRD = UA.Addr->getReachingDef();
455  }
456 
457  // Update all the uses of 'add' with the appropriate base and offset
458  // values.
459  bool Changed = false;
460  for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
461  NodeAddr<UseNode *> UseN = *I;
462  assert(!(UseN.Addr->getFlags() & NodeAttrs::PhiRef) &&
463  "Found a PhiRef node as a real reached use!!");
464 
465  NodeAddr<StmtNode *> OwnerN = UseN.Addr->getOwner(*DFG);
466  MachineInstr *UseMI = OwnerN.Addr->getCode();
467  LLVM_DEBUG(dbgs() << "\t\t[MI <BB#" << UseMI->getParent()->getNumber()
468  << ">]: " << *UseMI << "\n");
469  Changed |= updateAddUses(AddMI, UseMI);
470 
471  // Set the reachingDef for UseNode under consideration
472  // after updating the Add use. This local change is
473  // to avoid rebuilding of the RDF graph after update.
474  NodeAddr<DefNode *> LRExtRegDN = DFG->addr<DefNode *>(LRExtRegRD);
475  UseN.Addr->linkToDef(UseN.Id, LRExtRegDN);
476  }
477 
478  if (Changed)
479  Deleted.insert(AddMI);
480 
481  return Changed;
482 }
483 
484 bool HexagonOptAddrMode::updateAddUses(MachineInstr *AddMI,
485  MachineInstr *UseMI) {
486  const MachineOperand ImmOp = AddMI->getOperand(2);
487  const MachineOperand AddRegOp = AddMI->getOperand(1);
488  Register NewReg = AddRegOp.getReg();
489 
490  MachineOperand &BaseOp = UseMI->getOperand(getBaseOpPosition(UseMI));
491  MachineOperand &OffsetOp = UseMI->getOperand(getOffsetOpPosition(UseMI));
492  BaseOp.setReg(NewReg);
493  BaseOp.setIsUndef(AddRegOp.isUndef());
494  BaseOp.setImplicit(AddRegOp.isImplicit());
495  OffsetOp.setImm(ImmOp.getImm() + OffsetOp.getImm());
496  MRI->clearKillFlags(NewReg);
497 
498  return true;
499 }
500 
501 bool HexagonOptAddrMode::analyzeUses(unsigned tfrDefR,
502  const NodeList &UNodeList,
503  InstrEvalMap &InstrEvalResult,
504  short &SizeInc) {
505  bool KeepTfr = false;
506  bool HasRepInstr = false;
507  InstrEvalResult.clear();
508 
509  for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
510  bool CanBeReplaced = false;
511  NodeAddr<UseNode *> UN = *I;
512  NodeAddr<StmtNode *> SN = UN.Addr->getOwner(*DFG);
513  MachineInstr &MI = *SN.Addr->getCode();
514  const MCInstrDesc &MID = MI.getDesc();
515  if ((MID.mayLoad() || MID.mayStore())) {
516  if (!hasRepForm(MI, tfrDefR)) {
517  KeepTfr = true;
518  continue;
519  }
520  SizeInc++;
521  CanBeReplaced = true;
522  } else if (MI.getOpcode() == Hexagon::S2_addasl_rrri) {
523  NodeList AddaslUseList;
524 
525  LLVM_DEBUG(dbgs() << "\nGetting ReachedUses for === " << MI << "\n");
526  getAllRealUses(SN, AddaslUseList);
527  // Process phi nodes.
528  if (allValidCandidates(SN, AddaslUseList) &&
529  canRemoveAddasl(SN, MI, AddaslUseList)) {
530  SizeInc += AddaslUseList.size();
531  SizeInc -= 1; // Reduce size by 1 as addasl itself can be removed.
532  CanBeReplaced = true;
533  } else
534  SizeInc++;
535  } else
536  // Currently, only load/store and addasl are handled.
537  // Some other instructions to consider -
538  // A2_add -> A2_addi
539  // M4_mpyrr_addr -> M4_mpyrr_addi
540  KeepTfr = true;
541 
542  InstrEvalResult[&MI] = CanBeReplaced;
543  HasRepInstr |= CanBeReplaced;
544  }
545 
546  // Reduce total size by 2 if original tfr can be deleted.
547  if (!KeepTfr)
548  SizeInc -= 2;
549 
550  return HasRepInstr;
551 }
552 
553 bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
554  unsigned ImmOpNum) {
555  bool Changed = false;
556  MachineBasicBlock *BB = OldMI->getParent();
557  auto UsePos = MachineBasicBlock::iterator(OldMI);
558  MachineBasicBlock::instr_iterator InsertPt = UsePos.getInstrIterator();
559  ++InsertPt;
560  unsigned OpStart;
561  unsigned OpEnd = OldMI->getNumOperands();
563 
564  if (ImmOpNum == 1) {
565  if (HII->getAddrMode(*OldMI) == HexagonII::BaseRegOffset) {
566  short NewOpCode = HII->changeAddrMode_rr_ur(*OldMI);
567  assert(NewOpCode >= 0 && "Invalid New opcode\n");
568  MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
569  MIB.add(OldMI->getOperand(0));
570  MIB.add(OldMI->getOperand(2));
571  MIB.add(OldMI->getOperand(3));
572  MIB.add(ImmOp);
573  OpStart = 4;
574  Changed = true;
575  } else if (HII->getAddrMode(*OldMI) == HexagonII::BaseImmOffset &&
576  OldMI->getOperand(2).isImm()) {
577  short NewOpCode = HII->changeAddrMode_io_abs(*OldMI);
578  assert(NewOpCode >= 0 && "Invalid New opcode\n");
579  MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode))
580  .add(OldMI->getOperand(0));
581  const GlobalValue *GV = ImmOp.getGlobal();
582  int64_t Offset = ImmOp.getOffset() + OldMI->getOperand(2).getImm();
583 
584  MIB.addGlobalAddress(GV, Offset, ImmOp.getTargetFlags());
585  OpStart = 3;
586  Changed = true;
587  } else
588  Changed = false;
589 
590  LLVM_DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
591  LLVM_DEBUG(dbgs() << "[TO]: " << *MIB << "\n");
592  } else if (ImmOpNum == 2) {
593  if (OldMI->getOperand(3).isImm() && OldMI->getOperand(3).getImm() == 0) {
594  short NewOpCode = HII->changeAddrMode_rr_io(*OldMI);
595  assert(NewOpCode >= 0 && "Invalid New opcode\n");
596  MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
597  MIB.add(OldMI->getOperand(0));
598  MIB.add(OldMI->getOperand(1));
599  MIB.add(ImmOp);
600  OpStart = 4;
601  Changed = true;
602  LLVM_DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
603  LLVM_DEBUG(dbgs() << "[TO]: " << *MIB << "\n");
604  }
605  }
606 
607  if (Changed)
608  for (unsigned i = OpStart; i < OpEnd; ++i)
609  MIB.add(OldMI->getOperand(i));
610 
611  return Changed;
612 }
613 
614 bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
615  unsigned ImmOpNum) {
616  bool Changed = false;
617  unsigned OpStart = 0;
618  unsigned OpEnd = OldMI->getNumOperands();
619  MachineBasicBlock *BB = OldMI->getParent();
620  auto UsePos = MachineBasicBlock::iterator(OldMI);
621  MachineBasicBlock::instr_iterator InsertPt = UsePos.getInstrIterator();
622  ++InsertPt;
624  if (ImmOpNum == 0) {
625  if (HII->getAddrMode(*OldMI) == HexagonII::BaseRegOffset) {
626  short NewOpCode = HII->changeAddrMode_rr_ur(*OldMI);
627  assert(NewOpCode >= 0 && "Invalid New opcode\n");
628  MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
629  MIB.add(OldMI->getOperand(1));
630  MIB.add(OldMI->getOperand(2));
631  MIB.add(ImmOp);
632  MIB.add(OldMI->getOperand(3));
633  OpStart = 4;
634  Changed = true;
635  } else if (HII->getAddrMode(*OldMI) == HexagonII::BaseImmOffset) {
636  short NewOpCode = HII->changeAddrMode_io_abs(*OldMI);
637  assert(NewOpCode >= 0 && "Invalid New opcode\n");
638  MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
639  const GlobalValue *GV = ImmOp.getGlobal();
640  int64_t Offset = ImmOp.getOffset() + OldMI->getOperand(1).getImm();
641  MIB.addGlobalAddress(GV, Offset, ImmOp.getTargetFlags());
642  MIB.add(OldMI->getOperand(2));
643  OpStart = 3;
644  Changed = true;
645  }
646  } else if (ImmOpNum == 1 && OldMI->getOperand(2).getImm() == 0) {
647  short NewOpCode = HII->changeAddrMode_rr_io(*OldMI);
648  assert(NewOpCode >= 0 && "Invalid New opcode\n");
649  MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
650  MIB.add(OldMI->getOperand(0));
651  MIB.add(ImmOp);
652  OpStart = 3;
653  Changed = true;
654  }
655  if (Changed) {
656  LLVM_DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
657  LLVM_DEBUG(dbgs() << "[TO]: " << *MIB << "\n");
658 
659  for (unsigned i = OpStart; i < OpEnd; ++i)
660  MIB.add(OldMI->getOperand(i));
661  }
662 
663  return Changed;
664 }
665 
666 short HexagonOptAddrMode::getBaseWithLongOffset(const MachineInstr &MI) const {
667  if (HII->getAddrMode(MI) == HexagonII::BaseImmOffset) {
668  short TempOpCode = HII->changeAddrMode_io_rr(MI);
669  return HII->changeAddrMode_rr_ur(TempOpCode);
670  }
671  return HII->changeAddrMode_rr_ur(MI);
672 }
673 
674 bool HexagonOptAddrMode::changeAddAsl(NodeAddr<UseNode *> AddAslUN,
675  MachineInstr *AddAslMI,
676  const MachineOperand &ImmOp,
677  unsigned ImmOpNum) {
678  NodeAddr<StmtNode *> SA = AddAslUN.Addr->getOwner(*DFG);
679 
680  LLVM_DEBUG(dbgs() << "Processing addasl :" << *AddAslMI << "\n");
681 
682  NodeList UNodeList;
683  getAllRealUses(SA, UNodeList);
684 
685  for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
686  NodeAddr<UseNode *> UseUN = *I;
687  assert(!(UseUN.Addr->getFlags() & NodeAttrs::PhiRef) &&
688  "Can't transform this 'AddAsl' instruction!");
689 
690  NodeAddr<StmtNode *> UseIA = UseUN.Addr->getOwner(*DFG);
691  LLVM_DEBUG(dbgs() << "[InstrNode]: "
692  << Print<NodeAddr<InstrNode *>>(UseIA, *DFG) << "\n");
693  MachineInstr *UseMI = UseIA.Addr->getCode();
694  LLVM_DEBUG(dbgs() << "[MI <" << printMBBReference(*UseMI->getParent())
695  << ">]: " << *UseMI << "\n");
696  const MCInstrDesc &UseMID = UseMI->getDesc();
697  assert(HII->getAddrMode(*UseMI) == HexagonII::BaseImmOffset);
698 
699  auto UsePos = MachineBasicBlock::iterator(UseMI);
700  MachineBasicBlock::instr_iterator InsertPt = UsePos.getInstrIterator();
701  short NewOpCode = getBaseWithLongOffset(*UseMI);
702  assert(NewOpCode >= 0 && "Invalid New opcode\n");
703 
704  unsigned OpStart;
705  unsigned OpEnd = UseMI->getNumOperands();
706 
708  MachineInstrBuilder MIB =
709  BuildMI(*BB, InsertPt, UseMI->getDebugLoc(), HII->get(NewOpCode));
710  // change mem(Rs + # ) -> mem(Rt << # + ##)
711  if (UseMID.mayLoad()) {
712  MIB.add(UseMI->getOperand(0));
713  MIB.add(AddAslMI->getOperand(2));
714  MIB.add(AddAslMI->getOperand(3));
715  const GlobalValue *GV = ImmOp.getGlobal();
716  MIB.addGlobalAddress(GV, UseMI->getOperand(2).getImm()+ImmOp.getOffset(),
717  ImmOp.getTargetFlags());
718  OpStart = 3;
719  } else if (UseMID.mayStore()) {
720  MIB.add(AddAslMI->getOperand(2));
721  MIB.add(AddAslMI->getOperand(3));
722  const GlobalValue *GV = ImmOp.getGlobal();
723  MIB.addGlobalAddress(GV, UseMI->getOperand(1).getImm()+ImmOp.getOffset(),
724  ImmOp.getTargetFlags());
725  MIB.add(UseMI->getOperand(2));
726  OpStart = 3;
727  } else
728  llvm_unreachable("Unhandled instruction");
729 
730  for (unsigned i = OpStart; i < OpEnd; ++i)
731  MIB.add(UseMI->getOperand(i));
732 
733  Deleted.insert(UseMI);
734  }
735 
736  return true;
737 }
738 
739 bool HexagonOptAddrMode::xformUseMI(MachineInstr *TfrMI, MachineInstr *UseMI,
740  NodeAddr<UseNode *> UseN,
741  unsigned UseMOnum) {
742  const MachineOperand ImmOp = TfrMI->getOperand(1);
743  const MCInstrDesc &MID = UseMI->getDesc();
744  unsigned Changed = false;
745  if (MID.mayLoad())
746  Changed = changeLoad(UseMI, ImmOp, UseMOnum);
747  else if (MID.mayStore())
748  Changed = changeStore(UseMI, ImmOp, UseMOnum);
749  else if (UseMI->getOpcode() == Hexagon::S2_addasl_rrri)
750  Changed = changeAddAsl(UseN, UseMI, ImmOp, UseMOnum);
751 
752  if (Changed)
753  Deleted.insert(UseMI);
754 
755  return Changed;
756 }
757 
758 bool HexagonOptAddrMode::processBlock(NodeAddr<BlockNode *> BA) {
759  bool Changed = false;
760 
761  for (auto IA : BA.Addr->members(*DFG)) {
762  if (!DFG->IsCode<NodeAttrs::Stmt>(IA))
763  continue;
764 
765  NodeAddr<StmtNode *> SA = IA;
766  MachineInstr *MI = SA.Addr->getCode();
767  if ((MI->getOpcode() != Hexagon::A2_tfrsi ||
768  !MI->getOperand(1).isGlobal()) &&
769  (MI->getOpcode() != Hexagon::A2_addi ||
770  !MI->getOperand(2).isImm() || HII->isConstExtended(*MI)))
771  continue;
772 
773  LLVM_DEBUG(dbgs() << "[Analyzing " << HII->getName(MI->getOpcode())
774  << "]: " << *MI << "\n\t[InstrNode]: "
775  << Print<NodeAddr<InstrNode *>>(IA, *DFG) << '\n');
776 
777  NodeList UNodeList;
778  getAllRealUses(SA, UNodeList);
779 
780  if (!allValidCandidates(SA, UNodeList))
781  continue;
782 
783  // Analyze all uses of 'add'. If the output of 'add' is used as an address
784  // in the base+immediate addressing mode load/store instructions, see if
785  // they can be updated to use the immediate value as an offet. Thus,
786  // providing us the opportunity to eliminate 'add'.
787  // Ex: Rx= add(Rt,#12)
788  // memw(Rx+#0) = Rs
789  // This can be replaced with memw(Rt+#12) = Rs
790  //
791  // This transformation is only performed if all uses can be updated and
792  // the offset isn't required to be constant extended.
793  if (MI->getOpcode() == Hexagon::A2_addi) {
794  Changed |= processAddUses(SA, MI, UNodeList);
795  continue;
796  }
797 
798  short SizeInc = 0;
799  Register DefR = MI->getOperand(0).getReg();
800  InstrEvalMap InstrEvalResult;
801 
802  // Analyze all uses and calculate increase in size. Perform the optimization
803  // only if there is no increase in size.
804  if (!analyzeUses(DefR, UNodeList, InstrEvalResult, SizeInc))
805  continue;
806  if (SizeInc > CodeGrowthLimit)
807  continue;
808 
809  bool KeepTfr = false;
810 
811  LLVM_DEBUG(dbgs() << "\t[Total reached uses] : " << UNodeList.size()
812  << "\n");
813  LLVM_DEBUG(dbgs() << "\t[Processing Reached Uses] ===\n");
814  for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
815  NodeAddr<UseNode *> UseN = *I;
816  assert(!(UseN.Addr->getFlags() & NodeAttrs::PhiRef) &&
817  "Found a PhiRef node as a real reached use!!");
818 
819  NodeAddr<StmtNode *> OwnerN = UseN.Addr->getOwner(*DFG);
820  MachineInstr *UseMI = OwnerN.Addr->getCode();
821  LLVM_DEBUG(dbgs() << "\t\t[MI <" << printMBBReference(*UseMI->getParent())
822  << ">]: " << *UseMI << "\n");
823 
824  int UseMOnum = -1;
825  unsigned NumOperands = UseMI->getNumOperands();
826  for (unsigned j = 0; j < NumOperands - 1; ++j) {
827  const MachineOperand &op = UseMI->getOperand(j);
828  if (op.isReg() && op.isUse() && DefR == op.getReg())
829  UseMOnum = j;
830  }
831  // It is possible that the register will not be found in any operand.
832  // This could happen, for example, when DefR = R4, but the used
833  // register is D2.
834 
835  // Change UseMI if replacement is possible. If any replacement failed,
836  // or wasn't attempted, make sure to keep the TFR.
837  bool Xformed = false;
838  if (UseMOnum >= 0 && InstrEvalResult[UseMI])
839  Xformed = xformUseMI(MI, UseMI, UseN, UseMOnum);
840  Changed |= Xformed;
841  KeepTfr |= !Xformed;
842  }
843  if (!KeepTfr)
844  Deleted.insert(MI);
845  }
846  return Changed;
847 }
848 
849 bool HexagonOptAddrMode::runOnMachineFunction(MachineFunction &MF) {
850  if (skipFunction(MF.getFunction()))
851  return false;
852 
853  bool Changed = false;
854  auto &HST = MF.getSubtarget<HexagonSubtarget>();
855  MRI = &MF.getRegInfo();
856  HII = HST.getInstrInfo();
857  HRI = HST.getRegisterInfo();
858  const auto &MDF = getAnalysis<MachineDominanceFrontier>();
859  MDT = &getAnalysis<MachineDominatorTree>();
860  const TargetOperandInfo TOI(*HII);
861 
862  DataFlowGraph G(MF, *HII, *HRI, *MDT, MDF, TOI);
863  // Need to keep dead phis because we can propagate uses of registers into
864  // nodes dominated by those would-be phis.
866  DFG = &G;
867 
868  Liveness L(*MRI, *DFG);
869  L.computePhiInfo();
870  LV = &L;
871 
872  Deleted.clear();
873  NodeAddr<FuncNode *> FA = DFG->getFunc();
874  LLVM_DEBUG(dbgs() << "==== [RefMap#]=====:\n "
875  << Print<NodeAddr<FuncNode *>>(FA, *DFG) << "\n");
876 
877  for (NodeAddr<BlockNode *> BA : FA.Addr->members(*DFG))
878  Changed |= processBlock(BA);
879 
880  for (auto MI : Deleted)
881  MI->eraseFromParent();
882 
883  if (Changed) {
884  G.build();
885  L.computeLiveIns();
886  L.resetLiveIns();
887  L.resetKills();
888  }
889 
890  return Changed;
891 }
892 
893 //===----------------------------------------------------------------------===//
894 // Public Constructor Functions
895 //===----------------------------------------------------------------------===//
896 
898  return new HexagonOptAddrMode();
899 }
llvm::rdf::Print
Definition: RDFGraph.h:924
i
i
Definition: README.txt:29
mode
amode Optimize addressing mode
Definition: HexagonOptAddrMode.cpp:125
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(HexagonOptAddrMode, "amode-opt", "Optimize addressing mode", false, false) INITIALIZE_PASS_END(HexagonOptAddrMode
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
MachineInstr.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::rdf::RegisterRef::Reg
RegisterId Reg
Definition: RDFRegisters.h:72
llvm::rdf::NodeAttrs::PhiRef
@ PhiRef
Definition: RDFGraph.h:286
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:102
llvm::rdf::CodeNode::members_if
NodeList members_if(Predicate P, const DataFlowGraph &G) const
Definition: RDFGraph.h:909
MCInstrDesc.h
llvm::MachineOperand::getGlobal
const GlobalValue * getGlobal() const
Definition: MachineOperand.h:563
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
Pass.h
llvm::rdf::UseNode::linkToDef
void linkToDef(NodeId Self, NodeAddr< DefNode * > DA)
Definition: RDFGraph.cpp:453
llvm::rdf::Liveness::RefMap
std::unordered_map< RegisterId, NodeRefSet > RefMap
Definition: RDFLiveness.h:77
op
#define op(i)
llvm::printMBBReference
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Definition: MachineBasicBlock.cpp:119
HexagonSubtarget.h
ErrorHandling.h
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
MachineBasicBlock.h
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::MachineOperand::setImm
void setImm(int64_t immVal)
Definition: MachineOperand.h:655
llvm::MachineInstr::getDesc
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:486
DenseMap.h
llvm::initializeHexagonOptAddrModePass
void initializeHexagonOptAddrModePass(PassRegistry &)
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:80
llvm::rdf::PrintNode
Definition: RDFGraph.h:932
llvm::MachineOperand::getOffset
int64_t getOffset() const
Return the offset from the symbol in this operand.
Definition: MachineOperand.h:600
RDFRegisters.h
llvm::rdf::RegisterRef
Definition: RDFRegisters.h:71
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
HexagonBaseInfo.h
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1233
MachineRegisterInfo.h
llvm::rdf::NodeBase::getFlags
uint16_t getFlags() const
Definition: RDFGraph.h:456
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
LoopDeletionResult::Deleted
@ Deleted
CommandLine.h
RDFLiveness.h
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:651
llvm::MachineOperand::isImplicit
bool isImplicit() const
Definition: MachineOperand.h:380
llvm::rdf::NodeAddr
Definition: RDFGraph.h:334
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
llvm::HexagonII::ByteAccess
@ ByteAccess
Definition: HexagonBaseInfo.h:42
llvm::rdf::RefNode::getRegRef
RegisterRef getRegRef(const DataFlowGraph &G) const
Definition: RDFGraph.cpp:408
llvm::rdf::NodeAttrs::Stmt
@ Stmt
Definition: RDFGraph.h:278
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:499
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
DenseSet.h
false
Definition: StackSlotColoring.cpp:142
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:195
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
NodeList
Definition: MicrosoftDemangle.cpp:37
llvm::rdf::NodeId
uint32_t NodeId
Definition: RDFGraph.h:260
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
llvm::HexagonII::HalfWordAccess
@ HalfWordAccess
Definition: HexagonBaseInfo.h:43
HexagonInstrInfo.h
llvm::rdf::NodeAddr::Addr
T Addr
Definition: RDFGraph.h:351
llvm::NodeSet
A NodeSet contains a set of SUnit DAG nodes with additional information that assigns a priority to th...
Definition: MachinePipeliner.h:311
llvm::MachineInstrBuilder::getReg
Register getReg(unsigned Idx) const
Get the register for the operand index.
Definition: MachineInstrBuilder.h:94
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
llvm::MachineRegisterInfo::clearKillFlags
void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
Definition: MachineRegisterInfo.cpp:429
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:641
llvm::MCInstrDesc::mayLoad
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:429
llvm::cl::opt
Definition: CommandLine.h:1432
llvm::MachineInstr::getDebugLoc
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:418
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::MachineOperand::isUndef
bool isUndef() const
Definition: MachineOperand.h:395
llvm::MachineOperand::getTargetFlags
unsigned getTargetFlags() const
Definition: MachineOperand.h:221
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
llvm::MachineDominanceFrontier
Definition: MachineDominanceFrontier.h:20
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::rdf::CodeNode::members
NodeList members(const DataFlowGraph &G) const
Definition: RDFGraph.cpp:527
CodeGrowthLimit
static cl::opt< int > CodeGrowthLimit("hexagon-amode-growth-limit", cl::Hidden, cl::init(0), cl::desc("Code growth limit for address mode " "optimization"))
llvm::rdf::UseNode
Definition: RDFGraph.h:575
llvm::DenseMap
Definition: DenseMap.h:714
llvm::rdf::DataFlowGraph
Definition: RDFGraph.h:644
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:441
MachineFunctionPass.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::HexagonII::BaseRegOffset
@ BaseRegOffset
Definition: HexagonBaseInfo.h:36
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::HexagonII::BaseImmOffset
@ BaseImmOffset
Definition: HexagonBaseInfo.h:34
llvm::HexagonII::DoubleWordAccess
@ DoubleWordAccess
Definition: HexagonBaseInfo.h:45
llvm::MachineFunction
Definition: MachineFunction.h:241
llvm::MCInstrDesc::mayStore
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:435
llvm::HexagonInstrInfo
Definition: HexagonInstrInfo.h:38
llvm::MachineBasicBlock::iterator
MachineInstrBundleIterator< MachineInstr > iterator
Definition: MachineBasicBlock.h:237
llvm::MachineBasicBlock::getNumber
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
Definition: MachineBasicBlock.h:1073
opt
amode opt
Definition: HexagonOptAddrMode.cpp:125
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:489
RDFGraph.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::createHexagonOptAddrMode
FunctionPass * createHexagonOptAddrMode()
Definition: HexagonOptAddrMode.cpp:897
llvm::MachineOperand::setIsUndef
void setIsUndef(bool Val=true)
Definition: MachineOperand.h:511
TargetSubtargetInfo.h
llvm::MachineInstr::getParent
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:286
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
j
return j(j<< 16)
llvm::rdf::DataFlowGraph::build
void build(unsigned Options=BuildOptions::None)
Definition: RDFGraph.cpp:868
llvm::rdf::TargetOperandInfo
Definition: RDFGraph.h:414
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:607
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
MachineDominanceFrontier.h
llvm::rdf::DefNode
Definition: RDFGraph.h:558
llvm::rdf::RefNode::getOwner
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
Definition: RDFGraph.cpp:434
llvm::MachineOperand::setImplicit
void setImplicit(bool Val=true)
Definition: MachineOperand.h:495
llvm::MachineOperand::isImm
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Definition: MachineOperand.h:323
llvm::rdf::StmtNode::getCode
MachineInstr * getCode() const
Definition: RDFGraph.h:621
llvm::MachineInstrBuilder::addGlobalAddress
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:177
llvm::rdf::NodeAddr::Id
NodeId Id
Definition: RDFGraph.h:352
llvm::rdf::RefNode::getReachingDef
NodeId getReachingDef() const
Definition: RDFGraph.h:528
llvm::rdf::Liveness
Definition: RDFLiveness.h:59
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
llvm::MachineOperand::setReg
void setReg(Register Reg)
Change the register this operand corresponds to.
Definition: MachineOperand.cpp:55
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:492
llvm::rdf::BuildOptions::KeepDeadPhis
@ KeepDeadPhis
Definition: RDFGraph.h:330
llvm::HexagonSubtarget
Definition: HexagonSubtarget.h:43
llvm::HexagonII::WordAccess
@ WordAccess
Definition: HexagonBaseInfo.h:44
MachineOperand.h
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::HexagonRegisterInfo
Definition: HexagonRegisterInfo.h:29
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::cl::desc
Definition: CommandLine.h:412
llvm::M68kBeads::DA
@ DA
Definition: M68kBaseInfo.h:59
raw_ostream.h
llvm::MachineDominatorTree
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Definition: MachineDominators.h:46
MachineFunction.h
InitializePasses.h
Debug.h
llvm::rdf::DataFlowGraph::DefStackMap
std::unordered_map< RegisterId, DefStack > DefStackMap
Definition: RDFGraph.h:733
MachineDominators.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38