diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2017-03-01 19:30:42 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2017-03-01 19:30:42 +0000 |
commit | ebabd99adb9a1fef811298b1fffa2d0649185991 (patch) | |
tree | 11edce8d2d3c76513d7fe7a3dceaca9b63c8f49b /llvm/lib/Target | |
parent | d2fd4aeb5611e496bd394d38495c007c0d73a5a1 (diff) | |
download | bcm5719-llvm-ebabd99adb9a1fef811298b1fffa2d0649185991.tar.gz bcm5719-llvm-ebabd99adb9a1fef811298b1fffa2d0649185991.zip |
[RDF] Add recursion limit to getAllReachingDefsRec
For large programs this function can take significant amounts of time.
Let it abort gracefully when the program is too complex.
llvm-svn: 296662
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFLiveness.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFLiveness.h | 9 |
3 files changed, 40 insertions, 9 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp b/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp index 49d5cb34a0d..be50288849c 100644 --- a/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp +++ b/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp @@ -208,7 +208,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"; diff --git a/llvm/lib/Target/Hexagon/RDFLiveness.cpp b/llvm/lib/Target/Hexagon/RDFLiveness.cpp index 2a2700ee6ac..6067be37ef1 100644 --- a/llvm/lib/Target/Hexagon/RDFLiveness.cpp +++ b/llvm/lib/Target/Hexagon/RDFLiveness.cpp @@ -31,11 +31,15 @@ #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; using namespace rdf; +static cl::opt<unsigned> MaxRecNest("rdf-liveness-max-rec", cl::init(25), + cl::Hidden, cl::desc("Maximum recursion level")); + namespace llvm { namespace rdf { template<> @@ -247,8 +251,18 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR, } -NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR, - NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs) { +std::pair<NodeSet,bool> +Liveness::getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA, + NodeSet &Visited, const NodeSet &Defs) { + return getAllReachingDefsRecImpl(RefRR, RefA, Visited, Defs, 0, MaxRecNest); +} + + +std::pair<NodeSet,bool> +Liveness::getAllReachingDefsRecImpl(RegisterRef RefRR, NodeAddr<RefNode*> RefA, + NodeSet &Visited, const NodeSet &Defs, unsigned Nest, unsigned MaxNest) { + if (Nest > MaxNest) + return { {}, false }; // Collect all defined registers. Do not consider phis to be defining // anything, only collect "real" definitions. RegisterAggr DefRRs(PRI); @@ -260,7 +274,7 @@ NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR, NodeList RDs = getAllReachingDefs(RefRR, RefA, false, true, DefRRs); if (RDs.empty()) - return Defs; + return { Defs, true }; // Make a copy of the preexisting definitions and add the newly found ones. NodeSet TmpDefs = Defs; @@ -279,12 +293,15 @@ NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR, Visited.insert(PA.Id); // Go over all phi uses and get the reaching defs for each use. for (auto U : PA.Addr->members_if(DFG.IsRef<NodeAttrs::Use>, DFG)) { - const auto &T = getAllReachingDefsRec(RefRR, U, Visited, TmpDefs); - Result.insert(T.begin(), T.end()); + const auto &T = getAllReachingDefsRecImpl(RefRR, U, Visited, TmpDefs, + Nest+1, MaxNest); + if (!T.second) + return { T.first, false }; + Result.insert(T.first.begin(), T.first.end()); } } - return Result; + return { Result, true }; } diff --git a/llvm/lib/Target/Hexagon/RDFLiveness.h b/llvm/lib/Target/Hexagon/RDFLiveness.h index 76a3a4031b8..edb9e198fb8 100644 --- a/llvm/lib/Target/Hexagon/RDFLiveness.h +++ b/llvm/lib/Target/Hexagon/RDFLiveness.h @@ -62,14 +62,15 @@ namespace rdf { NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA) { return getAllReachingDefs(RefRR, RefA, false, false, NoRegs); } - NodeSet getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA, - NodeSet &Visited, const NodeSet &Defs); NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA, const RegisterAggr &DefRRs); NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA) { return getAllReachedUses(RefRR, DefA, NoRegs); } + std::pair<NodeSet,bool> getAllReachingDefsRec(RegisterRef RefRR, + NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs); + LiveMapType &getLiveMap() { return LiveMap; } const LiveMapType &getLiveMap() const { return LiveMap; } const RefMap &getRealUses(NodeId P) const { @@ -125,6 +126,10 @@ namespace rdf { MachineBasicBlock *getBlockWithRef(NodeId RN) const; void traverse(MachineBasicBlock *B, RefMap &LiveIn); void emptify(RefMap &M); + + std::pair<NodeSet,bool> getAllReachingDefsRecImpl(RegisterRef RefRR, + NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs, + unsigned Nest, unsigned MaxNest); }; } // namespace rdf } // namespace llvm |