diff options
-rw-r--r-- | test/TableGen/intrinsic-order.td | 35 | ||||
-rw-r--r-- | utils/TableGen/IntrinsicEmitter.cpp | 18 |
2 files changed, 53 insertions, 0 deletions
diff --git a/test/TableGen/intrinsic-order.td b/test/TableGen/intrinsic-order.td new file mode 100644 index 0000000..5eadf60 --- /dev/null +++ b/test/TableGen/intrinsic-order.td @@ -0,0 +1,35 @@ +// RUN: llvm-tblgen -gen-intrinsic %s | FileCheck %s + +class IntrinsicProperty; + +class ValueType<int size, int value> { + string Namespace = "MVT"; + int Size = size; + int Value = value; +} + +class LLVMType<ValueType vt> { + ValueType VT = vt; +} + +class Intrinsic<string name, list<LLVMType> param_types = []> { + string LLVMName = name; + bit isTarget = 0; + string TargetPrefix = ""; + list<LLVMType> RetTypes = []; + list<LLVMType> ParamTypes = param_types; + list<IntrinsicProperty> Properties = []; +} + +def iAny : ValueType<0, 254>; +def llvm_anyint_ty : LLVMType<iAny>; + + +// Make sure an intrinsic name that is a prefix of another is checked after the +// other. + +// CHECK: if (NameR.startswith("oo.bar.")) return Intrinsic::foo_bar; +// CHECK: if (NameR.startswith("oo.")) return Intrinsic::foo; + +def int_foo : Intrinsic<"llvm.foo", [llvm_anyint_ty]>; +def int_foo_bar : Intrinsic<"llvm.foo.bar", [llvm_anyint_ty]>; diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index c83797c..c508795 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -131,6 +131,20 @@ 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) { @@ -144,12 +158,16 @@ 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); + // Emit all the overloaded intrinsics first, build a table of the // non-overloaded ones. std::vector<StringMatcher::StringPair> MatchTable; |