diff options
Diffstat (limited to 'llvm/utils/TableGen')
| -rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 10 | ||||
| -rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.h | 8 | ||||
| -rw-r--r-- | llvm/utils/TableGen/GlobalISelEmitter.cpp | 77 |
3 files changed, 90 insertions, 5 deletions
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index 3b400c1262e..c07a7267bbe 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -2744,8 +2744,10 @@ void TreePattern::dump() const { print(errs()); } // CodeGenDAGPatterns implementation // -CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : - Records(R), Target(R), LegalVTS(Target.getLegalValueTypes()) { +CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R, + PatternRewriterFn PatternRewriter) + : Records(R), Target(R), LegalVTS(Target.getLegalValueTypes()), + PatternRewriter(PatternRewriter) { Intrinsics = CodeGenIntrinsicTable(Records, false); TgtIntrinsics = CodeGenIntrinsicTable(Records, true); @@ -3536,6 +3538,8 @@ void CodeGenDAGPatterns::ParseInstructions() { TreePattern *I = TheInst.getPattern(); if (!I) continue; // No pattern. + if (PatternRewriter) + PatternRewriter(I); // FIXME: Assume only the first tree is the pattern. The others are clobber // nodes. TreePatternNode *Pattern = I->getTree(0); @@ -3936,6 +3940,8 @@ void CodeGenDAGPatterns::ParsePatterns() { Temp.getOnlyTree()->hasPossibleType()) { ListInit *Preds = CurPattern->getValueAsListInit("Predicates"); int Complexity = CurPattern->getValueAsInt("AddedComplexity"); + if (PatternRewriter) + PatternRewriter(Pattern); AddPatternToMatch( Pattern, PatternToMatch( diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.h b/llvm/utils/TableGen/CodeGenDAGPatterns.h index 1f7e9fb98d3..d3bb99a5a8f 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.h +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.h @@ -25,6 +25,7 @@ #include "llvm/Support/MathExtras.h" #include <algorithm> #include <array> +#include <functional> #include <map> #include <set> #include <vector> @@ -780,6 +781,7 @@ public: const std::vector<TreePatternNode*> &getTrees() const { return Trees; } unsigned getNumTrees() const { return Trees.size(); } TreePatternNode *getTree(unsigned i) const { return Trees[i]; } + void setTree(unsigned i, TreePatternNode *Tree) { Trees[i] = Tree; } TreePatternNode *getOnlyTree() const { assert(Trees.size() == 1 && "Doesn't have exactly one pattern!"); return Trees[0]; @@ -1029,8 +1031,12 @@ class CodeGenDAGPatterns { TypeSetByHwMode LegalVTS; + using PatternRewriterFn = std::function<void (TreePattern *)>; + PatternRewriterFn PatternRewriter; + public: - CodeGenDAGPatterns(RecordKeeper &R); + CodeGenDAGPatterns(RecordKeeper &R, + PatternRewriterFn PatternRewriter = nullptr); CodeGenTarget &getTargetInfo() { return Target; } const CodeGenTarget &getTargetInfo() const { return Target; } diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 08649d7f9b5..8a0d625ca44 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -2356,6 +2356,9 @@ private: Expected<RuleMatcher> runOnPattern(const PatternToMatch &P); void declareSubtargetFeature(Record *Predicate); + + TreePatternNode *fixupPatternNode(TreePatternNode *N); + void fixupPatternTrees(TreePattern *P); }; void GlobalISelEmitter::gatherNodeEquivs() { @@ -2377,8 +2380,8 @@ Record *GlobalISelEmitter::findNodeEquiv(Record *N) const { } GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK) - : RK(RK), CGP(RK), Target(CGP.getTargetInfo()), - CGRegs(RK, Target.getHwModes()) {} + : RK(RK), CGP(RK, [&](TreePattern *P) { fixupPatternTrees(P); }), + Target(CGP.getTargetInfo()), CGRegs(RK, Target.getHwModes()) {} //===- Emitter ------------------------------------------------------------===// @@ -3233,6 +3236,7 @@ void GlobalISelEmitter::run(raw_ostream &OS) { // Look through the SelectionDAG patterns we found, possibly emitting some. for (const PatternToMatch &Pat : CGP.ptms()) { ++NumPatternTotal; + auto MatcherOrErr = runOnPattern(Pat); // The pattern analysis can fail, indicating an unsupported pattern. @@ -3483,6 +3487,75 @@ void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) { Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size())); } +TreePatternNode *GlobalISelEmitter::fixupPatternNode(TreePatternNode *N) { + if (!N->isLeaf()) { + for (unsigned I = 0, E = N->getNumChildren(); I < E; ++I) { + TreePatternNode *OrigChild = N->getChild(I); + TreePatternNode *NewChild = fixupPatternNode(OrigChild); + if (OrigChild != NewChild) + N->setChild(I, NewChild); + } + + if (N->getOperator()->getName() == "ld") { + // If it's a signext-load we need to adapt the pattern slightly. We need + // to split the node into (sext (ld ...)), remove the <<signext>> predicate, + // and then apply the <<signextTY>> predicate by updating the result type + // of the load. + // + // For example: + // (ld:[i32] [iPTR])<<unindexed>><<signext>><<signexti16>> + // must be transformed into: + // (sext:[i32] (ld:[i16] [iPTR])<<unindexed>>) + // + // Likewise for zeroext-load. + + std::vector<TreePredicateFn> Predicates; + bool IsSignExtLoad = false; + bool IsZeroExtLoad = false; + Record *MemVT = nullptr; + for (const auto &P : N->getPredicateFns()) { + if (P.isLoad() && P.isSignExtLoad()) { + IsSignExtLoad = true; + continue; + } + if (P.isLoad() && P.isZeroExtLoad()) { + IsZeroExtLoad = true; + continue; + } + if (P.isLoad() && P.getMemoryVT()) { + MemVT = P.getMemoryVT(); + continue; + } + Predicates.push_back(P); + } + + if ((IsSignExtLoad || IsZeroExtLoad) && MemVT) { + assert(((IsSignExtLoad && !IsZeroExtLoad) || + (!IsSignExtLoad && IsZeroExtLoad)) && + "IsSignExtLoad and IsZeroExtLoad are mutually exclusive"); + TreePatternNode *Ext = new TreePatternNode( + RK.getDef(IsSignExtLoad ? "sext" : "zext"), {N}, 1); + Ext->setType(0, N->getType(0)); + N->clearPredicateFns(); + N->setPredicateFns(Predicates); + N->setType(0, getValueType(MemVT)); + return Ext; + } + } + } + + return N; +} + +void GlobalISelEmitter::fixupPatternTrees(TreePattern *P) { + for (unsigned I = 0, E = P->getNumTrees(); I < E; ++I) { + TreePatternNode *OrigTree = P->getTree(I); + TreePatternNode *NewTree = fixupPatternNode(OrigTree); + if (OrigTree != NewTree) + P->setTree(I, NewTree); + } +} + } // end anonymous namespace //===----------------------------------------------------------------------===// |

