summaryrefslogtreecommitdiffstats
path: root/llvm/utils/TableGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen')
-rw-r--r--llvm/utils/TableGen/CodeGenDAGPatterns.cpp10
-rw-r--r--llvm/utils/TableGen/CodeGenDAGPatterns.h8
-rw-r--r--llvm/utils/TableGen/GlobalISelEmitter.cpp77
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
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud