diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h index 0e856a1c7bee..fa3b08feec7f 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -113,7 +113,6 @@ public: OPC_CheckPredicate, OPC_CheckOpcode, OPC_SwitchOpcode, - OPC_CheckMultiOpcode, OPC_CheckType, OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type, OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 1e3550cb8201..f1e6b960ee09 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1787,15 +1787,6 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, 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++]; diff --git a/llvm/utils/TableGen/DAGISelEmitter.cpp b/llvm/utils/TableGen/DAGISelEmitter.cpp index 2854e4f221da..533664669ac5 100644 --- a/llvm/utils/TableGen/DAGISelEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelEmitter.cpp @@ -1959,10 +1959,17 @@ void DAGISelEmitter::run(raw_ostream &OS) { PatternSortingPredicate2(CGP)); - // Convert each pattern into Matcher's. + // Convert each variant of each pattern into a Matcher. std::vector 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()); diff --git a/llvm/utils/TableGen/DAGISelMatcher.cpp b/llvm/utils/TableGen/DAGISelMatcher.cpp index c88f260c4e4d..860165f7f4fa 100644 --- a/llvm/utils/TableGen/DAGISelMatcher.cpp +++ b/llvm/utils/TableGen/DAGISelMatcher.cpp @@ -98,10 +98,6 @@ void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const { } -void CheckMultiOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const{ - OS.indent(indent) << "CheckMultiOpcode \n"; -} - void CheckTypeMatcher::printImpl(raw_ostream &OS, unsigned indent) const { OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n'; } @@ -221,13 +217,6 @@ unsigned CheckOpcodeMatcher::getHashImpl() const { 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); } @@ -311,8 +300,6 @@ bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const { 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. diff --git a/llvm/utils/TableGen/DAGISelMatcher.h b/llvm/utils/TableGen/DAGISelMatcher.h index 9992c79a3296..8b6b32291429 100644 --- a/llvm/utils/TableGen/DAGISelMatcher.h +++ b/llvm/utils/TableGen/DAGISelMatcher.h @@ -25,7 +25,7 @@ namespace llvm { 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, @@ -449,33 +449,6 @@ private: 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 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(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 { diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index a828db30053b..279f036b3643 100644 --- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -282,16 +282,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, return CurrentIdx-StartIdx; } - case Matcher::CheckMultiOpcode: { - const CheckMultiOpcodeMatcher *CMO = cast(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(N)->getType()) << ",\n"; return 2; @@ -623,7 +614,6 @@ void MatcherTableEmitter::EmitHistogram(formatted_raw_ostream &OS) { 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; diff --git a/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/llvm/utils/TableGen/DAGISelMatcherGen.cpp index 5a253e8d202b..95cfa5b251ce 100644 --- a/llvm/utils/TableGen/DAGISelMatcherGen.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherGen.cpp @@ -97,7 +97,7 @@ namespace { delete PatWithNoTypes; } - void EmitMatcherCode(); + bool EmitMatcherCode(unsigned Variant); void EmitResultCode(); Matcher *GetMatcher() const { return TheMatcher; } @@ -247,20 +247,6 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) { // 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 &OpNodes = CP.getRootNodes(); - if (OpNodes.size() == 1) { - AddMatcher(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[0]))); - } else if (!OpNodes.empty()) { - SmallVector 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. @@ -495,7 +481,30 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N, 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 &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 @@ -503,11 +512,11 @@ void MatcherGen::EmitMatcherCode() { // 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; } @@ -849,13 +858,16 @@ void MatcherGen::EmitResultCode() { } +/// 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 diff --git a/llvm/utils/TableGen/DAGISelMatcherOpt.cpp b/llvm/utils/TableGen/DAGISelMatcherOpt.cpp index 41ce6ae69133..0e89fa028f59 100644 --- a/llvm/utils/TableGen/DAGISelMatcherOpt.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherOpt.cpp @@ -153,8 +153,7 @@ static void ContractNodes(OwningPtr &MatcherPtr, // like X86 where many operations are valid on multiple types. if ((isa(N) || isa(N) || isa(N)) && - (isa(N->getNext()) || - isa(N->getNext()))) { + isa(N->getNext())) { // Unlink the two nodes from the list. Matcher *CheckType = MatcherPtr.take(); Matcher *CheckOpcode = CheckType->takeNext();