================
@@ -950,6 +953,76 @@ static bool isStackProtectorOn(const LangOptions &LangOpts,
return LangOpts.getStackProtector() == Mode;
}
+// Emit module flags for symbols and symvers defined in global inline
+// assembly. This allows LLVM IR tools to build a symbol table for an
+// IR module without knowing exact CPU and Features required to parse
+// its global inline assembly.
+static void emitGlobalAsmSymbols(llvm::Module &M, StringRef CPU,
+ StringRef Features) {
+ llvm::LLVMContext &Ctx = M.getContext();
+ bool HaveErrors = false;
+
+ auto DiagHandler = [&](const llvm::DiagnosticInfo &DI) {
+ // Ignore diagnostics from the assembly parser.
+ //
+ // Errors in assembly mean that we cannot build a symbol table
+ // from it. However, we do not diagnose them here in Clang,
+ // because we don't know if the Module is ever going to actually
+ // reach CodeGen where this would matter.
+ if (DI.getSeverity() == llvm::DS_Error) {
+ HaveErrors = true;
+ }
+ };
+
+ // Build global-asm-symbols as a list of pairs (name, flags bitmask).
+ SmallVector<llvm::Metadata *, 16> Symbols;
+ llvm::ModuleSymbolTable::CollectAsmSymbols(
+ M,
+ [&](StringRef Name, llvm::object::BasicSymbolRef::Flags Flags) {
+ Symbols.push_back(llvm::MDNode::get(
+ Ctx, {llvm::MDString::get(Ctx, Name),
+ llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
+ llvm::Type::getInt32Ty(Ctx), Flags))}));
+ },
+ DiagHandler, CPU, Features);
+
+ if (Symbols.empty() || HaveErrors) {
+ return;
+ }
+
+ M.addModuleFlag(llvm::Module::Append, "global-asm-symbols",
+ llvm::MDNode::get(Ctx, Symbols));
+
+ // Build global-asm-symvers as a list of lists (name, followed by all
+ // aliases).
+ llvm::MapVector<StringRef, SmallVector<llvm::Metadata *, 2>> SymversMap;
+ llvm::ModuleSymbolTable::CollectAsmSymvers(
+ M,
+ [&](StringRef Name, StringRef Alias) {
+ auto ItNew = SymversMap.try_emplace(Name);
+ SmallVector<llvm::Metadata *, 2> &Aliases = ItNew.first->second;
+ if (ItNew.second) {
+ // If it is a new list, insert the primary name at the
+ // front.
+ Aliases.push_back(llvm::MDString::get(Ctx, Name));
+ }
+ Aliases.push_back(llvm::MDString::get(Ctx, Alias));
+ },
+ DiagHandler, CPU, Features);
+
+ if (SymversMap.empty() || HaveErrors) {
+ return;
+ }
+
+ SmallVector<llvm::Metadata *, 16> Symvers;
----------------
ilovepi wrote:
```suggestion
SmallVector<llvm::Metadata *, 16> Symvers;
Symvers.reserve(SymversMap.size());
```
We know the size upfront, so we can avoid any possible unneeded allocations if
it would hit the heap.
https://github.com/llvm/llvm-project/pull/174995
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits