diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-01-18 20:42:47 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-01-18 20:42:47 +0000 |
commit | e6b0662092cac34e10279971b7dfe85c5e3cc880 (patch) | |
tree | 341f2ee4cc81f3393c667a7681f17100302cbaaf /llvm/lib/Target/Hexagon/RDFDeadCode.cpp | |
parent | 69e670d5f996e2d1c0e4300aec4b41cc2ec24dcb (diff) | |
download | llvm-e6b0662092cac34e10279971b7dfe85c5e3cc880.zip llvm-e6b0662092cac34e10279971b7dfe85c5e3cc880.tar.gz llvm-e6b0662092cac34e10279971b7dfe85c5e3cc880.tar.bz2 |
[RDF] Improve compile-time performance of dead code elimination
llvm-svn: 258074
Diffstat (limited to 'llvm/lib/Target/Hexagon/RDFDeadCode.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFDeadCode.cpp | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFDeadCode.cpp b/llvm/lib/Target/Hexagon/RDFDeadCode.cpp index a749324..63177d5 100644 --- a/llvm/lib/Target/Hexagon/RDFDeadCode.cpp +++ b/llvm/lib/Target/Hexagon/RDFDeadCode.cpp @@ -18,9 +18,38 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include <queue> + using namespace llvm; using namespace rdf; +// This drastically improves execution time in "collect" over using +// SetVector as a work queue, and popping the first element from it. +template<typename T> struct DeadCodeElimination::SetQueue { + SetQueue() : Set(), Queue() {} + + bool empty() const { + return Queue.empty(); + } + T pop_front() { + T V = Queue.front(); + Queue.pop(); + Set.erase(V); + return V; + } + void push_back(T V) { + if (Set.count(V)) + return; + Queue.push(V); + Set.insert(V); + } + +private: + DenseSet<T> Set; + std::queue<T> Queue; +}; + + // Check if the given instruction has observable side-effects, i.e. if // it should be considered "live". It is safe for this function to be // overly conservative (i.e. return "true" for all instructions), but it @@ -40,33 +69,33 @@ bool DeadCodeElimination::isLiveInstr(const MachineInstr *MI) const { } void DeadCodeElimination::scanInstr(NodeAddr<InstrNode*> IA, - SetVector<NodeId> &WorkQ) { + SetQueue<NodeId> &WorkQ) { if (!DFG.IsCode<NodeAttrs::Stmt>(IA)) return; if (!isLiveInstr(NodeAddr<StmtNode*>(IA).Addr->getCode())) return; for (NodeAddr<RefNode*> RA : IA.Addr->members(DFG)) { if (!LiveNodes.count(RA.Id)) - WorkQ.insert(RA.Id); + WorkQ.push_back(RA.Id); } } void DeadCodeElimination::processDef(NodeAddr<DefNode*> DA, - SetVector<NodeId> &WorkQ) { + SetQueue<NodeId> &WorkQ) { NodeAddr<InstrNode*> IA = DA.Addr->getOwner(DFG); for (NodeAddr<UseNode*> UA : IA.Addr->members_if(DFG.IsUse, DFG)) { if (!LiveNodes.count(UA.Id)) - WorkQ.insert(UA.Id); + WorkQ.push_back(UA.Id); } for (NodeAddr<DefNode*> TA : DFG.getRelatedRefs(IA, DA)) LiveNodes.insert(TA.Id); } void DeadCodeElimination::processUse(NodeAddr<UseNode*> UA, - SetVector<NodeId> &WorkQ) { + SetQueue<NodeId> &WorkQ) { for (NodeAddr<DefNode*> DA : LV.getAllReachingDefs(UA)) { if (!LiveNodes.count(DA.Id)) - WorkQ.insert(DA.Id); + WorkQ.push_back(DA.Id); } } @@ -84,14 +113,13 @@ bool DeadCodeElimination::collect() { // instruction are considered live. For each live use, all its reaching // defs are considered live. LiveNodes.clear(); - SetVector<NodeId> WorkQ; + SetQueue<NodeId> WorkQ; for (NodeAddr<BlockNode*> BA : DFG.getFunc().Addr->members(DFG)) for (NodeAddr<InstrNode*> IA : BA.Addr->members(DFG)) scanInstr(IA, WorkQ); while (!WorkQ.empty()) { - NodeId N = *WorkQ.begin(); - WorkQ.remove(N); + NodeId N = WorkQ.pop_front(); LiveNodes.insert(N); auto RA = DFG.addr<RefNode*>(N); if (DFG.IsDef(RA)) |