diff options
| author | Chris Lattner <sabre@nondot.org> | 2011-04-17 22:05:17 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2011-04-17 22:05:17 +0000 |
| commit | 2ff8c1a25fb9bcbf000bfa74aec131de70bd6e57 (patch) | |
| tree | 4130386f5c6bb54eca9e152062aa495f7ae82f35 | |
| parent | 02feb58dd7af9ae1ac483b49a55f1110a1071b8e (diff) | |
| download | bcm5719-llvm-2ff8c1a25fb9bcbf000bfa74aec131de70bd6e57.tar.gz bcm5719-llvm-2ff8c1a25fb9bcbf000bfa74aec131de70bd6e57.zip | |
now that predicates have a decent abstraction layer on them, introduce a new
kind of predicate: one that is specific to imm nodes. The predicate function
specified here just checks an int64_t directly instead of messing around with
SDNode's. The virtue of this is that it means that fastisel and other things
can reason about these predicates.
llvm-svn: 129675
| -rw-r--r-- | llvm/include/llvm/Target/TargetSelectionDAG.td | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 7 | ||||
| -rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 24 | ||||
| -rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.h | 3 | ||||
| -rw-r--r-- | llvm/utils/TableGen/Record.h | 2 |
5 files changed, 49 insertions, 4 deletions
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td index ffb9c5ee492..f7fac7afa3e 100644 --- a/llvm/include/llvm/Target/TargetSelectionDAG.td +++ b/llvm/include/llvm/Target/TargetSelectionDAG.td @@ -520,6 +520,7 @@ class PatFrag<dag ops, dag frag, code pred = [{}], dag Operands = ops; dag Fragment = frag; code PredicateCode = pred; + code ImmediateCode = [{}]; SDNodeXForm OperandTransform = xform; } @@ -528,6 +529,22 @@ class PatFrag<dag ops, dag frag, code pred = [{}], class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm> : PatFrag<(ops), frag, pred, xform>; + +// ImmLeaf is a pattern fragment with a constraint on the immediate. The +// constraint is a function that is run on the immediate (always with the value +// sign extended out to an int64_t) as Imm. The value type being matched is +// available as VT. For example: +// +// def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>; +// +// this is a more convenient form to match 'imm' nodes in than PatLeaf and also +// is preferred over using PatLeaf because it allows the code generator to +// reason more about the constraint. +class ImmLeaf<ValueType vt, code pred> : PatFrag<(ops), (vt imm)> { + let ImmediateCode = pred; +} + + // Leaf fragments. def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index d1812254635..e487e33e738 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -486,7 +486,12 @@ def immSext8 : PatLeaf<(imm), [{ return immSext8(N); }]>; def i16immSExt8 : PatLeaf<(i16 immSext8)>; def i32immSExt8 : PatLeaf<(i32 immSext8)>; def i64immSExt8 : PatLeaf<(i64 immSext8)>; -def i64immSExt32 : PatLeaf<(i64 imm), [{ return i64immSExt32(N); }]>; + + +def i64immSExt32 : ImmLeaf<i64, [{ return Imm == (int32_t)Imm; }]>; + + + def i64immZExt32 : PatLeaf<(i64 imm), [{ // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit // unsignedsign extended field. diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index b74144ebfdc..13ac6b15ba3 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -621,14 +621,24 @@ static void DumpDepVars(MultipleUseVarSet &DepVars) { // TreePredicateFn Implementation //===----------------------------------------------------------------------===// +/// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag. +TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) { + assert((getPredCode().empty() || getImmCode().empty()) && + ".td file corrupt: can't have a node predicate *and* an imm predicate"); +} + std::string TreePredicateFn::getPredCode() const { return PatFragRec->getRecord()->getValueAsCode("PredicateCode"); } +std::string TreePredicateFn::getImmCode() const { + return PatFragRec->getRecord()->getValueAsCode("ImmediateCode"); +} + /// isAlwaysTrue - Return true if this is a noop predicate. bool TreePredicateFn::isAlwaysTrue() const { - return getPredCode().empty(); + return getPredCode().empty() && getImmCode().empty(); } /// Return the name to use in the generated code to reference this, this is @@ -642,6 +652,18 @@ std::string TreePredicateFn::getFnName() const { /// not N. This handles casting and conversion to a concrete node type as /// appropriate. std::string TreePredicateFn::getCodeToRunOnSDNode() const { + // Handle immediate predicates first. + std::string ImmCode = getImmCode(); + if (!ImmCode.empty()) { + std::string Result = + " int64_t Imm = cast<ConstantSDNode>(Node)->getSExtValue();\n"; + if (ImmCode.find("VT") != std::string::npos) + Result += " MVT VT = Node->getValueType(0).getSimpleVT();\n"; + return Result + ImmCode; + } + + // Handle arbitrary node predicates. + assert(!getPredCode().empty() && "Don't have any predicate code!"); std::string ClassName; if (PatFragRec->getOnlyTree()->isLeaf()) ClassName = "SDNode"; diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.h b/llvm/utils/TableGen/CodeGenDAGPatterns.h index 2624495a8dc..b113a59e4a9 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.h +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.h @@ -249,7 +249,7 @@ class TreePredicateFn { TreePattern *PatFragRec; public: /// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag. - TreePredicateFn(TreePattern *N) : PatFragRec(N) {} + TreePredicateFn(TreePattern *N); TreePattern *getOrigPatFragRecord() const { return PatFragRec; } @@ -276,6 +276,7 @@ public: private: std::string getPredCode() const; + std::string getImmCode() const; }; diff --git a/llvm/utils/TableGen/Record.h b/llvm/utils/TableGen/Record.h index f3a5df23ec5..522b719803c 100644 --- a/llvm/utils/TableGen/Record.h +++ b/llvm/utils/TableGen/Record.h @@ -707,7 +707,7 @@ class CodeInit : public Init { public: explicit CodeInit(const std::string &V) : Value(V) {} - const std::string getValue() const { return Value; } + const std::string &getValue() const { return Value; } virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); |

