[TableGen] Add a space between type and '*' in front of a variable name in output...
[oota-llvm.git] / utils / TableGen / CodeGenDAGPatterns.cpp
index e5c6613edfd38b03116888115b51c61267ac69a5..a91ed1854617ed7f1e7a449d963436998a207bfd 100644 (file)
@@ -350,7 +350,7 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
 
 
 /// EnforceSmallerThan - 'this' must be a smaller VT than Other. For vectors
-/// this shoud be based on the element type. Update this and other based on
+/// this should be based on the element type. Update this and other based on
 /// this information.
 bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
   if (TP.hasError())
@@ -389,52 +389,6 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
   else if (!Other.hasScalarTypes())
     MadeChange |= EnforceVector(TP);
 
-  // For vectors we need to ensure that smaller size doesn't produce larger
-  // vector and vice versa.
-  if (isConcrete() && isVector(getConcrete())) {
-    MVT IVT = getConcrete();
-    unsigned Size = IVT.getSizeInBits();
-
-    // Only keep types that have at least as many bits.
-    TypeSet InputSet(Other);
-
-    for (unsigned i = 0; i != Other.TypeVec.size(); ++i) {
-      assert(isVector(Other.TypeVec[i]) && "EnforceVector didn't work");
-      if (MVT(Other.TypeVec[i]).getSizeInBits() < Size) {
-        Other.TypeVec.erase(Other.TypeVec.begin()+i--);
-        MadeChange = true;
-      }
-    }
-
-    if (Other.TypeVec.empty()) {  // FIXME: Really want an SMLoc here!
-      TP.error("Type inference contradiction found, forcing '" +
-               InputSet.getName() + "' to have at least as many bits as " +
-               getName() + "'");
-      return false;
-    }
-  } else if (Other.isConcrete() && isVector(Other.getConcrete())) {
-    MVT IVT = Other.getConcrete();
-    unsigned Size = IVT.getSizeInBits();
-
-    // Only keep types with the same or fewer total bits
-    TypeSet InputSet(*this);
-
-    for (unsigned i = 0; i != TypeVec.size(); ++i) {
-      assert(isVector(TypeVec[i]) && "EnforceVector didn't work");
-      if (MVT(TypeVec[i]).getSizeInBits() > Size) {
-        TypeVec.erase(TypeVec.begin()+i--);
-        MadeChange = true;
-      }
-    }
-
-    if (TypeVec.empty()) {  // FIXME: Really want an SMLoc here!
-      TP.error("Type inference contradiction found, forcing '" +
-               InputSet.getName() + "' to have the same or fewer bits than " +
-               Other.getName() + "'");
-      return false;
-    }
-  }
-
   // This code does not currently handle nodes which have multiple types,
   // where some types are integer, and some are fp.  Assert that this is not
   // the case.
@@ -445,12 +399,22 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
   if (TP.hasError())
     return false;
 
-  // Okay, find the smallest scalar type from the other set and remove
-  // anything the same or smaller from the current set.
+  // Okay, find the smallest type from current set and remove anything the
+  // same or smaller from the other set. We need to ensure that the scalar
+  // type size is smaller than the scalar size of the smallest type. For
+  // vectors, we also need to make sure that the total size is no larger than
+  // the size of the smallest type.
   TypeSet InputSet(Other);
