Reapply 63765.  Patches for clang and llvm-gcc to follow.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63812 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index f3bdb4f..6e7dd1e 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -1303,7 +1303,8 @@
 
 // FIXME: REMOVE OSTREAM ARGUMENT
 CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
-  Intrinsics = LoadIntrinsics(Records);
+  Intrinsics = LoadIntrinsics(Records, false);
+  TgtIntrinsics = LoadIntrinsics(Records, true);
   ParseNodeInfo();
   ParseNodeTransforms();
   ParseComplexPatterns();
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index d44bfc9..0bd3165 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -465,6 +465,7 @@
   RecordKeeper &Records;
   CodeGenTarget Target;
   std::vector<CodeGenIntrinsic> Intrinsics;
+  std::vector<CodeGenIntrinsic> TgtIntrinsics;
   
   std::map<Record*, SDNodeInfo> SDNodes;
   std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
@@ -515,18 +516,25 @@
   const CodeGenIntrinsic &getIntrinsic(Record *R) const {
     for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
       if (Intrinsics[i].TheDef == R) return Intrinsics[i];
+    for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
+      if (TgtIntrinsics[i].TheDef == R) return TgtIntrinsics[i];
     assert(0 && "Unknown intrinsic!");
     abort();
   }
   
   const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const {
-    assert(IID-1 < Intrinsics.size() && "Bad intrinsic ID!");
-    return Intrinsics[IID-1];
+    if (IID-1 < Intrinsics.size())
+      return Intrinsics[IID-1];
+    if (IID-Intrinsics.size()-1 < TgtIntrinsics.size())
+      return TgtIntrinsics[IID-Intrinsics.size()-1];
+    assert(0 && "Bad intrinsic ID!");
   }
   
   unsigned getIntrinsicID(Record *R) const {
     for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
       if (Intrinsics[i].TheDef == R) return i;
+    for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
+      if (TgtIntrinsics[i].TheDef == R) return i + Intrinsics.size();
     assert(0 && "Unknown intrinsic!");
     abort();
   }
diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h
index dd99e31..fea868b 100644
--- a/utils/TableGen/CodeGenIntrinsics.h
+++ b/utils/TableGen/CodeGenIntrinsics.h
@@ -80,7 +80,8 @@
 
   /// LoadIntrinsics - Read all of the intrinsics defined in the specified
   /// .td file.
-  std::vector<CodeGenIntrinsic> LoadIntrinsics(const RecordKeeper &RC);
+  std::vector<CodeGenIntrinsic> LoadIntrinsics(const RecordKeeper &RC,
+                                               bool TargetOnly);
 }
 
 #endif
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 274cc78..9ef64d6 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -426,13 +426,17 @@
 // CodeGenIntrinsic Implementation
 //===----------------------------------------------------------------------===//
 
-std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC) {
+std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
+                                                   bool TargetOnly) {
   std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
   
   std::vector<CodeGenIntrinsic> Result;
 
-  for (unsigned i = 0, e = I.size(); i != e; ++i)
-    Result.push_back(CodeGenIntrinsic(I[i]));
+  for (unsigned i = 0, e = I.size(); i != e; ++i) {
+    bool isTarget = I[i]->getValueAsBit("isTarget");
+    if (isTarget == TargetOnly)
+      Result.push_back(CodeGenIntrinsic(I[i]));
+  }
   return Result;
 }
 
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index eda55e1..53081ff 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -25,7 +25,10 @@
 void IntrinsicEmitter::run(std::ostream &OS) {
   EmitSourceFileHeader("Intrinsic Function Source Fragment", OS);
   
-  std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records);
+  std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly);
+  
+  if (TargetOnly && !Ints.empty())
+    TargetPrefix = Ints[0].TargetPrefix;
 
   // Emit the enum information.
   EmitEnumInfo(Ints, OS);
@@ -91,12 +94,12 @@
     if (Ints[I->second].isOverloaded)
       OS << "    if (Len > " << I->first.size()
        << " && !memcmp(Name, \"" << I->first << ".\", "
