aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--utils/TableGen/CodeGenIntrinsics.h6
-rw-r--r--utils/TableGen/CodeGenTarget.cpp10
-rw-r--r--utils/TableGen/IntrinsicEmitter.cpp36
3 files changed, 35 insertions, 17 deletions
diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h
index 0d1b39b..536f346 100644
--- a/utils/TableGen/CodeGenIntrinsics.h
+++ b/utils/TableGen/CodeGenIntrinsics.h
@@ -24,7 +24,7 @@ namespace llvm {
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 @@ namespace llvm {
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);
};
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 7cf80b0..151295f 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -43,6 +43,7 @@ std::string llvm::getName(MVT::ValueType T) {
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 @@ std::string llvm::getEnumName(MVT::ValueType T) {
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 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R, CodeGenTarget *CGT) {
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 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R, CodeGenTarget *CGT) {
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");
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index 6247da2..f884c42 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -74,9 +74,9 @@ void IntrinsicEmitter::
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 @@ EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
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 @@ EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
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 @@ static bool EmitTypeVerify(std::ostream &OS, Record *ArgType) {
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 @@ void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints,
}
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 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
}
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";
}