Skip to content

Commit 0b7a95a

Browse files
committed
Partially Reapply "RuntimeLibcalls: Add methods to recognize libcall names (#149001)"
This partially reverts commit a961210. Drop the IRSymtab changes for now
1 parent 3121cc3 commit 0b7a95a

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

llvm/include/llvm/ADT/StringTable.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ class StringTable {
118118
constexpr Iterator(const Iterator &RHS) = default;
119119
constexpr Iterator(Iterator &&RHS) = default;
120120

121+
Iterator &operator=(const Iterator &RHS) {
122+
Table = RHS.Table;
123+
O = RHS.O;
124+
S = RHS.S;
125+
return *this;
126+
}
127+
121128
bool operator==(const Iterator &RHS) const {
122129
assert(Table == RHS.Table && "Compared iterators for unrelated tables!");
123130
return O == RHS.O;
@@ -132,6 +139,8 @@ class StringTable {
132139
O = O.value() + (*Table)[O].size() + 1;
133140
return *this;
134141
}
142+
143+
Offset offset() const { return O; }
135144
};
136145

137146
constexpr Iterator begin() const { return Iterator(*this, 0); }

llvm/include/llvm/IR/RuntimeLibcalls.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ struct RuntimeLibcallsInfo {
132132
return ImplToLibcall[Impl];
133133
}
134134

135+
/// Check if this is valid libcall for the current module, otherwise
136+
/// RTLIB::Unsupported.
137+
RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const;
138+
135139
private:
136140
static const RTLIB::LibcallImpl
137141
DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1];
@@ -156,6 +160,14 @@ struct RuntimeLibcallsInfo {
156160
/// Map from a concrete LibcallImpl implementation to its RTLIB::Libcall kind.
157161
LLVM_ABI static const RTLIB::Libcall ImplToLibcall[RTLIB::NumLibcallImpls];
158162

163+
/// Check if a function name is a recognized runtime call of any kind. This
164+
/// does not consider if this call is available for any current compilation,
165+
/// just that it is a known call somewhere. This returns the set of all
166+
/// LibcallImpls which match the name; multiple implementations with the same
167+
/// name may exist but differ in interpretation based on the target context.
168+
LLVM_ABI static iterator_range<ArrayRef<uint16_t>::const_iterator>
169+
getRecognizedLibcallImpls(StringRef FuncName);
170+
159171
static bool darwinHasSinCosStret(const Triple &TT) {
160172
if (!TT.isOSDarwin())
161173
return false;

llvm/lib/IR/RuntimeLibcalls.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,51 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
135135
}
136136
}
137137

138+
RTLIB::LibcallImpl
139+
RuntimeLibcallsInfo::getSupportedLibcallImpl(StringRef FuncName) const {
140+
const ArrayRef<uint16_t> RuntimeLibcallNameOffsets(
141+
RuntimeLibcallNameOffsetTable);
142+
143+
iterator_range<ArrayRef<uint16_t>::const_iterator> Range =
144+
getRecognizedLibcallImpls(FuncName);
145+
146+
for (auto I = Range.begin(); I != Range.end(); ++I) {
147+
RTLIB::LibcallImpl Impl =
148+
static_cast<RTLIB::LibcallImpl>(I - RuntimeLibcallNameOffsets.begin());
149+
150+
// FIXME: This should not depend on looking up ImplToLibcall, only the list
151+
// of libcalls for the module.
152+
RTLIB::LibcallImpl Recognized = LibcallImpls[ImplToLibcall[Impl]];
153+
if (Recognized != RTLIB::Unsupported)
154+
return Recognized;
155+
}
156+
157+
return RTLIB::Unsupported;
158+
}
159+
160+
iterator_range<ArrayRef<uint16_t>::const_iterator>
161+
RuntimeLibcallsInfo::getRecognizedLibcallImpls(StringRef FuncName) {
162+
StringTable::Iterator It = lower_bound(RuntimeLibcallImplNameTable, FuncName);
163+
if (It == RuntimeLibcallImplNameTable.end() || *It != FuncName)
164+
return iterator_range(ArrayRef<uint16_t>());
165+
166+
uint16_t IndexVal = It.offset().value();
167+
const ArrayRef<uint16_t> TableRef(RuntimeLibcallNameOffsetTable);
168+
169+
ArrayRef<uint16_t>::const_iterator E = TableRef.end();
170+
ArrayRef<uint16_t>::const_iterator EntriesBegin =
171+
std::lower_bound(TableRef.begin(), E, IndexVal);
172+
ArrayRef<uint16_t>::const_iterator EntriesEnd = EntriesBegin;
173+
174+
while (EntriesEnd != E && *EntriesEnd == IndexVal)
175+
++EntriesEnd;
176+
177+
assert(EntriesBegin != E &&
178+
"libcall found in name table but not offset table");
179+
180+
return make_range(EntriesBegin, EntriesEnd);
181+
}
182+
138183
bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) {
139184
switch (TT.getOS()) {
140185
case Triple::MacOSX:

llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,19 @@ class RuntimeLibcallEmitter {
236236
for (RuntimeLibcall &LibCall : RuntimeLibcallDefList)
237237
Def2RuntimeLibcall[LibCall.getDef()] = &LibCall;
238238

239-
ArrayRef<const Record *> AllRuntimeLibcallImpls =
239+
ArrayRef<const Record *> AllRuntimeLibcallImplsRaw =
240240
Records.getAllDerivedDefinitions("RuntimeLibcallImpl");
241+
242+
SmallVector<const Record *, 1024> AllRuntimeLibcallImpls(
243+
AllRuntimeLibcallImplsRaw);
244+
245+
// Sort by libcall impl name, not the enum name. This keeps the order
246+
// suitable for using the name table for libcall recognition binary search.
247+
llvm::sort(AllRuntimeLibcallImpls, [](const Record *A, const Record *B) {
248+
return A->getValueAsString("LibCallFuncName") <
249+
B->getValueAsString("LibCallFuncName");
250+
});
251+
241252
RuntimeLibcallImplDefList.reserve(AllRuntimeLibcallImpls.size());
242253

243254
size_t LibCallImplEnumVal = 1;

0 commit comments

Comments
 (0)