-  MVT::SimpleValueType Smallest = TypeVec[0];
+  MVT Smallest = TypeVec[0];
   for (unsigned i = 0; i != Other.TypeVec.size(); ++i) {
-    if (Other.TypeVec[i] <= Smallest) {
+    MVT OtherVT = Other.TypeVec[i];
+    // Don't compare vector and non-vector types.
+    if (OtherVT.isVector() != Smallest.isVector())
+      continue;
+    // The getSizeInBits() check here is only needed for vectors, but is
+    // a subset of the scalar check for scalars so no need to qualify.
+    if (OtherVT.getScalarSizeInBits() <= Smallest.getScalarSizeInBits() ||
+        OtherVT.getSizeInBits() < Smallest.getSizeInBits()) {
       Other.TypeVec.erase(Other.TypeVec.begin()+i--);
       MadeChange = true;
     }
@@ -462,12 +426,22 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
     return false;
   }
 
-  // Okay, find the largest scalar type from the other set and remove
-  // anything the same or larger from the current set.
+  // Okay, find the largest type from the other set and remove anything the
+  // same or smaller from the current set. We need to ensure that the scalar
+  // type size is larger than the scalar size of the largest type. For
+  // vectors, we also need to make sure that the total size is no smaller than
+  // the size of the largest type.
   InputSet = TypeSet(*this);
-  MVT::SimpleValueType Largest = Other.TypeVec[Other.TypeVec.size()-1];
+  MVT Largest = Other.TypeVec[Other.TypeVec.size()-1];
   for (unsigned i = 0; i != TypeVec.size(); ++i) {
-    if (TypeVec[i] >= Largest) {
+    MVT OtherVT = TypeVec[i];
+    // Don't compare vector and non-vector types.
+    if (OtherVT.isVector() != Largest.isVector())
+      continue;
+    // The getSizeInBits() check here is only needed for vectors, but is
+    // a subset of the scalar check for scalars so no need to qualify.
+    if (OtherVT.getScalarSizeInBits() >= Largest.getScalarSizeInBits() ||
+         OtherVT.getSizeInBits() > Largest.getSizeInBits()) {
       TypeVec.erase(TypeVec.begin()+i--);
       MadeChange = true;
     }
@@ -482,7 +456,7 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
   return MadeChange;
 }
 
-/// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
+/// EnforceVectorEltTypeIs - 'this' is now constrained to be a vector type
 /// whose element is specified by VTOperand.
 bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT,
                                            TreePattern &TP) {
@@ -510,7 +484,7 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(MVT::SimpleValueType VT,
   return MadeChange;
 }
 
-/// EnforceVectorEltTypeIs - 'this' is now constrainted to be a vector type
+/// EnforceVectorEltTypeIs - 'this' is now constrained to be a vector type
 /// whose element is specified by VTOperand.
 bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand,
                                            TreePattern &TP) {
@@ -556,7 +530,7 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand,
   return MadeChange;
 }
 
-/// EnforceVectorSubVectorTypeIs - 'this' is now constrainted to be a
+/// EnforceVectorSubVectorTypeIs - 'this' is now constrained to be a
 /// vector type specified by VTOperand.
 bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand,
                                                  TreePattern &TP) {
@@ -637,7 +611,7 @@ bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand,
   return MadeChange;
 }
 
