Added support for overloading intrinsics (atomics) based on pointers
to different address spaces.  This alters the naming scheme for those
intrinsics, e.g., atomic.load.add.i32 => atomic.load.add.i32.p0i32


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54195 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 1948c90..1e95783 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -443,8 +443,8 @@
     return true;
   }
 
-  if (getExtTypeNum(0) == MVT::iPTR) {
-    if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == EMVT::isInt)
+  if (getExtTypeNum(0) == MVT::iPTR || getExtTypeNum(0) == MVT::iPTRAny) {
+    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);
@@ -463,7 +463,8 @@
     setTypes(FVTs);
     return true;
   }
-  if (ExtVTs[0] == MVT::iPTR && EMVT::isExtIntegerInVTs(getExtTypes())) {
+  if ((ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny) &&
+      EMVT::isExtIntegerInVTs(getExtTypes())) {
     //assert(hasTypeSet() && "should be handled above!");
     std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
     if (getExtTypes() == FVTs)
@@ -495,7 +496,8 @@
     setTypes(ExtVTs);
     return true;
   }
-  if (getExtTypeNum(0) == EMVT::isInt && ExtVTs[0] == MVT::iPTR) {
+  if (getExtTypeNum(0) == EMVT::isInt &&
+      (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny)) {
     setTypes(ExtVTs);
     return true;
   }
@@ -527,6 +529,7 @@
   case EMVT::isFP : OS << ":isFP"; break;
   case EMVT::isUnknown: ; /*OS << ":?";*/ break;
   case MVT::iPTR:  OS << ":iPTR"; break;
+  case MVT::iPTRAny:  OS << ":iPTRAny"; break;
   default: {
     std::string VTName = llvm::getName(getTypeNum(0));
     // Strip off MVT:: prefix if present.
@@ -781,7 +784,7 @@
           assert(getTypeNum(i) == VT && "TreePattern has too many types!");
         
         VT = getTypeNum(0);
-        if (VT != MVT::iPTR) {
+        if (VT != MVT::iPTR && VT != MVT::iPTRAny) {
           unsigned Size = MVT(VT).getSizeInBits();
           // Make sure that the value is representable for this type.
           if (Size < 32) {
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index 50c39bc..4434cf0 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -182,13 +182,14 @@
   
   bool isLeaf() const { return Val != 0; }
   bool hasTypeSet() const {
-    return (Types[0] < MVT::LAST_VALUETYPE) || (Types[0] == MVT::iPTR);
+    return (Types[0] < MVT::LAST_VALUETYPE) || (Types[0] == MVT::iPTR) || 
+          (Types[0] == MVT::iPTRAny);
   }
   bool isTypeCompletelyUnknown() const {
     return Types[0] == EMVT::isUnknown;
   }
   bool isTypeDynamicallyResolved() const {
-    return Types[0] == MVT::iPTR;
+    return (Types[0] == MVT::iPTR) || (Types[0] == MVT::iPTRAny);
   }
   MVT::SimpleValueType getTypeNum(unsigned Num) const {
     assert(hasTypeSet() && "Doesn't have a type yet!");
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index a09068e..5ba37e5 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -65,6 +65,7 @@
   case MVT::v3i32: return "MVT::v3i32";
   case MVT::v3f32: return "MVT::v3f32";
   case MVT::iPTR:  return "TLI.getPointerTy()";
+  case MVT::iPTRAny:  return "TLI.getPointerTy()";
   default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
   }
 }
@@ -101,6 +102,7 @@
   case MVT::v3i32: return "MVT::v3i32";
   case MVT::v3f32: return "MVT::v3f32";
   case MVT::iPTR:  return "MVT::iPTR";
+  case MVT::iPTRAny:  return "MVT::iPTRAny";
   default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
   }
 }
@@ -459,7 +461,7 @@
     Record *TyEl = TypeList->getElementAsRecord(i);
     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
     MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
-    isOverloaded |= VT == MVT::iAny || VT == MVT::fAny;
+    isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
     ArgVTs.push_back(VT);
     ArgTypeDefs.push_back(TyEl);
   }
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index bfe44bf..c9ca971 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -56,7 +56,8 @@
           EMVT::isExtFloatingPointInVTs(P->getExtTypes()) ||
           P->getExtTypeNum(0) == MVT::isVoid ||
           P->getExtTypeNum(0) == MVT::Flag ||
-          P->getExtTypeNum(0) == MVT::iPTR) && 
+          P->getExtTypeNum(0) == MVT::iPTR ||
+          P->getExtTypeNum(0) == MVT::iPTRAny) && 
          "Not a valid pattern node to size!");
   unsigned Size = 3;  // The node itself.
   // If the root node is a ConstantSDNode, increases its size.
@@ -1828,6 +1829,8 @@
       std::string OpVTStr;
       if (OpVT == MVT::iPTR) {
         OpVTStr = "_iPTR";
+      } else if (OpVT == MVT::iPTRAny) {
+        OpVTStr = "_iPTRAny";
       } else if (OpVT == MVT::isVoid) {
         // Nodes with a void result actually have a first result type of either
         // Other (a chain) or Flag.  Since there is no one-to-one mapping from
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index ab7b58b..38a5255 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -162,6 +162,14 @@
     OS << "PointerType::getUnqual(";
     EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
     OS << ")";
+  } else if (VT == MVT::iPTRAny) {
+    // Make sure the user has passed us an argument type to overload. If not,
+    // treat it as an ordinary (not overloaded) intrinsic.
+    OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 
+    << "] : PointerType::getUnqual(";
+    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
+    OS << ")";
+    ++ArgNo;
   } else if (VT == MVT::isVoid) {
     if (ArgNo == 0)
       OS << "Type::VoidTy";