these utils don't need exports.
[oota-llvm.git] / utils / TableGen / CodeGenDAGPatterns.cpp
index 1e595dd4744a9e68390531118a8ed310ce7a4790..6e7dd1eae05dd9a946434f53196f2b939d24f9f5 100644 (file)
@@ -471,7 +471,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
   }
 
   if (getExtTypeNum(0) == MVT::iPTR || getExtTypeNum(0) == MVT::iPTRAny) {
-    if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny || ExtVTs[0] == EMVT::isInt)
+    if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny ||
+        ExtVTs[0] == EMVT::isInt)
       return false;
     if (EMVT::isExtIntegerInVTs(ExtVTs)) {
       std::vector<unsigned char> FVTs = FilterEVTs(ExtVTs, isInteger);
@@ -481,8 +482,9 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
       }
     }
   }
-  
-  if (ExtVTs[0] == EMVT::isInt && EMVT::isExtIntegerInVTs(getExtTypes())) {
+
+  if ((ExtVTs[0] == EMVT::isInt || ExtVTs[0] == MVT::iAny) &&
+      EMVT::isExtIntegerInVTs(getExtTypes())) {
     assert(hasTypeSet() && "should be handled above!");
     std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
     if (getExtTypes() == FVTs)
@@ -501,7 +503,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
       return true;
     }
   }      
