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