summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2019-03-29 00:14:01 +0000
committerThomas Lively <tlively@google.com>2019-03-29 00:14:01 +0000
commit3f34e1b883351c7d98426b084386a7aa762aa366 (patch)
tree04c234c41b653cc23f751e4c711e8a66a78f51a6 /llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
parent0c9ea1053058be474a58859be2ab212aaf33ea31 (diff)
downloadbcm5719-llvm-3f34e1b883351c7d98426b084386a7aa762aa366.tar.gz
bcm5719-llvm-3f34e1b883351c7d98426b084386a7aa762aa366.zip
[WebAssembly] Merge used feature sets, update atomics linkage policy
Summary: It does not currently make sense to use WebAssembly features in some functions but not others, so this CL adds an IR pass that takes the union of all used feature sets and applies it to each function in the module. This allows us to prevent atomics from being lowered away if some function has opted in to using them. When atomics is not enabled anywhere, we detect whether there exists any atomic operations or thread local storage that would be stripped and disallow linking with objects that contain atomics if and only if atomics or tls are stripped. When atomics is enabled, mark it as used but do not require it of other objects in the link. These changes allow libraries that do not use atomics to be built once and linked into both single-threaded and multithreaded binaries. Reviewers: aheejin, sbc100, dschuff Subscribers: jgravelle-google, hiraditya, sunfish, jfb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59625 llvm-svn: 357226
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp59
1 files changed, 27 insertions, 32 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index e4129276b84..2e6de3cd9f2 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -33,6 +33,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCStreamer.h"
@@ -161,7 +162,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
}
EmitProducerInfo(M);
- EmitTargetFeatures();
+ EmitTargetFeatures(M);
}
void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
@@ -215,46 +216,40 @@ void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
}
}
-void WebAssemblyAsmPrinter::EmitTargetFeatures() {
- static const std::pair<unsigned, const char *> FeaturePairs[] = {
- {WebAssembly::FeatureAtomics, "atomics"},
- {WebAssembly::FeatureBulkMemory, "bulk-memory"},
- {WebAssembly::FeatureExceptionHandling, "exception-handling"},
- {WebAssembly::FeatureNontrappingFPToInt, "nontrapping-fptoint"},
- {WebAssembly::FeatureSignExt, "sign-ext"},
- {WebAssembly::FeatureSIMD128, "simd128"},
- };
-
+void WebAssemblyAsmPrinter::EmitTargetFeatures(Module &M) {
struct FeatureEntry {
uint8_t Prefix;
StringRef Name;
};
- FeatureBitset UsedFeatures =
- static_cast<WebAssemblyTargetMachine &>(TM).getUsedFeatures();
-
- // Calculate the features and linkage policies to emit
+ // Read target features and linkage policies from module metadata
SmallVector<FeatureEntry, 4> EmittedFeatures;
- for (auto &F : FeaturePairs) {
+ for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
+ std::string MDKey = (StringRef("wasm-feature-") + KV.Key).str();
+ Metadata *Policy = M.getModuleFlag(MDKey);
+ if (Policy == nullptr)
+ continue;
+
FeatureEntry Entry;
- Entry.Name = F.second;
- if (F.first == WebAssembly::FeatureAtomics) {
- // "atomics" is special: code compiled without atomics may have had its
- // atomics lowered to nonatomic operations. Such code would be dangerous
- // to mix with proper atomics, so it is always Required or Disallowed.
- Entry.Prefix = UsedFeatures[F.first]
- ? wasm::WASM_FEATURE_PREFIX_REQUIRED
- : wasm::WASM_FEATURE_PREFIX_DISALLOWED;
- EmittedFeatures.push_back(Entry);
- } else {
- // Other features are marked Used or not mentioned
- if (UsedFeatures[F.first]) {
- Entry.Prefix = wasm::WASM_FEATURE_PREFIX_USED;
- EmittedFeatures.push_back(Entry);
- }
- }
+ Entry.Prefix = 0;
+ Entry.Name = KV.Key;
+
+ if (auto *MD = cast<ConstantAsMetadata>(Policy))
+ if (auto *I = cast<ConstantInt>(MD->getValue()))
+ Entry.Prefix = I->getZExtValue();
+
+ // Silently ignore invalid metadata
+ if (Entry.Prefix != wasm::WASM_FEATURE_PREFIX_USED &&
+ Entry.Prefix != wasm::WASM_FEATURE_PREFIX_REQUIRED &&
+ Entry.Prefix != wasm::WASM_FEATURE_PREFIX_DISALLOWED)
+ continue;
+
+ EmittedFeatures.push_back(Entry);
}
+ if (EmittedFeatures.size() == 0)
+ return;
+
// Emit features and linkage policies into the "target_features" section
MCSectionWasm *FeaturesSection = OutContext.getWasmSection(
".custom_section.target_features", SectionKind::getMetadata());
OpenPOWER on IntegriCloud