-/// EnforceVectorSameNumElts - 'this' is now constrainted to
+/// EnforceVectorSameNumElts - 'this' is now constrained to
 /// be a vector with same num elements as VTOperand.
 bool EEVT::TypeSet::EnforceVectorSameNumElts(EEVT::TypeSet &VTOperand,
                                              TreePattern &TP) {
@@ -797,7 +771,7 @@ std::string TreePredicateFn::getCodeToRunOnSDNode() const {
   if (ClassName == "SDNode")
     Result = "    SDNode *N = Node;\n";
   else
-    Result = "    " + ClassName + "*N = cast<" + ClassName + ">(Node);\n";
+    Result = "    auto *N = cast<" + ClassName + ">(Node);\n";
   
   return Result + getPredCode();
 }
@@ -868,8 +842,8 @@ getPatternComplexity(const CodeGenDAGPatterns &CGP) const {
 ///
 std::string PatternToMatch::getPredicateCheck() const {
   std::string PredicateCheck;
-  for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
-    if (DefInit *Pred = dyn_cast<DefInit>(Predicates->getElement(i))) {
+  for (Init *I : Predicates->getValues()) {
+    if (DefInit *Pred = dyn_cast<DefInit>(I)) {
       Record *Def = Pred->getDef();
       if (!Def->isSubClassOf("Predicate")) {
 #ifndef NDEBUG
@@ -939,8 +913,7 @@ SDTypeConstraint::SDTypeConstraint(Record *R) {
     x.SDTCisSameNumEltsAs_Info.OtherOperandNum =
       R->getValueAsInt("OtherOperandNum");
   } else {
-    errs() << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n";
-    exit(1);
+    PrintFatalError("Unrecognized SDTypeConstraint '" + R->getName() + "'!\n");
   }
 }
 
@@ -958,11 +931,12 @@ static TreePatternNode *getOperandNum(unsigned OpNo, TreePatternNode *N,
   OpNo -= NumResults;
 
   if (OpNo >= N->getNumChildren()) {
-    errs() << "Invalid operand number in type constraint "
+    std::string S;
+    raw_string_ostream OS(S);
+    OS << "Invalid operand number in type constraint "
            << (OpNo+NumResults) << " ";
-    N->dump();
-    errs() << '\n';
-    exit(1);
+    N->print(OS);
+    PrintFatalError(OS.str());
   }
 
   return N->getChild(OpNo);
@@ -1142,9 +1116,9 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
     } else if (PropList[i]->getName() == "SDNPVariadic") {
       Properties |= 1 << SDNPVariadic;
     } else {
-      errs() << "Unknown SD Node property '" << PropList[i]->getName()
-             << "' on node '" << R->getName() << "'!\n";
-      exit(1);
+      PrintFatalError("Unknown SD Node property '" +
+                      PropList[i]->getName() + "' on node '" +
+                      R->getName() + "'!");
     }
   }
 
@@ -1222,8 +1196,16 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
   if (Operator->isSubClassOf("Instruction")) {
     CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator);
 
-    // FIXME: Should allow access to all the results here.
-    unsigned NumDefsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;
+    unsigned NumDefsToAdd = InstInfo.Operands.NumDefs;
+
+    // Subtract any defaulted outputs.
+    for (unsigned i = 0; i != InstInfo.Operands.NumDefs; ++i) {
+      Record *OperandNode = InstInfo.Operands[i].Rec;
+
+      if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
+          !CDP.getDefaultOperand(OperandNode).DefaultOps.empty())
+        --NumDefsToAdd;
+    }
 
     // Add on one implicit def if it has a resolvable type.
     if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other)
@@ -1241,8 +1223,7 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
     return 1;
 
   Operator->dump();
-  errs() << "Unhandled node in GetNumNodeResults\n";
-  exit(1);
+  PrintFatalError("Unhandled node in GetNumNodeResults");
 }
 
 void TreePatternNode::print(raw_ostream &OS) const {
@@ -1800,8 +1781,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
 
     // Apply the result types to the node, these come from the things in the
     // (outs) list of the instruction.
-    // FIXME: Cap at one result so far.
-    unsigned NumResultsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;
+    unsigned NumResultsToAdd = std::min(InstInfo.Operands.NumDefs,
+                                        Inst.getNumResults());
     for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo)
       MadeChange |= UpdateNodeTypeFromInst(ResNo, Inst.getResult(ResNo), TP);
 
@@ -2018,8 +1999,8 @@ bool TreePatternNode::canPatternMatch(std::string &Reason,
 TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
                          CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp),
                          isInputPattern(isInput), HasError(false) {
-  for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
-    Trees.push_back(ParseTreePattern(RawPat->getElement(i), ""));
+  for (Init *I : RawPat->getValues())
+    Trees.push_back(ParseTreePattern(I, ""));
 }
 
 TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
@@ -2082,7 +2063,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){
   }
 
   // ?:$name or just $name.
-  if (TheInit == UnsetInit::get()) {
+  if (isa<UnsetInit>(TheInit)) {
     if (OpName.empty())
       error("'?' argument requires a name to match with operand list");
     TreePatternNode *Res = new TreePatternNode(TheInit, 1);
@@ -2162,7 +2143,8 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){
         Operator->getName() != "tblockaddress" &&
         Operator->getName() != "tglobaladdr" &&
         Operator->getName() != "bb" &&
-        Operator->getName() != "vt")
+        Operator->getName() != "vt" &&
+        Operator->getName() != "mcsym")
       error("Cannot use '" + Operator->getName() + "' in an output pattern!");
   }
 