-       << (I->first.size() + 1) << ")) return Intrinsic::"
+       << (I->first.size() + 1) << ")) return " << TargetPrefix << "Intrinsic::"
        << Ints[I->second].EnumName << ";\n";
     else 
       OS << "    if (Len == " << I->first.size()
          << " && !memcmp(Name, \"" << I->first << "\", "
-         << I->first.size() << ")) return Intrinsic::"
+         << I->first.size() << ")) return " << TargetPrefix << "Intrinsic::"
          << Ints[I->second].EnumName << ";\n";
   }
   OS << "  }\n";
@@ -351,11 +354,13 @@
                              Ints[i].IS.ParamTypeDefs)].push_back(i);
 
   // Loop through the array, emitting one generator for each batch.
+  std::string IntrinsicStr = TargetPrefix + "Intrinsic::";
+  
   for (MapTy::iterator I = UniqueArgInfos.begin(),
        E = UniqueArgInfos.end(); I != E; ++I) {
     for (unsigned i = 0, e = I->second.size(); i != e; ++i)
-      OS << "  case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
-         << Ints[I->second[i]].Name << "\n";
+      OS << "  case " << IntrinsicStr << Ints[I->second[i]].EnumName 
+         << ":\t\t// " << Ints[I->second[i]].Name << "\n";
     
     const RecPair &ArgTypes = I->first;
     const std::vector<Record*> &RetTys = ArgTypes.first;
@@ -392,7 +397,11 @@
 EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
   OS << "// Add parameter attributes that are not common to all intrinsics.\n";
   OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
-  OS << "AttrListPtr Intrinsic::getAttributes(ID id) {";
+  if (TargetOnly)
+    OS << "static AttrListPtr getAttributes(" << TargetPrefix 
+       << "Intrinsic::ID id) {";
+  else
+    OS << "AttrListPtr Intrinsic::getAttributes(ID id) {";
   OS << "  // No intrinsic can throw exceptions.\n";
   OS << "  Attributes Attr = Attribute::NoUnwind;\n";
   OS << "  switch (id) {\n";
@@ -404,7 +413,8 @@
     switch (Ints[i].ModRef) {
     default: break;
     case CodeGenIntrinsic::NoMem:
-      OS << "  case Intrinsic::" << Ints[i].EnumName << ":\n";
+      OS << "  case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 
+         << ":\n";
       break;
     }
   }
@@ -415,7 +425,8 @@
     default: break;
     case CodeGenIntrinsic::ReadArgMem:
     case CodeGenIntrinsic::ReadMem:
-      OS << "  case Intrinsic::" << Ints[i].EnumName << ":\n";
+      OS << "  case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 
+         << ":\n";
       break;
     }
   }
@@ -431,7 +442,8 @@
   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
     if (Ints[i].ArgumentAttributes.empty()) continue;
     
-    OS << "  case Intrinsic::" << Ints[i].EnumName << ":\n";
+    OS << "  case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 
+       << ":\n";
 
     std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs =
       Ints[i].ArgumentAttributes;
@@ -495,7 +507,7 @@
 typedef std::map<std::string, std::string>::const_iterator StrMapIterator;
 static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End,
                                    unsigned CharStart, unsigned Indent,
-                                   std::ostream &OS) {
+                                   std::string TargetPrefix, std::ostream &OS) {
   if (Start == End) return; // empty range.
   
   // Determine what, if anything, is the same about all these strings.
@@ -522,7 +534,8 @@
       OS << CommonString.size() - CharStart << "))\n";
       ++Indent;
     }
-    OS << std::string(Indent*2, ' ') << "IntrinsicID = Intrinsic::";
+    OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix
+       << "Intrinsic::";
     OS << Start->second << ";\n";
     return;
   }
@@ -535,7 +548,8 @@
     OS << ", \"" << (CommonString.c_str()+CharStart) << "\", ";
     OS << CommonString.size()-CharStart << ")) {\n";
     
-    EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, OS);
+    EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, 
+                           TargetPrefix, OS);
     OS << std::string(Indent*2, ' ') << "}\n";
     return;
   }
