class Record;
class SDNodeInfo;
-Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,
+Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
const CodeGenDAGPatterns &CGP);
Matcher *OptimizeMatcher(Matcher *Matcher, const CodeGenDAGPatterns &CGP);
void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP,
CheckPatternPredicate,
CheckPredicate, // Fail if node predicate fails.
CheckOpcode, // Fail if not opcode.
- CheckMultiOpcode, // Fail if not in opcode list.
+ SwitchOpcode, // Dispatch based on opcode.
CheckType, // Fail if not correct type.
+ SwitchType, // Dispatch based on type.
CheckChildType, // Fail if child has wrong type.
CheckInteger, // Fail if wrong val.
CheckCondCode, // Fail if not condcode.
CheckAndImm,
CheckOrImm,
CheckFoldableChainNode,
- CheckChainCompatible,
// Node creation/emisssion.
EmitInteger, // Create a TargetConstant
return false;
}
+ /// isSimplePredicateNode - Return true if this is a simple predicate that
+ /// operates on the node or its children without potential side effects or a
+ /// change of the current node.
+ bool isSimplePredicateNode() const {
+ switch (getKind()) {
+ default: return false;
+ case CheckSame:
+ case CheckPatternPredicate:
+ case CheckPredicate:
+ case CheckOpcode:
+ case CheckType:
+ case CheckChildType:
+ case CheckInteger:
+ case CheckCondCode:
+ case CheckValueType:
+ case CheckAndImm:
+ case CheckOrImm:
+ case CheckFoldableChainNode:
+ return true;
+ }
+ }
+
+ /// isSimplePredicateOrRecordNode - Return true if this is a record node or
+ /// a simple predicate.
+ bool isSimplePredicateOrRecordNode() const {
+ return isSimplePredicateNode() ||
+ getKind() == RecordNode || getKind() == RecordChild;
+ }
+
+ /// unlinkNode - Unlink the specified node from this chain. If Other == this,
+ /// we unlink the next pointer and return it. Otherwise we unlink Other from
+ /// the list and return this.
+ Matcher *unlinkNode(Matcher *Other);
+
+ /// canMoveBefore - Return true if this matcher is the same as Other, or if
+ /// we can move this matcher past all of the nodes in-between Other and this
+ /// node. Other must be equal to or before this.
+ bool canMoveBefore(const Matcher *Other) const;
+
+ /// canMoveBefore - Return true if it is safe to move the current matcher
+ /// across the specified one.
+ bool canMoveBeforeNode(const Matcher *Other) const;
+
/// isContradictory - Return true of these two matchers could never match on
/// the same node.
bool isContradictory(const Matcher *Other) const {
/// WhatFor - This is a string indicating why we're recording this. This
/// should only be used for comment generation not anything semantic.
std::string WhatFor;
+
+ /// ResultNo - The slot number in the RecordedNodes vector that this will be,
+ /// just printed as a comment.
+ unsigned ResultNo;
public:
- RecordMatcher(const std::string &whatfor)
- : Matcher(RecordNode), WhatFor(whatfor) {}
+ RecordMatcher(const std::string &whatfor, unsigned resultNo)
+ : Matcher(RecordNode), WhatFor(whatfor), ResultNo(resultNo) {}
const std::string &getWhatFor() const { return WhatFor; }
+ unsigned getResultNo() const { return ResultNo; }
static inline bool classof(const Matcher *N) {
return N->getKind() == RecordNode;
/// WhatFor - This is a string indicating why we're recording this. This
/// should only be used for comment generation not anything semantic.
std::string WhatFor;
+
+ /// ResultNo - The slot number in the RecordedNodes vector that this will be,
+ /// just printed as a comment.
+ unsigned ResultNo;
public:
- RecordChildMatcher(unsigned childno, const std::string &whatfor)
- : Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor) {}
+ RecordChildMatcher(unsigned childno, const std::string &whatfor,
+ unsigned resultNo)
+ : Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor),
+ ResultNo(resultNo) {}
unsigned getChildNo() const { return ChildNo; }
const std::string &getWhatFor() const { return WhatFor; }
-
+ unsigned getResultNo() const { return ResultNo; }
+
static inline bool classof(const Matcher *N) {
return N->getKind() == RecordChild;
}
private:
virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
- return &cast<CheckOpcodeMatcher>(M)->Opcode == &Opcode;
- }
+ virtual bool isEqualImpl(const Matcher *M) const;
virtual unsigned getHashImpl() const;
virtual bool isContradictoryImpl(const Matcher *M) const;
};
-
-/// CheckMultiOpcodeMatcher - This checks to see if the current node has one
-/// of the specified opcode, if not it fails to match.
-class CheckMultiOpcodeMatcher : public Matcher {
- SmallVector<const SDNodeInfo*, 4> Opcodes;
+
+/// SwitchOpcodeMatcher - Switch based on the current node's opcode, dispatching
+/// to one matcher per opcode. If the opcode doesn't match any of the cases,
+/// then the match fails. This is semantically equivalent to a Scope node where
+/// every child does a CheckOpcode, but is much faster.
+class SwitchOpcodeMatcher : public Matcher {
+ SmallVector<std::pair<const SDNodeInfo*, Matcher*>, 8> Cases;
public:
- CheckMultiOpcodeMatcher(const SDNodeInfo * const *opcodes, unsigned numops)
- : Matcher(CheckMultiOpcode), Opcodes(opcodes, opcodes+numops) {}
-
- unsigned getNumOpcodes() const { return Opcodes.size(); }
- const SDNodeInfo &getOpcode(unsigned i) const { return *Opcodes[i]; }
-
+ SwitchOpcodeMatcher(const std::pair<const SDNodeInfo*, Matcher*> *cases,
+ unsigned numcases)
+ : Matcher(SwitchOpcode), Cases(cases, cases+numcases) {}
+
static inline bool classof(const Matcher *N) {
- return N->getKind() == CheckMultiOpcode;
+ return N->getKind() == SwitchOpcode;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
-
+ unsigned getNumCases() const { return Cases.size(); }
+
+ const SDNodeInfo &getCaseOpcode(unsigned i) const { return *Cases[i].first; }
+ Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }
+ const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }
+
private:
virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
- return cast<CheckMultiOpcodeMatcher>(M)->Opcodes == Opcodes;
- }
- virtual unsigned getHashImpl() const;
+ virtual bool isEqualImpl(const Matcher *M) const { return false; }
+ virtual unsigned getHashImpl() const { return 4123; }
};
-
-
/// CheckTypeMatcher - This checks to see if the current node has the
-/// specified type, if not it fails to match.
+/// specified type at the specified result, if not it fails to match.
class CheckTypeMatcher : public Matcher {
MVT::SimpleValueType Type;
+ unsigned ResNo;
public:
- CheckTypeMatcher(MVT::SimpleValueType type)
- : Matcher(CheckType), Type(type) {}
+ CheckTypeMatcher(MVT::SimpleValueType type, unsigned resno)
+ : Matcher(CheckType), Type(type), ResNo(resno) {}
MVT::SimpleValueType getType() const { return Type; }
+ unsigned getResNo() const { return ResNo; }
static inline bool classof(const Matcher *N) {
return N->getKind() == CheckType;
virtual bool isContradictoryImpl(const Matcher *M) const;
};
+/// SwitchTypeMatcher - Switch based on the current node's type, dispatching
+/// to one matcher per case. If the type doesn't match any of the cases,
+/// then the match fails. This is semantically equivalent to a Scope node where
+/// every child does a CheckType, but is much faster.
+class SwitchTypeMatcher : public Matcher {
+ SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
+public:
+ SwitchTypeMatcher(const std::pair<MVT::SimpleValueType, Matcher*> *cases,
+ unsigned numcases)
+ : Matcher(SwitchType), Cases(cases, cases+numcases) {}
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == SwitchType;
+ }
+
+ unsigned getNumCases() const { return Cases.size(); }
+
+ MVT::SimpleValueType getCaseType(unsigned i) const { return Cases[i].first; }
+ Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }
+ const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }
+
+private:
+ virtual void printImpl(raw_ostream &OS, unsigned indent) const;
+ virtual bool isEqualImpl(const Matcher *M) const { return false; }
+ virtual unsigned getHashImpl() const { return 4123; }
+};
+
+
/// CheckChildTypeMatcher - This checks to see if a child node has the
/// specified type, if not it fails to match.
class CheckChildTypeMatcher : public Matcher {
return cast<CheckValueTypeMatcher>(M)->TypeName == TypeName;
}
virtual unsigned getHashImpl() const;
+ bool isContradictoryImpl(const Matcher *M) const;
};
/// the current node.
class CheckComplexPatMatcher : public Matcher {
const ComplexPattern &Pattern;
+
+ /// MatchNumber - This is the recorded nodes slot that contains the node we want to
+ /// match against.
+ unsigned MatchNumber;
+
+ /// Name - The name of the node we're matching, for comment emission.
+ std::string Name;
+
+ /// FirstResult - This is the first slot in the RecordedNodes list that the
+ /// result of the match populates.
+ unsigned FirstResult;
public:
- CheckComplexPatMatcher(const ComplexPattern &pattern)
- : Matcher(CheckComplexPat), Pattern(pattern) {}
+ CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned matchnumber,
+ const std::string &name, unsigned firstresult)
+ : Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber),
+ Name(name), FirstResult(firstresult) {}
const ComplexPattern &getPattern() const { return Pattern; }
+ unsigned getMatchNumber() const { return MatchNumber; }
+
+ const std::string getName() const { return Name; }
+ unsigned getFirstResult() const { return FirstResult; }
static inline bool classof(const Matcher *N) {
return N->getKind() == CheckComplexPat;
private:
virtual void printImpl(raw_ostream &OS, unsigned indent) const;
virtual bool isEqualImpl(const Matcher *M) const {
- return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern;
+ return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern &&
+ cast<CheckComplexPatMatcher>(M)->MatchNumber == MatchNumber;
}
virtual unsigned getHashImpl() const {
- return (unsigned)(intptr_t)&Pattern;
+ return (unsigned)(intptr_t)&Pattern ^ MatchNumber;
}
};
virtual unsigned getHashImpl() const { return 0; }
};
-/// CheckChainCompatibleMatcher - Verify that the current node's chain
-/// operand is 'compatible' with the specified recorded node's.
-class CheckChainCompatibleMatcher : public Matcher {
- unsigned PreviousOp;
-public:
- CheckChainCompatibleMatcher(unsigned previousop)
- : Matcher(CheckChainCompatible), PreviousOp(previousop) {}
-
- unsigned getPreviousOp() const { return PreviousOp; }
-
- static inline bool classof(const Matcher *N) {
- return N->getKind() == CheckChainCompatible;
- }
-
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
-
-private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
- return cast<CheckChainCompatibleMatcher>(M)->PreviousOp == PreviousOp;
- }
- virtual unsigned getHashImpl() const { return PreviousOp; }
-};
-
/// EmitIntegerMatcher - This creates a new TargetConstant.
class EmitIntegerMatcher : public Matcher {
int64_t Val;