OPC_CheckPredicate,
OPC_CheckOpcode,
OPC_SwitchOpcode,
- OPC_CheckMultiOpcode,
OPC_CheckType,
OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
continue;
}
- case OPC_CheckMultiOpcode: {
- unsigned NumOps = MatcherTable[MatcherIndex++];
- bool OpcodeEquals = false;
- for (unsigned i = 0; i != NumOps; ++i)
- OpcodeEquals |= N->getOpcode() == MatcherTable[MatcherIndex++];
- if (!OpcodeEquals) break;
- continue;
- }
-
case OPC_CheckType: {
MVT::SimpleValueType VT =
(MVT::SimpleValueType)MatcherTable[MatcherIndex++];
PatternSortingPredicate2(CGP));
- // Convert each pattern into Matcher's.
+ // Convert each variant of each pattern into a Matcher.
std::vector<Matcher*> PatternMatchers;
- for (unsigned i = 0, e = Patterns.size(); i != e; ++i)
- PatternMatchers.push_back(ConvertPatternToMatcher(*Patterns[i], CGP));
+ for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
+ for (unsigned Variant = 0; ; ++Variant) {
+ if (Matcher *M = ConvertPatternToMatcher(*Patterns[i], Variant, CGP))
+ PatternMatchers.push_back(M);
+ else
+ break;
+ }
+ }
+
Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0],
PatternMatchers.size());
}
-void CheckMultiOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const{
- OS.indent(indent) << "CheckMultiOpcode <todo args>\n";
-}
-
void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
}
return HashString(Opcode.getEnumName());
}
-unsigned CheckMultiOpcodeMatcher::getHashImpl() const {
- unsigned Result = 0;
- for (unsigned i = 0, e = Opcodes.size(); i != e; ++i)
- Result |= HashString(Opcodes[i]->getEnumName());
- return Result;
-}
-
unsigned CheckCondCodeMatcher::getHashImpl() const {
return HashString(CondCodeName);
}
return COM->getOpcode().getEnumName() != getOpcode().getEnumName();
}
- // TODO: CheckMultiOpcodeMatcher?
-
// If the node has a known type, and if the type we're checking for is
// different, then we know they contradict. For example, a check for
// ISD::STORE will never be true at the same time a check for Type i32 is.
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,
virtual unsigned getHashImpl() const { return 4123; }
};
-/// 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;
-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]; }
-
- static inline bool classof(const Matcher *N) {
- return N->getKind() == CheckMultiOpcode;
- }
-
- 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<CheckMultiOpcodeMatcher>(M)->Opcodes == Opcodes;
- }
- virtual unsigned getHashImpl() const;
-};
-
-
-
/// CheckTypeMatcher - This checks to see if the current node has the
/// specified type, if not it fails to match.
class CheckTypeMatcher : public Matcher {
return CurrentIdx-StartIdx;
}
- case Matcher::CheckMultiOpcode: {
- const CheckMultiOpcodeMatcher *CMO = cast<CheckMultiOpcodeMatcher>(N);
- OS << "OPC_CheckMultiOpcode, " << CMO->getNumOpcodes() << ", ";
- for (unsigned i = 0, e = CMO->getNumOpcodes(); i != e; ++i)
- OS << CMO->getOpcode(i).getEnumName() << ", ";
- OS << '\n';
- return 2 + CMO->getNumOpcodes();
- }
-
- case Matcher::CheckType:
+ case Matcher::CheckType:
OS << "OPC_CheckType, "
<< getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
return 2;
case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break;
case Matcher::CheckOpcode: OS << "OPC_CheckOpcode"; break;
case Matcher::SwitchOpcode: OS << "OPC_SwitchOpcode"; break;
- case Matcher::CheckMultiOpcode: OS << "OPC_CheckMultiOpcode"; break;
case Matcher::CheckType: OS << "OPC_CheckType"; break;
case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
delete PatWithNoTypes;
}
- void EmitMatcherCode();
+ bool EmitMatcherCode(unsigned Variant);
void EmitResultCode();
Matcher *GetMatcher() const { return TheMatcher; }
// Handle complex pattern.
const ComplexPattern &CP = CGP.getComplexPattern(LeafRec);
-
- // If we're at the root of the pattern, we have to check that the opcode
- // is a one of the ones requested to be matched.
- if (N == Pattern.getSrcPattern()) {
- const std::vector<Record*> &OpNodes = CP.getRootNodes();
- if (OpNodes.size() == 1) {
- AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[0])));
- } else if (!OpNodes.empty()) {
- SmallVector<const SDNodeInfo*, 4> OpNames;
- for (unsigned i = 0, e = OpNodes.size(); i != e; i++)
- OpNames.push_back(&CGP.getSDNodeInfo(OpNodes[i]));
- AddMatcher(new CheckMultiOpcodeMatcher(OpNames.data(), OpNames.size()));
- }
- }
// Emit a CheckComplexPat operation, which does the match (aborting if it
// fails) and pushes the matched operands onto the recorded nodes list.
EmitOperatorMatchCode(N, NodeNoTypes);
}
-void MatcherGen::EmitMatcherCode() {
+/// EmitMatcherCode - Generate the code that matches the predicate of this
+/// pattern for the specified Variant. If the variant is invalid this returns
+/// true and does not generate code, if it is valid, it returns false.
+bool MatcherGen::EmitMatcherCode(unsigned Variant) {
+ // If the root of the pattern is a ComplexPattern and if it is specified to
+ // match some number of root opcodes, these are considered to be our variants.
+ // Depending on which variant we're generating code for, emit the root opcode
+ // check.
+ if (const ComplexPattern *CP =
+ Pattern.getSrcPattern()->getComplexPatternInfo(CGP)) {
+
+ const std::vector<Record*> &OpNodes = CP->getRootNodes();
+ if (OpNodes.empty()) {
+ // FIXME: Empty OpNodes runs on everything, is this even valid?
+ if (Variant != 0) return true;
+ } else {
+ if (Variant >= OpNodes.size()) return true;
+
+ AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[Variant])));
+ }
+ } else {
+ if (Variant != 0) return true;
+ }
+
// If the pattern has a predicate on it (e.g. only enabled when a subtarget
// feature is around, do the check).
// FIXME: This should get emitted after the match code below to encourage
// dag combine, eliminating the horrible side-effect-full stuff from
// X86's MatchAddress.
if (!Pattern.getPredicateCheck().empty())
- AddMatcher(new
- CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
-
+ AddMatcher(new CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
+
// Emit the matcher for the pattern structure and types.
EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes);
+ return false;
}
}
+/// ConvertPatternToMatcher - Create the matcher for the specified pattern with
+/// the specified variant. If the variant number is invalid, this returns null.
Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
+ unsigned Variant,
const CodeGenDAGPatterns &CGP) {
MatcherGen Gen(Pattern, CGP);
// Generate the code for the matcher.
- Gen.EmitMatcherCode();
-
+ if (Gen.EmitMatcherCode(Variant))
+ return 0;
// FIXME2: Kill extra MoveParent commands at the end of the matcher sequence.
// FIXME2: Split result code out to another table, and make the matcher end
// like X86 where many operations are valid on multiple types.
if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) ||
isa<RecordMatcher>(N)) &&
- (isa<CheckOpcodeMatcher>(N->getNext()) ||
- isa<CheckMultiOpcodeMatcher>(N->getNext()))) {
+ isa<CheckOpcodeMatcher>(N->getNext())) {
// Unlink the two nodes from the list.
Matcher *CheckType = MatcherPtr.take();
Matcher *CheckOpcode = CheckType->takeNext();