summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp')
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp152
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 "
OpenPOWER on IntegriCloud