Expose "noduplicate" attribute as a property for intrinsics.
[oota-llvm.git] / utils / TableGen / IntrinsicEmitter.cpp
index 173e50653274154483a2be8299d617ad89cbb11d..1b281288a4ed579c21d09ff6a6b36837b6e34e8c 100644 (file)
@@ -131,20 +131,6 @@ void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
   OS << "#endif\n\n";
 }
 
-struct IntrinsicNameSorter {
-  IntrinsicNameSorter(const std::vector<CodeGenIntrinsic> &I)
-  : Ints(I) {}
-
-  // Sort in reverse order of intrinsic name so "abc.def" appears after
-  // "abd.def.ghi" in the overridden name matcher
-  bool operator()(unsigned i, unsigned j) {
-    return Ints[i].Name > Ints[j].Name;
-  }
-
-private:
-  const std::vector<CodeGenIntrinsic> &Ints;
-};
-
 void IntrinsicEmitter::
 EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
                      raw_ostream &OS) {
@@ -158,15 +144,17 @@ EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
   OS << "  StringRef NameR(Name+6, Len-6);   // Skip over 'llvm.'\n";
   OS << "  switch (Name[5]) {                  // Dispatch on first letter.\n";
   OS << "  default: break;\n";
-  IntrinsicNameSorter Sorter(Ints);
   // Emit the intrinsic matching stuff by first letter.
   for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(),
        E = IntMapping.end(); I != E; ++I) {
     OS << "  case '" << I->first << "':\n";
     std::vector<unsigned> &IntList = I->second;
 
-    // Sort intrinsics in reverse order of their names
-    std::sort(IntList.begin(), IntList.end(), Sorter);
+    // Sort in reverse order of intrinsic name so "abc.def" appears after
+    // "abd.def.ghi" in the overridden name matcher
+    std::sort(IntList.begin(), IntList.end(), [&](unsigned i, unsigned j) {
+      return Ints[i].Name > Ints[j].Name;
+    });
 
     // Emit all the overloaded intrinsics first, build a table of the
     // non-overloaded ones.
@@ -514,6 +502,9 @@ struct AttributeComparator {
     if (L->canThrow != R->canThrow)
       return R->canThrow;
 
+    if (L->isNoDuplicate != R->isNoDuplicate)
+      return R->isNoDuplicate;
+
     if (L->isNoReturn != R->isNoReturn)
       return R->isNoReturn;
 
@@ -628,7 +619,8 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
 
     ModRefKind modRef = getModRefKind(intrinsic);
 
-    if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn) {
+    if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn ||
+        intrinsic.isNoDuplicate) {
       OS << "      const Attribute::AttrKind Atts[] = {";
       bool addComma = false;
       if (!intrinsic.canThrow) {
@@ -641,6 +633,12 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
         OS << "Attribute::NoReturn";
         addComma = true;
       }
+      if (intrinsic.isNoDuplicate) {
+        if (addComma)
+          OS << ",";
+        OS << "Attribute::NoDuplicate";
+        addComma = true;
+      }
 
       switch (modRef) {
       case MRK_none: break;
@@ -666,6 +664,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
       OS << "      }\n";
     } else {
       OS << "      return AttributeSet();\n";
+      OS << "      }\n";
     }
   }