@@ -2391,10 +2373,9 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) :
 
 Record *CodeGenDAGPatterns::getSDNodeNamed(const std::string &Name) const {
   Record *N = Records.getDef(Name);
-  if (!N || !N->isSubClassOf("SDNode")) {
-    errs() << "Error getting SDNode '" << Name << "'!\n";
-    exit(1);
-  }
+  if (!N || !N->isSubClassOf("SDNode"))
+    PrintFatalError("Error getting SDNode '" + Name + "'!");
+
   return N;
 }
 
@@ -2834,7 +2815,7 @@ static bool InferFromPattern(CodeGenInstruction &InstInfo,
 
   if (InstInfo.mayLoad != PatInfo.mayLoad && !InstInfo.mayLoad_Unset) {
     // Allow explicitly setting mayLoad = 1, even when the pattern has no loads.
-    // Some targets translate imediates to loads.
+    // Some targets translate immediates to loads.
     if (!InstInfo.mayLoad) {
       Error = true;
       PrintError(PatDef->getLoc(), "Pattern doesn't match mayLoad = " +
@@ -2880,8 +2861,8 @@ static bool hasNullFragReference(DagInit *DI) {
 /// hasNullFragReference - Return true if any DAG in the list references
 /// the null_frag operator.
 static bool hasNullFragReference(ListInit *LI) {
-  for (unsigned i = 0, e = LI->getSize(); i != e; ++i) {
-    DagInit *DI = dyn_cast<DagInit>(LI->getElement(i));
+  for (Init *I : LI->getValues()) {
+    DagInit *DI = dyn_cast<DagInit>(I);
     assert(DI && "non-dag in an instruction Pattern list?!");
     if (hasNullFragReference(DI))
       return true;
@@ -2967,7 +2948,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern(
 
   // Check that all of the results occur first in the list.
   std::vector<Record*> Results;
-  TreePatternNode *Res0Node = nullptr;
+  SmallVector<TreePatternNode *, 2> ResNodes;
   for (unsigned i = 0; i != NumResults; ++i) {
     if (i == CGI.Operands.size())
       I->error("'" + InstResults.begin()->first +
@@ -2979,8 +2960,8 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern(
     if (!RNode)
       I->error("Operand $" + OpName + " does not exist in operand list!");
 
-    if (i == 0)
-      Res0Node = RNode;
+    ResNodes.push_back(RNode);
+
     Record *R = cast<DefInit>(RNode->getLeafValue())->getDef();
     if (!R)
       I->error("Operand $" + OpName + " should be a set destination: all "
@@ -3055,9 +3036,11 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern(
   TreePatternNode *ResultPattern =
     new TreePatternNode(I->getRecord(), ResultNodeOperands,
                         GetNumNodeResults(I->getRecord(), *this));
-  // Copy fully inferred output node type to instruction result pattern.
-  for (unsigned i = 0; i != NumResults; ++i)
-    ResultPattern->setType(i, Res0Node->getExtType(i));
+  // Copy fully inferred output node types to instruction result pattern.
+  for (unsigned i = 0; i != NumResults; ++i) {
+    assert(ResNodes[i]->getNumTypes() == 1 && "FIXME: Unhandled");
+    ResultPattern->setType(i, ResNodes[i]->getExtType(0));
+  }
 
   // Create and insert the instruction.
   // FIXME: InstImpResults should not be part of DAGInstruction.
@@ -3094,25 +3077,20 @@ void CodeGenDAGPatterns::ParseInstructions() {
     // null_frag operator is as-if no pattern were specified. Normally this
     // is from a multiclass expansion w/ a SDPatternOperator passed in as
     // null_frag.
-    if (!LI || LI->getSize() == 0 || hasNullFragReference(LI)) {
+    if (!LI || LI->empty() || hasNullFragReference(LI)) {
       std::vector<Record*> Results;
       std::vector<Record*> Operands;
 
       CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]);
 
       if (InstInfo.Operands.size() != 0) {
-        if (InstInfo.Operands.NumDefs == 0) {
-          // These produce no results
-          for (unsigned j = 0, e = InstInfo.Operands.size(); j < e; ++j)
-            Operands.push_back(InstInfo.Operands[j].Rec);
-        } else {
-          // Assume the first operand is the result.
-          Results.push_back(InstInfo.Operands[0].Rec);
-
-          // The rest are inputs.
-          for (unsigned j = 1, e = InstInfo.Operands.size(); j < e; ++j)
-            Operands.push_back(InstInfo.Operands[j].Rec);
-        }
+        for (unsigned j = 0, e = InstInfo.Operands.NumDefs; j < e; ++j)
+          Results.push_back(InstInfo.Operands[j].Rec);
+
+        // The rest are inputs.
+        for (unsigned j = InstInfo.Operands.NumDefs,
+               e = InstInfo.Operands.size(); j < e; ++j)
+          Operands.push_back(InstInfo.Operands[j].Rec);
       }
 
       // Create and insert the instruction.
@@ -3369,7 +3347,7 @@ void CodeGenDAGPatterns::VerifyInstructionFlags() {
       if (InstInfo.InferredFrom &&
           InstInfo.InferredFrom != InstInfo.TheDef &&
           InstInfo.InferredFrom != PTM.getSrcRecord())
-        PrintError(InstInfo.InferredFrom->getLoc(), "inferred from patttern");
+        PrintError(InstInfo.InferredFrom->getLoc(), "inferred from pattern");
     }
   }
   if (Errors)
@@ -3422,7 +3400,7 @@ void CodeGenDAGPatterns::ParsePatterns() {
     Pattern->InlinePatternFragments();
 
     ListInit *LI = CurPattern->getValueAsListInit("ResultInstrs");
-    if (LI->getSize() == 0) continue;  // no pattern.
+    if (LI->empty()) continue;  // no pattern.
 
     // Parse the instruction.
     TreePattern Result(CurPattern, LI, false, *this);
@@ -3595,7 +3573,7 @@ static void CombineChildVariants(TreePatternNode *Orig,
     }
 
     // Increment indices to the next permutation by incrementing the
-    // indicies from last index backward, e.g., generate the sequence
+    // indices from last index backward, e.g., generate the sequence
     // [0, 0], [0, 1], [1, 0], [1, 1].
     int IdxsIdx;
     for (IdxsIdx = Idxs.size() - 1; IdxsIdx >= 0; --IdxsIdx) {
@@ -3746,7 +3724,7 @@ static void GenerateVariantsOf(TreePatternNode *N,
       // operands are the commutative operands, and there might be more operands
       // after those.
       assert(NC >= 3 &&
-             "Commutative intrinsic should have at least 3 childrean!");
+             "Commutative intrinsic should have at least 3 children!");
       std::vector<std::vector<TreePatternNode*> > Variants;
       Variants.push_back(ChildVariants[0]); // Intrinsic id.
       Variants.push_back(ChildVariants[2]);
@@ -3821,13 +3799,11 @@ void CodeGenDAGPatterns::GenerateVariants() {
       if (AlreadyExists) continue;
 
       // Otherwise, add it to the list of patterns we have.
-      PatternsToMatch.
-        push_back(PatternToMatch(PatternsToMatch[i].getSrcRecord(),
-                                 PatternsToMatch[i].getPredicates(),
-                                 Variant, PatternsToMatch[i].getDstPattern(),
-                                 PatternsToMatch[i].getDstRegs(),
-                                 PatternsToMatch[i].getAddedComplexity(),
-                                 Record::getNewUID()));
+      PatternsToMatch.emplace_back(
+          PatternsToMatch[i].getSrcRecord(), PatternsToMatch[i].getPredicates(),
+          Variant, PatternsToMatch[i].getDstPattern(),
+          PatternsToMatch[i].getDstRegs(),
+          PatternsToMatch[i].getAddedComplexity(), Record::getNewUID());
     }
 
     DEBUG(errs() << "\n");