@@ -556,7 +570,7 @@
     for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar;
          ++NextChar)
       /*empty*/;
-    EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, OS);
+    EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS);
     OS << std::string(Indent*2, ' ') << "  break;\n";
     I = NextChar;
   }
@@ -566,6 +580,7 @@
 /// EmitTargetBuiltins - All of the builtins in the specified map are for the
 /// same target, and we already checked it.
 static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM,
+                               const std::string &TargetPrefix,
                                std::ostream &OS) {
   // Rearrange the builtins by length.
   std::vector<std::map<std::string, std::string> > BuiltinsByLen;
@@ -584,7 +599,7 @@
     if (BuiltinsByLen[i].empty()) continue;
     OS << "    case " << i << ":\n";
     EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(),
-                           0, 3, OS);
+                           0, 3, TargetPrefix, OS);
     OS << "      break;\n";
   }
   OS << "    }\n";
@@ -613,7 +628,22 @@
   OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
   OS << "// in as TargetPrefix.  The result is assigned to 'IntrinsicID'.\n";
   OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
-  OS << "  IntrinsicID = Intrinsic::not_intrinsic;\n";
+  
+  if (TargetOnly) {
+    OS << "static " << TargetPrefix << "Intrinsic::ID "
+       << "getIntrinsicForGCCBuiltin(const char "
+       << "*TargetPrefix, const char *BuiltinName) {\n";
+    OS << "  " << TargetPrefix << "Intrinsic::ID IntrinsicID = ";
+  } else {
+    OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
+       << "*TargetPrefix, const char *BuiltinName) {\n";
+    OS << "  Intrinsic::ID IntrinsicID = ";
+  }
+  
+  if (TargetOnly)
+    OS << "(" << TargetPrefix<< "Intrinsic::ID)";
+
+  OS << "Intrinsic::not_intrinsic;\n";
   
   // Note: this could emit significantly better code if we cared.
   for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){
@@ -625,8 +655,10 @@
     OS << "{\n";
 
     // Emit the comparisons for this target prefix.
-    EmitTargetBuiltins(I->second, OS);
+    EmitTargetBuiltins(I->second, TargetPrefix, OS);
     OS << "  }\n";
   }
+  OS << "  return IntrinsicID;\n";
+  OS << "}\n";
   OS << "#endif\n\n";
 }
diff --git a/utils/TableGen/IntrinsicEmitter.h b/utils/TableGen/IntrinsicEmitter.h
index 3573692..0f3f0e7 100644
--- a/utils/TableGen/IntrinsicEmitter.h
+++ b/utils/TableGen/IntrinsicEmitter.h
@@ -20,9 +20,12 @@
 namespace llvm {
   class IntrinsicEmitter : public TableGenBackend {
     RecordKeeper &Records;
+    bool TargetOnly;
+    std::string TargetPrefix;
     
   public:
-    IntrinsicEmitter(RecordKeeper &R) : Records(R) {}
+    IntrinsicEmitter(RecordKeeper &R, bool T = false) 
+      : Records(R), TargetOnly(T) {}
 
     void run(std::ostream &OS);
     
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index c6692f8..98a188e 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -49,6 +49,7 @@
   GenFastISel,
   GenSubtarget,
   GenIntrinsic,
+  GenTgtIntrinsic,
   GenLLVMCConf,
   PrintEnums
 };
@@ -82,6 +83,8 @@
                                "Generate subtarget enumerations"),
                     clEnumValN(GenIntrinsic, "gen-intrinsic",
                                "Generate intrinsic information"),
+                    clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic",
+                               "Generate target intrinsic information"),
                     clEnumValN(GenLLVMCConf, "gen-llvmc",
                                "Generate LLVMC configuration library"),
                     clEnumValN(PrintEnums, "print-enums",
@@ -190,6 +193,9 @@
     case GenIntrinsic:
       IntrinsicEmitter(Records).run(*Out);
       break;
+    case GenTgtIntrinsic:
+      IntrinsicEmitter(Records, true).run(*Out);
+      break;
     case GenLLVMCConf:
       LLVMCConfigurationEmitter(Records).run(*Out);
       break;