diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-11-29 18:20:08 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-11-29 18:20:08 +0000 |
commit | a26a848da3c45f58abce5578a5f710734e9ee2cf (patch) | |
tree | af6b43689a7b29b2e1f05adf8c7a5c3c9a623d0e /llvm/utils | |
parent | 4fe0080984899c35a27e673a098abff183a1c77e (diff) | |
download | bcm5719-llvm-a26a848da3c45f58abce5578a5f710734e9ee2cf.tar.gz bcm5719-llvm-a26a848da3c45f58abce5578a5f710734e9ee2cf.zip |
[TableGen] Examine entire subreg compositions to detect ambiguity
When tablegen detects that there exist two subregister compositions that
result in the same value for some register, it will emit a warning. This
kind of an overlap in compositions should only happen when it is caused
by a user-defined composition. It can happen, however, that the user-
defined composition is not identically equal to another one, but it does
produce the same value for one or more registers. In such cases suppress
the warning.
This patch is to silence the warning when building the System Z backend
after D50725.
Differential Revision: https://reviews.llvm.org/D50977
llvm-svn: 347894
Diffstat (limited to 'llvm/utils')
-rw-r--r-- | llvm/utils/TableGen/CodeGenRegisters.cpp | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp index e70a79f08af..74a2b078dfb 100644 --- a/llvm/utils/TableGen/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/CodeGenRegisters.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/IntEqClasses.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -1309,6 +1310,55 @@ getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8> &Parts) { } void CodeGenRegBank::computeComposites() { + using RegMap = std::map<const CodeGenRegister*, const CodeGenRegister*>; + + // Subreg -> { Reg->Reg }, where the right-hand side is the mapping from + // register to (sub)register associated with the action of the left-hand + // side subregister. + std::map<const CodeGenSubRegIndex*, RegMap> SubRegAction; + for (const CodeGenRegister &R : Registers) { + const CodeGenRegister::SubRegMap &SM = R.getSubRegs(); + for (std::pair<const CodeGenSubRegIndex*, const CodeGenRegister*> P : SM) + SubRegAction[P.first].insert({&R, P.second}); + } + + // Calculate the composition of two subregisters as compositions of their + // associated actions. + auto compose = [&SubRegAction] (const CodeGenSubRegIndex *Sub1, + const CodeGenSubRegIndex *Sub2) { + RegMap C; + const RegMap &Img1 = SubRegAction.at(Sub1); + const RegMap &Img2 = SubRegAction.at(Sub2); + for (std::pair<const CodeGenRegister*, const CodeGenRegister*> P : Img1) { + auto F = Img2.find(P.second); + if (F != Img2.end()) + C.insert({P.first, F->second}); + } + return C; + }; + + // Check if the two maps agree on the intersection of their domains. + auto agree = [] (const RegMap &Map1, const RegMap &Map2) { + // Technically speaking, an empty map agrees with any other map, but + // this could flag false positives. We're interested in non-vacuous + // agreements. + if (Map1.empty() || Map2.empty()) + return false; + for (std::pair<const CodeGenRegister*, const CodeGenRegister*> P : Map1) { + auto F = Map2.find(P.first); + if (F == Map2.end() || P.second != F->second) + return false; + } + return true; + }; + + using CompositePair = std::pair<const CodeGenSubRegIndex*, + const CodeGenSubRegIndex*>; + SmallSet<CompositePair,4> UserDefined; + for (const CodeGenSubRegIndex &Idx : SubRegIndices) + for (auto P : Idx.getComposites()) + UserDefined.insert(std::make_pair(&Idx, P.first)); + // Keep track of TopoSigs visited. We only need to visit each TopoSig once, // and many registers will share TopoSigs on regular architectures. BitVector TopoSigs(getNumTopoSigs()); @@ -1341,11 +1391,15 @@ void CodeGenRegBank::computeComposites() { assert(Idx3 && "Sub-register doesn't have an index"); // Conflicting composition? Emit a warning but allow it. - if (CodeGenSubRegIndex *Prev = Idx1->addComposite(Idx2, Idx3)) - PrintWarning(Twine("SubRegIndex ") + Idx1->getQualifiedName() + - " and " + Idx2->getQualifiedName() + - " compose ambiguously as " + Prev->getQualifiedName() + - " or " + Idx3->getQualifiedName()); + if (CodeGenSubRegIndex *Prev = Idx1->addComposite(Idx2, Idx3)) { + // If the composition was not user-defined, always emit a warning. + if (!UserDefined.count({Idx1, Idx2}) || + agree(compose(Idx1, Idx2), SubRegAction.at(Idx3))) + PrintWarning(Twine("SubRegIndex ") + Idx1->getQualifiedName() + + " and " + Idx2->getQualifiedName() + + " compose ambiguously as " + Prev->getQualifiedName() + + " or " + Idx3->getQualifiedName()); + } } } } |