@@ -47,20 +47,51 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
47
47
Intrinsics.reserve (Defs.size ());
48
48
49
49
for (const Record *Def : Defs)
50
- Intrinsics.push_back (CodeGenIntrinsic (Def, Ctx));
50
+ Intrinsics.emplace_back (CodeGenIntrinsic (Def, Ctx));
51
51
52
+ // To ensure deterministic sorted order when duplicates are present, use
53
+ // record ID as a tie-breaker similar to sortAndReportDuplicates in Utils.cpp.
52
54
llvm::sort (Intrinsics,
53
55
[](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) {
54
- return std::tie (LHS.TargetPrefix , LHS.Name ) <
55
- std::tie (RHS.TargetPrefix , RHS.Name );
56
+ unsigned LhsID = LHS.TheDef ->getID ();
57
+ unsigned RhsID = RHS.TheDef ->getID ();
58
+ return std::tie (LHS.TargetPrefix , LHS.Name , LhsID) <
59
+ std::tie (RHS.TargetPrefix , RHS.Name , RhsID);
56
60
});
61
+
57
62
Targets.push_back ({" " , 0 , 0 });
58
63
for (size_t I = 0 , E = Intrinsics.size (); I < E; ++I)
59
64
if (Intrinsics[I].TargetPrefix != Targets.back ().Name ) {
60
65
Targets.back ().Count = I - Targets.back ().Offset ;
61
66
Targets.push_back ({Intrinsics[I].TargetPrefix , I, 0 });
62
67
}
63
68
Targets.back ().Count = Intrinsics.size () - Targets.back ().Offset ;
69
+
70
+ CheckDuplicateIntrinsics ();
71
+ }
72
+
73
+ // Check for duplicate intrinsic names.
74
+ void CodeGenIntrinsicTable::CheckDuplicateIntrinsics () const {
75
+ // Since the Intrinsics vector is already sorted by name, if there are 2 or
76
+ // more intrinsics with duplicate names, they will appear adjacent in sorted
77
+ // order. Note that if the intrinsic name was derived from the record name
78
+ // there cannot be be duplicate as TableGen parser would have flagged that.
79
+ // However, if the name was specified in the intrinsic definition, then its
80
+ // possible to have duplicate names.
81
+ auto I = std::adjacent_find (
82
+ Intrinsics.begin (), Intrinsics.end (),
83
+ [](const CodeGenIntrinsic &Int1, const CodeGenIntrinsic &Int2) {
84
+ return Int1.Name == Int2.Name ;
85
+ });
86
+ if (I == Intrinsics.end ())
87
+ return ;
88
+
89
+ // Found a duplicate intrinsics.
90
+ const CodeGenIntrinsic &First = *I;
91
+ const CodeGenIntrinsic &Second = *(I + 1 );
92
+ PrintError (Second.TheDef ,
93
+ Twine (" Intrinsic `" ) + First.Name + " ` is already defined" );
94
+ PrintFatalNote (First.TheDef , " Previous definition here" );
64
95
}
65
96
66
97
CodeGenIntrinsic &CodeGenIntrinsicMap::operator [](const Record *Record) {
0 commit comments