[llvm-commits] CVS: llvm/utils/TableGen/CodeGenIntrinsics.h CodeGenTarget.cpp IntrinsicEmitter.cpp

Reid Spencer reid at x10sys.com
Sun Apr 1 00:20:19 PDT 2007



Changes in directory llvm/utils/TableGen:

CodeGenIntrinsics.h updated: 1.11 -> 1.12
CodeGenTarget.cpp updated: 1.87 -> 1.88
IntrinsicEmitter.cpp updated: 1.29 -> 1.30
---
Log message:

For PR1297: http://llvm.org/PR1297 :
Implement code generation for overloaded intrinsic functions. The basic
difference is that "actual" argument types must be provided when 
constructing intrinsic names and types. Also, for recognition, only the
prefix is examined. If it matches, the suffix is assumed to match. The
suffix is checked by the Verifier, however.


---
Diffs of the changes:  (+35 -17)

 CodeGenIntrinsics.h  |    6 +++++-
 CodeGenTarget.cpp    |   10 +++++++---
 IntrinsicEmitter.cpp |   36 +++++++++++++++++++++++-------------
 3 files changed, 35 insertions(+), 17 deletions(-)


Index: llvm/utils/TableGen/CodeGenIntrinsics.h
diff -u llvm/utils/TableGen/CodeGenIntrinsics.h:1.11 llvm/utils/TableGen/CodeGenIntrinsics.h:1.12
--- llvm/utils/TableGen/CodeGenIntrinsics.h:1.11	Sat Dec 30 23:50:28 2006
+++ llvm/utils/TableGen/CodeGenIntrinsics.h	Sun Apr  1 02:20:01 2007
@@ -24,7 +24,7 @@
   class CodeGenTarget;
 
   struct CodeGenIntrinsic {
-    Record *TheDef;            // The actual record defining this instruction.
+    Record *TheDef;            // The actual record defining this intrinsic.
     std::string Name;          // The name of the LLVM function "llvm.bswap.i32"
     std::string EnumName;      // The name of the enum "bswap_i32"
     std::string GCCBuiltinName;// Name of the corresponding GCC builtin, or "".
@@ -49,6 +49,10 @@
       NoMem, ReadArgMem, ReadMem, WriteArgMem, WriteMem
     } ModRef;
 
+    // This is set to true if the intrinsic is overloaded by its argument
+    // types.
+    bool isOverloaded;
+
     CodeGenIntrinsic(Record *R, CodeGenTarget *CGT);
   };
 


Index: llvm/utils/TableGen/CodeGenTarget.cpp
diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.87 llvm/utils/TableGen/CodeGenTarget.cpp:1.88
--- llvm/utils/TableGen/CodeGenTarget.cpp:1.87	Mon Mar 26 02:53:08 2007
+++ llvm/utils/TableGen/CodeGenTarget.cpp	Sun Apr  1 02:20:02 2007
@@ -43,6 +43,7 @@
   case MVT::i32:   return "MVT::i32";
   case MVT::i64:   return "MVT::i64";
   case MVT::i128:  return "MVT::i128";
+  case MVT::iAny:  return "MVT::iAny";
   case MVT::f32:   return "MVT::f32";
   case MVT::f64:   return "MVT::f64";
   case MVT::f80:   return "MVT::f80";
@@ -74,6 +75,7 @@
   case MVT::i32:   return "MVT::i32";
   case MVT::i64:   return "MVT::i64";
   case MVT::i128:  return "MVT::i128";
+  case MVT::iAny:  return "MVT::iAny";
   case MVT::f32:   return "MVT::f32";
   case MVT::f64:   return "MVT::f64";
   case MVT::f80:   return "MVT::f80";
@@ -570,6 +572,7 @@
   TheDef = R;
   std::string DefName = R->getName();
   ModRef = WriteMem;
+  isOverloaded = false;
   
   if (DefName.size() <= 4 || 
       std::string(DefName.begin(), DefName.begin()+4) != "int_")
@@ -610,13 +613,14 @@
     Record *TyEl = TypeList->getElementAsRecord(i);
     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
     ArgTypes.push_back(TyEl->getValueAsString("TypeVal"));
-    
-    if (CGT)
-      ArgVTs.push_back(getValueType(TyEl->getValueAsDef("VT"), CGT));
+    MVT::ValueType VT = getValueType(TyEl->getValueAsDef("VT"), CGT);
+    isOverloaded |= VT == MVT::iAny;
+    ArgVTs.push_back(VT);
     ArgTypeDefs.push_back(TyEl);
   }
   if (ArgTypes.size() == 0)
     throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!";
+
   
   // Parse the intrinsic properties.
   ListInit *PropList = R->getValueAsListInit("Properties");