-  if (ExtVTs[0] == EMVT::isFP  && EMVT::isExtFloatingPointInVTs(getExtTypes())) {
+  if ((ExtVTs[0] == EMVT::isFP || ExtVTs[0] == MVT::fAny) &&
+      EMVT::isExtFloatingPointInVTs(getExtTypes())) {
     assert(hasTypeSet() && "should be handled above!");
     std::vector<unsigned char> FVTs =
       FilterEVTs(getExtTypes(), isFloatingPoint);
@@ -516,9 +519,9 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
   //
   // Similarly, we should probably set the type here to the intersection of
   // {isInt|isFP} and ExtVTs
-  if ((getExtTypeNum(0) == EMVT::isInt &&
+  if (((getExtTypeNum(0) == EMVT::isInt || getExtTypeNum(0) == MVT::iAny) &&
        EMVT::isExtIntegerInVTs(ExtVTs)) ||
-      (getExtTypeNum(0) == EMVT::isFP &&
+      ((getExtTypeNum(0) == EMVT::isFP || getExtTypeNum(0) == MVT::fAny) &&
        EMVT::isExtFloatingPointInVTs(ExtVTs))) {
     setTypes(ExtVTs);
     return true;
@@ -579,8 +582,8 @@ void TreePatternNode::print(std::ostream &OS) const {
     OS << ")";
   }
   
-  if (!PredicateFn.empty())
-    OS << "<<P:" << PredicateFn << ">>";
+  for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i)
+    OS << "<<P:" << PredicateFns[i] << ">>";
   if (TransformFn)
     OS << "<<X:" << TransformFn->getName() << ">>";
   if (!getName().empty())
@@ -602,7 +605,7 @@ bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N,
                                      const MultipleUseVarSet &DepVars) const {
   if (N == this) return true;
   if (N->isLeaf() != isLeaf() || getExtTypes() != N->getExtTypes() ||
-      getPredicateFn() != N->getPredicateFn() ||
+      getPredicateFns() != N->getPredicateFns() ||
       getTransformFn() != N->getTransformFn())
     return false;
 
@@ -640,7 +643,7 @@ TreePatternNode *TreePatternNode::clone() const {
   }
   New->setName(getName());
   New->setTypes(getExtTypes());
-  New->setPredicateFn(getPredicateFn());
+  New->setPredicateFns(getPredicateFns());
   New->setTransformFn(getTransformFn());
   return New;
 }
@@ -658,9 +661,12 @@ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) {
       if (dynamic_cast<DefInit*>(Val) &&
           static_cast<DefInit*>(Val)->getDef()->getName() == "node") {
         // We found a use of a formal argument, replace it with its value.
-        Child = ArgMap[Child->getName()];
-        assert(Child && "Couldn't find formal argument!");
-        setChild(i, Child);
+        TreePatternNode *NewChild = ArgMap[Child->getName()];
+        assert(NewChild && "Couldn't find formal argument!");
+        assert((Child->getPredicateFns().empty() ||
+                NewChild->getPredicateFns() == Child->getPredicateFns()) &&
+               "Non-empty child predicate clobbered!");
+        setChild(i, NewChild);
       }
     } else {
       getChild(i)->SubstituteFormalArguments(ArgMap);
@@ -678,8 +684,16 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
   
   if (!Op->isSubClassOf("PatFrag")) {
     // Just recursively inline children nodes.
-    for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
-      setChild(i, getChild(i)->InlinePatternFragments(TP));
+    for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+      TreePatternNode *Child = getChild(i);
+      TreePatternNode *NewChild = Child->InlinePatternFragments(TP);
+
+      assert((Child->getPredicateFns().empty() ||
+              NewChild->getPredicateFns() == Child->getPredicateFns()) &&
+             "Non-empty child predicate clobbered!");
+
+      setChild(i, NewChild);
+    }
     return this;
   }
 
@@ -694,6 +708,10 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
 
   TreePatternNode *FragTree = Frag->getOnlyTree()->clone();
 
+  std::string Code = Op->getValueAsCode("Predicate");
+  if (!Code.empty())
+    FragTree->addPredicateFn("Predicate_"+Op->getName());
+
   // Resolve formal arguments to their actual value.
   if (Frag->getNumArgs()) {
     // Compute the map of formal to actual arguments.
@@ -706,7 +724,11 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
   
   FragTree->setName(getName());
   FragTree->UpdateNodeType(getExtTypes(), TP);
-  
+
+  // Transfer in the old predicates.
+  for (unsigned i = 0, e = getPredicateFns().size(); i != e; ++i)
+    FragTree->addPredicateFn(getPredicateFns()[i]);
+
   // Get a new copy of this fragment to stitch into here.
   //delete this;    // FIXME: implement refcounting!
   
@@ -787,7 +809,7 @@ TreePatternNode::isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const {
 }
 
 
-/// ApplyTypeConstraints - Apply all of the type constraints relevent to
+/// ApplyTypeConstraints - Apply all of the type constraints relevant to
 /// this node and its children in the tree.  This returns true if it makes a
 /// change, false otherwise.  If a type contradiction is found, throw an
 /// exception.
@@ -820,7 +842,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
               // If sign-extended doesn't fit, does it fit as unsigned?
               unsigned ValueMask;
               unsigned UnsignedVal;
-              ValueMask = unsigned(MVT(VT).getIntegerVTBitMask());
+              ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
               UnsignedVal = unsigned(II->getValue());
 
               if ((ValueMask & UnsignedVal) != UnsignedVal) {
@@ -866,18 +888,22 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
     bool MadeChange = false;
 
     // Apply the result type to the node.
-    MadeChange = UpdateNodeType(Int->ArgVTs[0], TP);
+    unsigned NumRetVTs = Int->IS.RetVTs.size();
+    unsigned NumParamVTs = Int->IS.ParamVTs.size();
+
+    for (unsigned i = 0, e = NumRetVTs; i != e; ++i)
+      MadeChange |= UpdateNodeType(Int->IS.RetVTs[i], TP);
 
-    if (getNumChildren() != Int->ArgVTs.size())
+    if (getNumChildren() != NumParamVTs + NumRetVTs)
       TP.error("Intrinsic '" + Int->Name + "' expects " +
-               utostr(Int->ArgVTs.size()-1) + " operands, not " +
-               utostr(getNumChildren()-1) + " operands!");
+               utostr(NumParamVTs + NumRetVTs - 1) + " operands, not " +
+               utostr(getNumChildren() - 1) + " operands!");
 
     // Apply type info to the intrinsic ID.
     MadeChange |= getChild(0)->UpdateNodeType(MVT::iPTR, TP);
     
-    for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
-      MVT::SimpleValueType OpVT = Int->ArgVTs[i];
+    for (unsigned i = NumRetVTs, e = getNumChildren(); i != e; ++i) {
+      MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i - NumRetVTs];
       MadeChange |= getChild(i)->UpdateNodeType(OpVT, TP);
       MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
     }
@@ -1213,7 +1239,7 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
 
     // If this intrinsic returns void, it must have side-effects and thus a
     // chain.
-    if (Int.ArgVTs[0] == MVT::isVoid) {
+    if (Int.IS.RetVTs[0] == MVT::isVoid) {
       Operator = getDAGPatterns().get_intrinsic_void_sdnode();
     } else if (Int.ModRef != CodeGenIntrinsic::NoMem) {
       // Has side-effects, requires chain.
@@ -1277,7 +1303,8 @@ void TreePattern::dump() const { print(*cerr.stream()); }
 
 // FIXME: REMOVE OSTREAM ARGUMENT
 CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
-  Intrinsics = LoadIntrinsics(Records);
+  Intrinsics = LoadIntrinsics(Records, false);
+  TgtIntrinsics = LoadIntrinsics(Records, true);
   ParseNodeInfo();
   ParseNodeTransforms();
   ParseComplexPatterns();
@@ -1405,7 +1432,7 @@ void CodeGenDAGPatterns::ParsePatternFragments() {
     // this fragment uses it.
     std::string Code = Fragments[i]->getValueAsCode("Predicate");
     if (!Code.empty())
-      P->getOnlyTree()->setPredicateFn("Predicate_"+Fragments[i]->getName());
+      P->getOnlyTree()->addPredicateFn("Predicate_"+Fragments[i]->getName());
     
     // If there is a node transformation corresponding to this, keep track of
     // it.
@@ -1911,7 +1938,7 @@ void CodeGenDAGPatterns::ParseInstructions() {
       TreePatternNode *OpNode = InVal->clone();
       
       // No predicate is useful on the result.
-      OpNode->setPredicateFn("");
+      OpNode->clearPredicateFns();
       
       // Promote the xform function to be an explicit node if set.
       if (Record *Xform = OpNode->getTransformFn()) {
@@ -2138,7 +2165,7 @@ static void CombineChildVariants(TreePatternNode *Orig,
     
     // Copy over properties.
     R->setName(Orig->getName());
-    R->setPredicateFn(Orig->getPredicateFn());
+    R->setPredicateFns(Orig->getPredicateFns());
     R->setTransformFn(Orig->getTransformFn());
     R->setTypes(Orig->getExtTypes());
     
@@ -2200,7 +2227,7 @@ static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N,
   Record *Operator = N->getOperator();
   
   // Only permit raw nodes.
-  if (!N->getName().empty() || !N->getPredicateFn().empty() ||
+  if (!N->getName().empty() || !N->getPredicateFns().empty() ||
       N->getTransformFn()) {
     Children.push_back(N);
     return;