diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp | 152 |
1 files changed, 59 insertions, 93 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp index 89db467..374ffa3 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp @@ -10,8 +10,6 @@ // load/store instructions. //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "opt-addr-mode" - #include "HexagonInstrInfo.h" #include "HexagonSubtarget.h" #include "MCTargetDesc/HexagonBaseInfo.h" @@ -35,7 +33,8 @@ #include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstdint> -#include <map> + +#define DEBUG_TYPE "opt-addr-mode" static cl::opt<int> CodeGrowthLimit("hexagon-amode-growth-limit", cl::Hidden, cl::init(0), cl::desc("Code growth limit for address mode " @@ -45,10 +44,8 @@ using namespace llvm; using namespace rdf; namespace llvm { - FunctionPass *createHexagonOptAddrMode(); - void initializeHexagonOptAddrModePass(PassRegistry &); - + void initializeHexagonOptAddrModePass(PassRegistry&); } // end namespace llvm namespace { @@ -59,10 +56,7 @@ public: HexagonOptAddrMode() : MachineFunctionPass(ID), HII(nullptr), MDT(nullptr), DFG(nullptr), - LV(nullptr) { - PassRegistry &R = *PassRegistry::getPassRegistry(); - initializeHexagonOptAddrModePass(R); - } + LV(nullptr) {} StringRef getPassName() const override { return "Optimize addressing mode of load/store"; @@ -84,7 +78,6 @@ private: MachineDominatorTree *MDT; DataFlowGraph *DFG; DataFlowGraph::DefStackMap DefM; - std::map<RegisterRef, std::map<NodeId, NodeId>> RDefMap; Liveness *LV; MISetType Deleted; @@ -99,8 +92,6 @@ private: void getAllRealUses(NodeAddr<StmtNode *> SN, NodeList &UNodeList); bool allValidCandidates(NodeAddr<StmtNode *> SA, NodeList &UNodeList); short getBaseWithLongOffset(const MachineInstr &MI) const; - void updateMap(NodeAddr<InstrNode *> IA); - bool constructDefMap(MachineBasicBlock *B); bool changeStore(MachineInstr *OldMI, MachineOperand ImmOp, unsigned ImmOpNum); bool changeLoad(MachineInstr *OldMI, MachineOperand ImmOp, unsigned ImmOpNum); @@ -112,11 +103,11 @@ private: char HexagonOptAddrMode::ID = 0; -INITIALIZE_PASS_BEGIN(HexagonOptAddrMode, "opt-amode", +INITIALIZE_PASS_BEGIN(HexagonOptAddrMode, "amode-opt", "Optimize addressing mode", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier) -INITIALIZE_PASS_END(HexagonOptAddrMode, "opt-amode", "Optimize addressing mode", +INITIALIZE_PASS_END(HexagonOptAddrMode, "amode-opt", "Optimize addressing mode", false, false) bool HexagonOptAddrMode::hasRepForm(MachineInstr &MI, unsigned TfrDefR) { @@ -173,8 +164,11 @@ bool HexagonOptAddrMode::canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN, for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) { NodeAddr<UseNode *> UA = *I; NodeAddr<InstrNode *> IA = UA.Addr->getOwner(*DFG); - if ((UA.Addr->getFlags() & NodeAttrs::PhiRef) || - RDefMap[OffsetRR][IA.Id] != OffsetRegRD) + if (UA.Addr->getFlags() & NodeAttrs::PhiRef) + return false; + NodeAddr<RefNode*> AA = LV->getNearestAliasedRef(OffsetRR, IA); + if ((DFG->IsDef(AA) && AA.Id != OffsetRegRD) || + AA.Addr->getReachingDef() != OffsetRegRD) return false; MachineInstr &UseMI = *NodeAddr<StmtNode *>(IA).Addr->getCode(); @@ -208,7 +202,16 @@ bool HexagonOptAddrMode::allValidCandidates(NodeAddr<StmtNode *> SA, NodeAddr<UseNode *> UN = *I; RegisterRef UR = UN.Addr->getRegRef(*DFG); NodeSet Visited, Defs; - const auto &ReachingDefs = LV->getAllReachingDefsRec(UR, UN, Visited, Defs); + const auto &P = LV->getAllReachingDefsRec(UR, UN, Visited, Defs); + if (!P.second) { + DEBUG({ + dbgs() << "*** Unable to collect all reaching defs for use ***\n" + << PrintNode<UseNode*>(UN, *DFG) << '\n' + << "The program's complexity may exceed the limits.\n"; + }); + return false; + } + const auto &ReachingDefs = P.first; if (ReachingDefs.size() > 1) { DEBUG({ dbgs() << "*** Multiple Reaching Defs found!!! ***\n"; @@ -230,7 +233,7 @@ void HexagonOptAddrMode::getAllRealUses(NodeAddr<StmtNode *> SA, for (NodeAddr<DefNode *> DA : SA.Addr->members_if(DFG->IsDef, *DFG)) { DEBUG(dbgs() << "\t\t[DefNode]: " << Print<NodeAddr<DefNode *>>(DA, *DFG) << "\n"); - RegisterRef DR = DFG->normalizeRef(DA.Addr->getRegRef(*DFG)); + RegisterRef DR = DFG->getPRI().normalize(DA.Addr->getRegRef(*DFG)); auto UseSet = LV->getAllReachedUses(DR, DA); @@ -250,7 +253,7 @@ void HexagonOptAddrMode::getAllRealUses(NodeAddr<StmtNode *> SA, << Print<Liveness::RefMap>(phiUse, *DFG) << "\n"); if (!phiUse.empty()) { for (auto I : phiUse) { - if (DR.Reg != I.first) + if (!DFG->getPRI().alias(RegisterRef(I.first), DR)) continue; auto phiUseSet = I.second; for (auto phiUI : phiUseSet) { @@ -333,17 +336,17 @@ bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp, short NewOpCode = HII->getBaseWithLongOffset(*OldMI); assert(NewOpCode >= 0 && "Invalid New opcode\n"); MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode)); - MIB.addOperand(OldMI->getOperand(0)); - MIB.addOperand(OldMI->getOperand(2)); - MIB.addOperand(OldMI->getOperand(3)); - MIB.addOperand(ImmOp); + MIB.add(OldMI->getOperand(0)); + MIB.add(OldMI->getOperand(2)); + MIB.add(OldMI->getOperand(3)); + MIB.add(ImmOp); OpStart = 4; Changed = true; } else if (HII->getAddrMode(*OldMI) == HexagonII::BaseImmOffset) { short NewOpCode = HII->getAbsoluteForm(*OldMI); assert(NewOpCode >= 0 && "Invalid New opcode\n"); MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode)) - .addOperand(OldMI->getOperand(0)); + .add(OldMI->getOperand(0)); const GlobalValue *GV = ImmOp.getGlobal(); int64_t Offset = ImmOp.getOffset() + OldMI->getOperand(2).getImm(); @@ -359,9 +362,9 @@ bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp, short NewOpCode = HII->xformRegToImmOffset(*OldMI); assert(NewOpCode >= 0 && "Invalid New opcode\n"); MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode)); - MIB.addOperand(OldMI->getOperand(0)); - MIB.addOperand(OldMI->getOperand(1)); - MIB.addOperand(ImmOp); + MIB.add(OldMI->getOperand(0)); + MIB.add(OldMI->getOperand(1)); + MIB.add(ImmOp); OpStart = 4; Changed = true; DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n"); @@ -370,7 +373,7 @@ bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp, if (Changed) for (unsigned i = OpStart; i < OpEnd; ++i) - MIB.addOperand(OldMI->getOperand(i)); + MIB.add(OldMI->getOperand(i)); return Changed; } @@ -390,10 +393,10 @@ bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp, short NewOpCode = HII->getBaseWithLongOffset(*OldMI); assert(NewOpCode >= 0 && "Invalid New opcode\n"); MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode)); - MIB.addOperand(OldMI->getOperand(1)); - MIB.addOperand(OldMI->getOperand(2)); - MIB.addOperand(ImmOp); - MIB.addOperand(OldMI->getOperand(3)); + MIB.add(OldMI->getOperand(1)); + MIB.add(OldMI->getOperand(2)); + MIB.add(ImmOp); + MIB.add(OldMI->getOperand(3)); OpStart = 4; } else if (HII->getAddrMode(*OldMI) == HexagonII::BaseImmOffset) { short NewOpCode = HII->getAbsoluteForm(*OldMI); @@ -402,7 +405,7 @@ bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp, const GlobalValue *GV = ImmOp.getGlobal(); int64_t Offset = ImmOp.getOffset() + OldMI->getOperand(1).getImm(); MIB.addGlobalAddress(GV, Offset, ImmOp.getTargetFlags()); - MIB.addOperand(OldMI->getOperand(2)); + MIB.add(OldMI->getOperand(2)); OpStart = 3; } Changed = true; @@ -412,9 +415,9 @@ bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp, short NewOpCode = HII->xformRegToImmOffset(*OldMI); assert(NewOpCode >= 0 && "Invalid New opcode\n"); MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode)); - MIB.addOperand(OldMI->getOperand(0)); - MIB.addOperand(ImmOp); - MIB.addOperand(OldMI->getOperand(1)); + MIB.add(OldMI->getOperand(0)); + MIB.add(ImmOp); + MIB.add(OldMI->getOperand(1)); OpStart = 2; Changed = true; DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n"); @@ -422,7 +425,7 @@ bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp, } if (Changed) for (unsigned i = OpStart; i < OpEnd; ++i) - MIB.addOperand(OldMI->getOperand(i)); + MIB.add(OldMI->getOperand(i)); return Changed; } @@ -473,26 +476,26 @@ bool HexagonOptAddrMode::changeAddAsl(NodeAddr<UseNode *> AddAslUN, BuildMI(*BB, InsertPt, UseMI->getDebugLoc(), HII->get(NewOpCode)); // change mem(Rs + # ) -> mem(Rt << # + ##) if (UseMID.mayLoad()) { - MIB.addOperand(UseMI->getOperand(0)); - MIB.addOperand(AddAslMI->getOperand(2)); - MIB.addOperand(AddAslMI->getOperand(3)); + MIB.add(UseMI->getOperand(0)); + MIB.add(AddAslMI->getOperand(2)); + MIB.add(AddAslMI->getOperand(3)); const GlobalValue *GV = ImmOp.getGlobal(); - MIB.addGlobalAddress(GV, UseMI->getOperand(2).getImm(), + MIB.addGlobalAddress(GV, UseMI->getOperand(2).getImm()+ImmOp.getOffset(), ImmOp.getTargetFlags()); OpStart = 3; } else if (UseMID.mayStore()) { - MIB.addOperand(AddAslMI->getOperand(2)); - MIB.addOperand(AddAslMI->getOperand(3)); + MIB.add(AddAslMI->getOperand(2)); + MIB.add(AddAslMI->getOperand(3)); const GlobalValue *GV = ImmOp.getGlobal(); - MIB.addGlobalAddress(GV, UseMI->getOperand(1).getImm(), + MIB.addGlobalAddress(GV, UseMI->getOperand(1).getImm()+ImmOp.getOffset(), ImmOp.getTargetFlags()); - MIB.addOperand(UseMI->getOperand(2)); + MIB.add(UseMI->getOperand(2)); OpStart = 3; } else llvm_unreachable("Unhandled instruction"); for (unsigned i = OpStart; i < OpEnd; ++i) - MIB.addOperand(UseMI->getOperand(i)); + MIB.add(UseMI->getOperand(i)); Deleted.insert(UseMI); } @@ -532,9 +535,9 @@ bool HexagonOptAddrMode::processBlock(NodeAddr<BlockNode *> BA) { !MI->getOperand(1).isGlobal()) continue; - DEBUG(dbgs() << "[Analyzing A2_tfrsi]: " << *MI << "\n"); - DEBUG(dbgs() << "\t[InstrNode]: " << Print<NodeAddr<InstrNode *>>(IA, *DFG) - << "\n"); + DEBUG(dbgs() << "[Analyzing " << HII->getName(MI->getOpcode()) << "]: " + << *MI << "\n\t[InstrNode]: " + << Print<NodeAddr<InstrNode *>>(IA, *DFG) << '\n'); NodeList UNodeList; getAllRealUses(SA, UNodeList); @@ -588,47 +591,10 @@ bool HexagonOptAddrMode::processBlock(NodeAddr<BlockNode *> BA) { return Changed; } -void HexagonOptAddrMode::updateMap(NodeAddr<InstrNode *> IA) { - RegisterSet RRs; - for (NodeAddr<RefNode *> RA : IA.Addr->members(*DFG)) - RRs.insert(RA.Addr->getRegRef(*DFG)); - bool Common = false; - for (auto &R : RDefMap) { - if (!RRs.count(R.first)) - continue; - Common = true; - break; - } - if (!Common) - return; - - for (auto &R : RDefMap) { - auto F = DefM.find(R.first.Reg); - if (F == DefM.end() || F->second.empty()) - continue; - R.second[IA.Id] = F->second.top()->Id; - } -} - -bool HexagonOptAddrMode::constructDefMap(MachineBasicBlock *B) { - bool Changed = false; - auto BA = DFG->getFunc().Addr->findBlock(B, *DFG); - DFG->markBlock(BA.Id, DefM); - - for (NodeAddr<InstrNode *> IA : BA.Addr->members(*DFG)) { - updateMap(IA); - DFG->pushDefs(IA, DefM); - } - - MachineDomTreeNode *N = MDT->getNode(B); - for (auto I : *N) - Changed |= constructDefMap(I->getBlock()); - - DFG->releaseBlock(BA.Id, DefM); - return Changed; -} - bool HexagonOptAddrMode::runOnMachineFunction(MachineFunction &MF) { + if (skipFunction(*MF.getFunction())) + return false; + bool Changed = false; auto &HST = MF.getSubtarget<HexagonSubtarget>(); auto &MRI = MF.getRegInfo(); @@ -639,15 +605,15 @@ bool HexagonOptAddrMode::runOnMachineFunction(MachineFunction &MF) { const TargetOperandInfo TOI(*HII); DataFlowGraph G(MF, *HII, TRI, *MDT, MDF, TOI); - G.build(); + // Need to keep dead phis because we can propagate uses of registers into + // nodes dominated by those would-be phis. + G.build(BuildOptions::KeepDeadPhis); DFG = &G; Liveness L(MRI, *DFG); L.computePhiInfo(); LV = &L; - constructDefMap(&DFG->getMF().front()); - Deleted.clear(); NodeAddr<FuncNode *> FA = DFG->getFunc(); DEBUG(dbgs() << "==== [RefMap#]=====:\n " |