Index: llvm/utils/TableGen/IntrinsicEmitter.cpp
diff -u llvm/utils/TableGen/IntrinsicEmitter.cpp:1.29 llvm/utils/TableGen/IntrinsicEmitter.cpp:1.30
--- llvm/utils/TableGen/IntrinsicEmitter.cpp:1.29	Thu Feb 15 13:26:16 2007
+++ llvm/utils/TableGen/IntrinsicEmitter.cpp	Sun Apr  1 02:20:02 2007
@@ -74,9 +74,9 @@
 EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 
                      std::ostream &OS) {
   // Build a function name -> intrinsic name mapping.
-  std::map<std::string, std::string> IntMapping;
+  std::map<std::string, unsigned> IntMapping;
   for (unsigned i = 0, e = Ints.size(); i != e; ++i)
-    IntMapping[Ints[i].Name] = Ints[i].EnumName;
+    IntMapping[Ints[i].Name] = i;
     
   OS << "// Function name -> enum value recognizer code.\n";
   OS << "#ifdef GET_FUNCTION_RECOGNIZER\n";
@@ -84,7 +84,7 @@
   OS << "  default:\n";
   // Emit the intrinsics in sorted order.
   char LastChar = 0;
-  for (std::map<std::string, std::string>::iterator I = IntMapping.begin(),
+  for (std::map<std::string, unsigned>::iterator I = IntMapping.begin(),
        E = IntMapping.end(); I != E; ++I) {
     if (I->first[5] != LastChar) {
       LastChar = I->first[5];
@@ -92,9 +92,15 @@
       OS << "  case '" << LastChar << "':\n";
     }
     
-    OS << "    if (Len == " << I->first.size()
-       << " && !memcmp(Name, \"" << I->first << "\", Len)) return Intrinsic::"
-       << I->second << ";\n";
+    // For overloaded intrinsics, only the prefix needs to match
+    if (Ints[I->second].isOverloaded)
+      OS << "    if (Len >= " << I->first.size()
+       << " && !memcmp(Name, \"" << I->first << "\", " << I->first.size()
+       << ")) return Intrinsic::" << Ints[I->second].EnumName << ";\n";
+    else 
+      OS << "    if (Len == " << I->first.size()
+         << " && !memcmp(Name, \"" << I->first << "\", Len)) return Intrinsic::"
+         << Ints[I->second].EnumName << ";\n";
   }
   OS << "  }\n";
   OS << "  // The 'llvm.' namespace is reserved!\n";
@@ -130,16 +136,20 @@
   return false;
 }
 
-static void EmitTypeGenerate(std::ostream &OS, Record *ArgType) {
+static void EmitTypeGenerate(std::ostream &OS, Record *ArgType, unsigned ArgNo){
   if (ArgType->isSubClassOf("LLVMIntegerType")) {
-    OS << "IntegerType::get(" << ArgType->getValueAsInt("Width") << ")";
+    unsigned BitWidth = ArgType->getValueAsInt("Width");
+    if (BitWidth == 0)
+      OS << "Tys[" << ArgNo << "]";
+    else
+      OS << "IntegerType::get(" << BitWidth << ")";
   } else if (ArgType->isSubClassOf("LLVMVectorType")) {
     OS << "VectorType::get(";
-    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"));
+    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
     OS << ", " << ArgType->getValueAsInt("NumElts") << ")";
   } else if (ArgType->isSubClassOf("LLVMPointerType")) {
     OS << "PointerType::get(";
-    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"));
+    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
     OS << ")";
   } else if (ArgType->isSubClassOf("LLVMEmptyStructType")) {
     OS << "StructType::get(std::vector<const Type *>())";
@@ -194,7 +204,7 @@
     }
     
     const std::vector<Record*> &ArgTypes = I->first;
-    OS << "    VerifyIntrinsicPrototype(IF, ";
+    OS << "    VerifyIntrinsicPrototype(ID, IF, ";
     bool VarArg = false;
     for (unsigned j = 0; j != ArgTypes.size(); ++j) {
       VarArg = EmitTypeVerify(OS, ArgTypes[j]);
@@ -246,12 +256,12 @@
     }
     
     OS << "    ResultTy = ";
-    EmitTypeGenerate(OS, ArgTypes[0]);
+    EmitTypeGenerate(OS, ArgTypes[0], 0);
     OS << ";\n";
     
     for (unsigned j = 1; j != N; ++j) {
       OS << "    ArgTys.push_back(";
-      EmitTypeGenerate(OS, ArgTypes[j]);
+      EmitTypeGenerate(OS, ArgTypes[j], j);
       OS << ");\n";
     }
     






More information about the llvm-commits mailing list