Beispiel #1
0
void MatcherTableEmitter::EmitNodePredicatesFunction(
    const std::vector<TreePredicateFn> &Preds, StringRef Decl,
    raw_ostream &OS) {
  if (Preds.empty())
    return;

  BeginEmitFunction(OS, "bool", Decl, true/*AddOverride*/);
  OS << "{\n";
  OS << "  switch (PredNo) {\n";
  OS << "  default: llvm_unreachable(\"Invalid predicate in table?\");\n";
  for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
    // Emit the predicate code corresponding to this pattern.
    TreePredicateFn PredFn = Preds[i];

    assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
    OS << "  case " << i << ": { \n";
    for (auto *SimilarPred :
          NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()])
      OS << "    // " << TreePredicateFn(SimilarPred).getFnName() <<'\n';

    OS << PredFn.getCodeToRunOnSDNode() << "\n  }\n";
  }
  OS << "  }\n";
  OS << "}\n";
  EndEmitFunction(OS);
}
void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
  // Emit pattern predicates.
  if (!PatternPredicates.empty()) {
    OS << "bool CheckPatternPredicate(unsigned PredNo) const override {\n";
    OS << "  switch (PredNo) {\n";
    OS << "  default: llvm_unreachable(\"Invalid predicate in table?\");\n";
    for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
      OS << "  case " << i << ": return "  << PatternPredicates[i] << ";\n";
    OS << "  }\n";
    OS << "}\n\n";
  }

  // Emit Node predicates.
  if (!NodePredicates.empty()) {
    OS << "bool CheckNodePredicate(SDNode *Node,\n";
    OS << "                        unsigned PredNo) const override {\n";
    OS << "  switch (PredNo) {\n";
    OS << "  default: llvm_unreachable(\"Invalid predicate in table?\");\n";
    for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) {
      // Emit the predicate code corresponding to this pattern.
      TreePredicateFn PredFn = NodePredicates[i];
      
      assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
      OS << "  case " << i << ": { \n";
      for (auto *SimilarPred :
           NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()])
        OS << "    // " << TreePredicateFn(SimilarPred).getFnName() <<'\n';
      
      OS << PredFn.getCodeToRunOnSDNode() << "\n  }\n";
    }
    OS << "  }\n";
    OS << "}\n\n";
  }

  // Emit CompletePattern matchers.
  // FIXME: This should be const.
  if (!ComplexPatterns.empty()) {
    OS << "bool CheckComplexPattern(SDNode *Root, SDNode *Parent,\n";
    OS << "                         SDValue N, unsigned PatternNo,\n";
    OS << "         SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) override {\n";
    OS << "  unsigned NextRes = Result.size();\n";
    OS << "  switch (PatternNo) {\n";
    OS << "  default: llvm_unreachable(\"Invalid pattern # in table?\");\n";
    for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {
      const ComplexPattern &P = *ComplexPatterns[i];
      unsigned NumOps = P.getNumOperands();

      if (P.hasProperty(SDNPHasChain))
        ++NumOps;  // Get the chained node too.

      OS << "  case " << i << ":\n";
      OS << "    Result.resize(NextRes+" << NumOps << ");\n";
      OS << "    return "  << P.getSelectFunc();

      OS << "(";
      // If the complex pattern wants the root of the match, pass it in as the
      // first argument.
      if (P.hasProperty(SDNPWantRoot))
        OS << "Root, ";

      // If the complex pattern wants the parent of the operand being matched,
      // pass it in as the next argument.
      if (P.hasProperty(SDNPWantParent))
        OS << "Parent, ";

      OS << "N";
      for (unsigned i = 0; i != NumOps; ++i)
        OS << ", Result[NextRes+" << i << "].first";
      OS << ");\n";
    }
    OS << "  }\n";
    OS << "}\n\n";
  }


  // Emit SDNodeXForm handlers.
  // FIXME: This should be const.
  if (!NodeXForms.empty()) {
    OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) override {\n";
    OS << "  switch (XFormNo) {\n";
    OS << "  default: llvm_unreachable(\"Invalid xform # in table?\");\n";

    // FIXME: The node xform could take SDValue's instead of SDNode*'s.
    for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) {
      const CodeGenDAGPatterns::NodeXForm &Entry =
        CGP.getSDNodeTransform(NodeXForms[i]);

      Record *SDNode = Entry.first;
      const std::string &Code = Entry.second;

      OS << "  case " << i << ": {  ";
      if (!OmitComments)
        OS << "// " << NodeXForms[i]->getName();
      OS << '\n';

      std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName();
      if (ClassName == "SDNode")
        OS << "    SDNode *N = V.getNode();\n";
      else
        OS << "    " << ClassName << " *N = cast<" << ClassName
           << ">(V.getNode());\n";
      OS << Code << "\n  }\n";
    }
    OS << "  }\n";
    OS << "}\n\n";
  }
}