rdar://11542750 - llvm.trap should be marked no return.
[oota-llvm.git] / utils / TableGen / IntrinsicEmitter.cpp
index 9c024a4981aff6a5f9cd7463acdcf386ce4ce299..9e2bb9d87f2402982b658c05edd70520fd6f2dbf 100644 (file)
@@ -46,9 +46,6 @@ void IntrinsicEmitter::run(raw_ostream &OS) {
   // Emit the function name recognizer.
   EmitFnNameRecognizer(Ints, OS);
   
-  // Emit the intrinsic verifier.
-  EmitVerifier(Ints, OS);
-  
   // Emit the intrinsic declaration generator.
   EmitGenerator(Ints, OS);
   
@@ -175,140 +172,6 @@ EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints,
   OS << "#endif\n\n";
 }
 
-/// RecordListComparator - Provide a deterministic comparator for lists of
-/// records.
-namespace {
-  typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair;
-  struct RecordListComparator {
-    bool operator()(const RecPair &LHS,
-                    const RecPair &RHS) const {
-      unsigned i = 0;
-      const std::vector<Record*> *LHSVec = &LHS.first;
-      const std::vector<Record*> *RHSVec = &RHS.first;
-      unsigned RHSSize = RHSVec->size();
-      unsigned LHSSize = LHSVec->size();
-
-      for (; i != LHSSize; ++i) {
-        if (i == RHSSize) return false;  // RHS is shorter than LHS.
-        if ((*LHSVec)[i] != (*RHSVec)[i])
-          return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
-      }
-
-      if (i != RHSSize) return true;
-
-      i = 0;
-      LHSVec = &LHS.second;
-      RHSVec = &RHS.second;
-      RHSSize = RHSVec->size();
-      LHSSize = LHSVec->size();
-
-      for (i = 0; i != LHSSize; ++i) {
-        if (i == RHSSize) return false;  // RHS is shorter than LHS.
-        if ((*LHSVec)[i] != (*RHSVec)[i])
-          return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
-      }
-
-      return i != RHSSize;
-    }
-  };
-}
-
-void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 
-                                    raw_ostream &OS) {
-  OS << "// Verifier::visitIntrinsicFunctionCall code.\n";
-  OS << "#ifdef GET_INTRINSIC_VERIFIER\n";
-  OS << "  switch (ID) {\n";
-  OS << "  default: llvm_unreachable(\"Invalid intrinsic!\");\n";
-  
-  // This checking can emit a lot of very common code.  To reduce the amount of
-  // code that we emit, batch up cases that have identical types.  This avoids
-  // problems where GCC can run out of memory compiling Verifier.cpp.
-  typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
-  MapTy UniqueArgInfos;
-  
-  // Compute the unique argument type info.
-  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
-    UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
-                             Ints[i].IS.ParamTypeDefs)].push_back(i);
-
-  // Loop through the array, emitting one comparison for each batch.
-  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";
-    
-    const RecPair &ArgTypes = I->first;
-    const std::vector<Record*> &RetTys = ArgTypes.first;
-    const std::vector<Record*> &ParamTys = ArgTypes.second;
-    std::vector<unsigned> OverloadedTypeIndices;
-
-    OS << "    VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", "
-       << ParamTys.size();
-
-    // Emit return types.
-    for (unsigned j = 0, je = RetTys.size(); j != je; ++j) {
-      Record *ArgType = RetTys[j];
-      OS << ", ";
-
-      if (ArgType->isSubClassOf("LLVMMatchType")) {
-        unsigned Number = ArgType->getValueAsInt("Number");
-        assert(Number < OverloadedTypeIndices.size() &&
-               "Invalid matching number!");
-        Number = OverloadedTypeIndices[Number];
-        if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
-          OS << "~(ExtendedElementVectorType | " << Number << ")";
-        else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
-          OS << "~(TruncatedElementVectorType | " << Number << ")";
-        else
-          OS << "~" << Number;
-      } else {
-        MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
-        OS << getEnumName(VT);
-
-        if (EVT(VT).isOverloaded())
-          OverloadedTypeIndices.push_back(j);
-
-        if (VT == MVT::isVoid && j != 0 && j != je - 1)
-          throw "Var arg type not last argument";
-      }
-    }
-
-    // Emit the parameter types.
-    for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) {
-      Record *ArgType = ParamTys[j];
-      OS << ", ";
-
-      if (ArgType->isSubClassOf("LLVMMatchType")) {
-        unsigned Number = ArgType->getValueAsInt("Number");
-        assert(Number < OverloadedTypeIndices.size() &&
-               "Invalid matching number!");
-        Number = OverloadedTypeIndices[Number];
-        if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
-          OS << "~(ExtendedElementVectorType | " << Number << ")";
-        else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
-          OS << "~(TruncatedElementVectorType | " << Number << ")";
-        else
-          OS << "~" << Number;
-      } else {
-        MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
-        OS << getEnumName(VT);
-
-        if (EVT(VT).isOverloaded())
-          OverloadedTypeIndices.push_back(j + RetTys.size());
-
-        if (VT == MVT::isVoid && j != 0 && j != je - 1)
-          throw "Var arg type not last argument";
-      }
-    }
-      
-    OS << ");\n";
-    OS << "    break;\n";
-  }
-  OS << "  }\n";
-  OS << "#endif\n\n";
-}
-
 
 // NOTE: This must be kept in synch with the copy in lib/VMCore/Function.cpp!
 enum IIT_Info {
@@ -588,6 +451,9 @@ namespace {
       if (L->canThrow != R->canThrow)
         return R->canThrow;
 
+      if (L->isNoReturn != R->isNoReturn)
+        return R->isNoReturn;
+
       // Try to order by readonly/readnone attribute.
       ModRefKind LK = getModRefKind(*L);
       ModRefKind RK = getModRefKind(*R);
@@ -686,16 +552,30 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
 
     ModRefKind modRef = getModRefKind(intrinsic);
 
-    if (!intrinsic.canThrow || modRef) {
+    if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn) {
       OS << "      AWI[" << numAttrs++ << "] = AttributeWithIndex::get(~0, ";
+      bool Emitted = false;
       if (!intrinsic.canThrow) {
         OS << "Attribute::NoUnwind";
-        if (modRef) OS << '|';
+        Emitted = true;
+      }
+      
+      if (intrinsic.isNoReturn) {
+        if (Emitted) OS << '|';
+        OS << "Attribute::NoReturn";
+        Emitted = true;
       }
+
       switch (modRef) {
       case MRK_none: break;
-      case MRK_readonly: OS << "Attribute::ReadOnly"; break;
-      case MRK_readnone: OS << "Attribute::ReadNone"; break;
+      case MRK_readonly:
+        if (Emitted) OS << '|';
+        OS << "Attribute::ReadOnly";
+        break;
+      case MRK_readnone:
+        if (Emitted) OS << '|';
+        OS << "Attribute::ReadNone"; 
+        break;
       }
       OS << ");\n";
     }