[llvm] r356610 - [WebAssembly] Target features section

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 20 13:26:45 PDT 2019


Author: tlively
Date: Wed Mar 20 13:26:45 2019
New Revision: 356610

URL: http://llvm.org/viewvc/llvm-project?rev=356610&view=rev
Log:
[WebAssembly] Target features section

Summary:
Implements a new target features section in assembly and object files
that records what features are used, required, and disallowed in
WebAssembly objects. The linker uses this information to ensure that
all objects participating in a link are feature-compatible and records
the set of used features in the output binary for use by optimizers
and other tools later in the toolchain.

The "atomics" feature is always required or disallowed to prevent
linking code with stripped atomics into multithreaded binaries. Other
features are marked used if they are enabled globally or on any
function in a module.

Future CLs will add linker flags for ignoring feature compatibility
checks and for specifying the set of allowed features, implement using
the presence of the "atomics" feature to control the type of memory
and segments in the linked binary, and add front-end flags for
relaxing the linkage policy for atomics.

Reviewers: aheejin, sbc100, dschuff

Subscribers: jgravelle-google, hiraditya, sunfish, mgrang, jfb, jdoerfert, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D59173

Added:
    llvm/trunk/test/CodeGen/WebAssembly/target-features.ll
    llvm/trunk/test/ObjectYAML/wasm/target-features-section.yaml
Modified:
    llvm/trunk/include/llvm/BinaryFormat/Wasm.h
    llvm/trunk/include/llvm/Object/Wasm.h
    llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h
    llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp
    llvm/trunk/lib/MC/WasmObjectWriter.cpp
    llvm/trunk/lib/Object/WasmObjectFile.cpp
    llvm/trunk/lib/ObjectYAML/WasmYAML.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
    llvm/trunk/test/MC/WebAssembly/array-fill.ll
    llvm/trunk/test/MC/WebAssembly/assembler-binary.ll
    llvm/trunk/test/MC/WebAssembly/bss.ll
    llvm/trunk/test/MC/WebAssembly/comdat.ll
    llvm/trunk/test/MC/WebAssembly/debug-info.ll
    llvm/trunk/test/MC/WebAssembly/explicit-sections.ll
    llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll
    llvm/trunk/test/MC/WebAssembly/visibility.ll
    llvm/trunk/test/MC/WebAssembly/weak-alias.ll
    llvm/trunk/test/MC/WebAssembly/weak.ll
    llvm/trunk/tools/obj2yaml/wasm2yaml.cpp
    llvm/trunk/tools/yaml2obj/yaml2wasm.cpp

Modified: llvm/trunk/include/llvm/BinaryFormat/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/Wasm.h?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/Wasm.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/Wasm.h Wed Mar 20 13:26:45 2019
@@ -48,6 +48,11 @@ struct WasmProducerInfo {
   std::vector<std::pair<std::string, std::string>> SDKs;
 };
 
+struct WasmFeatureEntry {
+  uint8_t Prefix;
+  std::string Name;
+};
+
 struct WasmExport {
   StringRef Name;
   uint8_t Kind;
@@ -253,6 +258,13 @@ enum : unsigned {
   WASM_SEGMENT_HAS_MEMINDEX = 0x02,
 };
 
+// Feature policy prefixes used in the custom "target_features" section
+enum : uint8_t {
+  WASM_FEATURE_PREFIX_USED = '+',
+  WASM_FEATURE_PREFIX_REQUIRED = '=',
+  WASM_FEATURE_PREFIX_DISALLOWED = '-',
+};
+
 // Kind codes used in the custom "name" section
 enum : unsigned {
   WASM_NAMES_FUNCTION = 0x1,

Modified: llvm/trunk/include/llvm/Object/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Wasm.h?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Wasm.h (original)
+++ llvm/trunk/include/llvm/Object/Wasm.h Wed Mar 20 13:26:45 2019
@@ -130,6 +130,9 @@ public:
 
   const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
   const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
+  ArrayRef<wasm::WasmFeatureEntry> getTargetFeatures() const {
+    return TargetFeatures;
+  }
   ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
   ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
   ArrayRef<wasm::WasmImport> imports() const { return Imports; }
@@ -252,12 +255,14 @@ private:
   Error parseLinkingSectionSymtab(ReadContext &Ctx);
   Error parseLinkingSectionComdat(ReadContext &Ctx);
   Error parseProducersSection(ReadContext &Ctx);
+  Error parseTargetFeaturesSection(ReadContext &Ctx);
   Error parseRelocSection(StringRef Name, ReadContext &Ctx);
 
   wasm::WasmObjectHeader Header;
   std::vector<WasmSection> Sections;
   wasm::WasmDylinkInfo DylinkInfo;
   wasm::WasmProducerInfo ProducerInfo;
+  std::vector<wasm::WasmFeatureEntry> TargetFeatures;
   std::vector<wasm::WasmSignature> Signatures;
   std::vector<uint32_t> FunctionTypes;
   std::vector<wasm::WasmTable> Tables;
@@ -318,6 +323,8 @@ public:
     WASM_SEC_ORDER_NAME,
     // "producers" section must appear after "name" section.
     WASM_SEC_ORDER_PRODUCERS,
+    // "target_features" section must appear after producers section
+    WASM_SEC_ORDER_TARGET_FEATURES,
 
     // Must be last
     WASM_NUM_SEC_ORDERS

Modified: llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h Wed Mar 20 13:26:45 2019
@@ -38,6 +38,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, Symbo
 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags)
 LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags)
 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, FeaturePolicyPrefix)
 
 struct FileHeader {
   yaml::Hex32 Version;
@@ -128,6 +129,11 @@ struct ProducerEntry {
   std::string Version;
 };
 
+struct FeatureEntry {
+  FeaturePolicyPrefix Prefix;
+  std::string Name;
+};
+
 struct SegmentInfo {
   uint32_t Index;
   StringRef Name;
@@ -242,6 +248,17 @@ struct ProducersSection : CustomSection
   std::vector<ProducerEntry> SDKs;
 };
 
+struct TargetFeaturesSection : CustomSection {
+  TargetFeaturesSection() : CustomSection("target_features") {}
+
+  static bool classof(const Section *S) {
+    auto C = dyn_cast<CustomSection>(S);
+    return C && C->Name == "target_features";
+  }
+
+  std::vector<FeatureEntry> Features;
+};
+
 struct TypeSection : Section {
   TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
 
@@ -385,6 +402,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmY
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
@@ -467,6 +485,14 @@ template <> struct MappingTraits<WasmYAM
   static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
 };
 
+template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> {
+  static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
+};
+
+template <> struct MappingTraits<WasmYAML::FeatureEntry> {
+  static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
+};
+
 template <> struct MappingTraits<WasmYAML::SegmentInfo> {
   static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
 };

Modified: llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp Wed Mar 20 13:26:45 2019
@@ -135,9 +135,10 @@ public:
       SectionKind Kind;
     };
     static SectionType SectionTypes[] = {
-        { ".text", SectionKind::getText() },
-        { ".rodata", SectionKind::getReadOnly() },
-        { ".data", SectionKind::getData() },
+        {".text", SectionKind::getText()},
+        {".rodata", SectionKind::getReadOnly()},
+        {".data", SectionKind::getData()},
+        {".custom_section", SectionKind::getMetadata()},
         // TODO: add more types.
     };
     for (size_t I = 0; I < sizeof(SectionTypes) / sizeof(SectionType); I++) {

Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Wed Mar 20 13:26:45 2019
@@ -250,6 +250,7 @@ class WasmObjectWriter : public MCObject
   // section.
   std::vector<WasmCustomSection> CustomSections;
   std::unique_ptr<WasmCustomSection> ProducersSection;
+  std::unique_ptr<WasmCustomSection> TargetFeaturesSection;
   // Relocations for fixing up references in the custom sections.
   DenseMap<const MCSectionWasm *, std::vector<WasmRelocationEntry>>
       CustomSectionsRelocations;
@@ -291,6 +292,7 @@ private:
     DataLocations.clear();
     CustomSections.clear();
     ProducersSection.reset();
+    TargetFeaturesSection.reset();
     CustomSectionsRelocations.clear();
     SignatureIndices.clear();
     Signatures.clear();
@@ -1286,11 +1288,16 @@ uint64_t WasmObjectWriter::writeObject(M
                              Twine(SectionName));
       }
 
-      // Separate out the producers section
+      // Separate out the producers and target features sections
       if (Name == "producers") {
         ProducersSection = llvm::make_unique<WasmCustomSection>(Name, &Section);
         continue;
       }
+      if (Name == "target_features") {
+        TargetFeaturesSection =
+            llvm::make_unique<WasmCustomSection>(Name, &Section);
+        continue;
+      }
 
       CustomSections.emplace_back(Name, &Section);
     }
@@ -1593,6 +1600,8 @@ uint64_t WasmObjectWriter::writeObject(M
   writeCustomRelocSections();
   if (ProducersSection)
     writeCustomSection(*ProducersSection, Asm, Layout);
+  if (TargetFeaturesSection)
+    writeCustomSection(*TargetFeaturesSection, Asm, Layout);
 
   // TODO: Translate the .comment section to the output.
   return W.OS.tell() - StartOffset;

Modified: llvm/trunk/lib/Object/WasmObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/WasmObjectFile.cpp?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/lib/Object/WasmObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/WasmObjectFile.cpp Wed Mar 20 13:26:45 2019
@@ -715,6 +715,36 @@ Error WasmObjectFile::parseProducersSect
   return Error::success();
 }
 
+Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
+  llvm::SmallSet<std::string, 8> FeaturesSeen;
+  uint32_t FeatureCount = readVaruint32(Ctx);
+  for (size_t I = 0; I < FeatureCount; ++I) {
+    wasm::WasmFeatureEntry Feature;
+    Feature.Prefix = readUint8(Ctx);
+    switch (Feature.Prefix) {
+    case wasm::WASM_FEATURE_PREFIX_USED:
+    case wasm::WASM_FEATURE_PREFIX_REQUIRED:
+    case wasm::WASM_FEATURE_PREFIX_DISALLOWED:
+      break;
+    default:
+      return make_error<GenericBinaryError>("Unknown feature policy prefix",
+                                            object_error::parse_failed);
+    }
+    Feature.Name = readString(Ctx);
+    if (!FeaturesSeen.insert(Feature.Name).second)
+      return make_error<GenericBinaryError>(
+          "Target features section contains repeated feature \"" +
+              Feature.Name + "\"",
+          object_error::parse_failed);
+    TargetFeatures.push_back(Feature);
+  }
+  if (Ctx.Ptr != Ctx.End)
+    return make_error<GenericBinaryError>(
+        "Target features section ended prematurely",
+        object_error::parse_failed);
+  return Error::success();
+}
+
 Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
   uint32_t SectionIndex = readVaruint32(Ctx);
   if (SectionIndex >= Sections.size())
@@ -816,6 +846,9 @@ Error WasmObjectFile::parseCustomSection
   } else if (Sec.Name == "producers") {
     if (Error Err = parseProducersSection(Ctx))
       return Err;
+  } else if (Sec.Name == "target_features") {
+    if (Error Err = parseTargetFeaturesSection(Ctx))
+      return Err;
   } else if (Sec.Name.startswith("reloc.")) {
     if (Error Err = parseRelocSection(Sec.Name, Ctx))
       return Err;
@@ -1528,6 +1561,7 @@ int WasmSectionOrderChecker::getSectionO
         .StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
         .Case("name", WASM_SEC_ORDER_NAME)
         .Case("producers", WASM_SEC_ORDER_PRODUCERS)
+        .Case("target_features", WASM_SEC_ORDER_TARGET_FEATURES)
         .Default(WASM_SEC_ORDER_NONE);
   case wasm::WASM_SEC_TYPE:
     return WASM_SEC_ORDER_TYPE;
@@ -1584,7 +1618,8 @@ int WasmSectionOrderChecker::DisallowedP
   {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME}, // WASM_SEC_ORDER_LINKING,
   {}, // WASM_SEC_ORDER_RELOC (can be repeated),
   {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS}, // WASM_SEC_ORDER_NAME,
-  {WASM_SEC_ORDER_PRODUCERS}, // WASM_SEC_ORDER_PRODUCERS,
+  {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES}, // WASM_SEC_ORDER_PRODUCERS,
+  {WASM_SEC_ORDER_TARGET_FEATURES}  // WASM_SEC_ORDER_TARGET_FEATURES
 };
 
 bool WasmSectionOrderChecker::isValidSectionOrder(unsigned ID,

Modified: llvm/trunk/lib/ObjectYAML/WasmYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/WasmYAML.cpp?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/WasmYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/WasmYAML.cpp Wed Mar 20 13:26:45 2019
@@ -81,6 +81,12 @@ static void sectionMapping(IO &IO, WasmY
   IO.mapOptional("SDKs", Section.SDKs);
 }
 
+static void sectionMapping(IO &IO, WasmYAML::TargetFeaturesSection &Section) {
+  commonSectionMapping(IO, Section);
+  IO.mapRequired("Name", Section.Name);
+  IO.mapRequired("Features", Section.Features);
+}
+
 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
   commonSectionMapping(IO, Section);
   IO.mapRequired("Name", Section.Name);
@@ -180,6 +186,10 @@ void MappingTraits<std::unique_ptr<WasmY
       if (!IO.outputting())
         Section.reset(new WasmYAML::ProducersSection());
       sectionMapping(IO, *cast<WasmYAML::ProducersSection>(Section.get()));
+    } else if (SectionName == "target_features") {
+      if (!IO.outputting())
+        Section.reset(new WasmYAML::TargetFeaturesSection());
+      sectionMapping(IO, *cast<WasmYAML::TargetFeaturesSection>(Section.get()));
     } else {
       if (!IO.outputting())
         Section.reset(new WasmYAML::CustomSection(SectionName));
@@ -310,6 +320,21 @@ void MappingTraits<WasmYAML::ProducerEnt
   IO.mapRequired("Version", ProducerEntry.Version);
 }
 
+void ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix>::enumeration(
+    IO &IO, WasmYAML::FeaturePolicyPrefix &Kind) {
+#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_FEATURE_PREFIX_##X);
+  ECase(USED);
+  ECase(REQUIRED);
+  ECase(DISALLOWED);
+#undef ECase
+}
+
+void MappingTraits<WasmYAML::FeatureEntry>::mapping(
+    IO &IO, WasmYAML::FeatureEntry &FeatureEntry) {
+  IO.mapRequired("Prefix", FeatureEntry.Prefix);
+  IO.mapRequired("Name", FeatureEntry.Name);
+}
+
 void MappingTraits<WasmYAML::SegmentInfo>::mapping(
     IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
   IO.mapRequired("Index", SegmentInfo.Index);

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Wed Mar 20 13:26:45 2019
@@ -21,8 +21,10 @@
 #include "WebAssemblyMCInstLower.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblyRegisterInfo.h"
+#include "WebAssemblyTargetMachine.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/Analysis.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
@@ -159,6 +161,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsm
   }
 
   EmitProducerInfo(M);
+  EmitTargetFeatures();
 }
 
 void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
@@ -212,6 +215,61 @@ void WebAssemblyAsmPrinter::EmitProducer
   }
 }
 
+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"},
+  };
+
+  struct FeatureEntry {
+    uint8_t Prefix;
+    StringRef Name;
+  };
+
+  FeatureBitset UsedFeatures =
+      static_cast<WebAssemblyTargetMachine &>(TM).getUsedFeatures();
+
+  // Calculate the features and linkage policies to emit
+  SmallVector<FeatureEntry, 4> EmittedFeatures;
+  for (auto &F : FeaturePairs) {
+    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);
+      }
+    }
+  }
+
+  // Emit features and linkage policies into the "target_features" section
+  MCSectionWasm *FeaturesSection = OutContext.getWasmSection(
+      ".custom_section.target_features", SectionKind::getMetadata());
+  OutStreamer->PushSection();
+  OutStreamer->SwitchSection(FeaturesSection);
+
+  OutStreamer->EmitULEB128IntValue(EmittedFeatures.size());
+  for (auto &F : EmittedFeatures) {
+    OutStreamer->EmitIntValue(F.Prefix, 1);
+    OutStreamer->EmitULEB128IntValue(F.Name.size());
+    OutStreamer->EmitBytes(F.Name);
+  }
+
+  OutStreamer->PopSection();
+}
+
 void WebAssemblyAsmPrinter::EmitConstantPool() {
   assert(MF->getConstantPool()->getConstants().empty() &&
          "WebAssembly disables constant pools");

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h Wed Mar 20 13:26:45 2019
@@ -59,6 +59,7 @@ public:
 
   void EmitEndOfAsmFile(Module &M) override;
   void EmitProducerInfo(Module &M);
+  void EmitTargetFeatures();
   void EmitJumpTableInfo() override;
   void EmitConstantPool() override;
   void EmitFunctionBodyStart() override;

Added: llvm/trunk/test/CodeGen/WebAssembly/target-features.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/target-features.ll?rev=356610&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/target-features.ll (added)
+++ llvm/trunk/test/CodeGen/WebAssembly/target-features.ll Wed Mar 20 13:26:45 2019
@@ -0,0 +1,67 @@
+; RUN: llc < %s | FileCheck %s --check-prefixes CHECK,ATTRS
+; RUN: llc < %s -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
+; RUN; llc < %s -mattr=+atomics | FileCheck %s --check-prefixes CHECK,ATOMICS
+; RUN: llc < %s -mcpu=bleeding-edge | FileCheck %s --check-prefixes CHECK,BLEEDING-EDGE
+
+; Test that codegen emits target features from the command line or
+; function attributes correctly.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define void @foo() #0 {
+  ret void
+}
+
+define void @bar() #1 {
+  ret void
+}
+
+attributes #0 = { "target-features"="+sign-ext" }
+attributes #1 = { "target-features"="+nontrapping-fptoint" }
+
+; CHECK-LABEL: .custom_section.target_features,"",@
+
+; -atomics, +sign_ext
+; ATTRS-NEXT: .int8 3
+; ATTRS-NEXT: .int8 45
+; ATTRS-NEXT: .int8 7
+; ATTRS-NEXT: .ascii "atomics"
+; ATTRS-NEXT: .int8 43
+; ATTRS-NEXT: .int8 19
+; ATTRS-NEXT: .ascii "nontrapping-fptoint"
+; ATTRS-NEXT: .int8 43
+; ATTRS-NEXT:  int8 8
+; ATTRS-NEXT: .ascii "sign-ext"
+
+; -atomics, +simd128
+; SIMD128-NEXT: .int8 2
+; SIMD128-NEXT: .int8 45
+; SIMD128-NEXT: .int8 7
+; SIMD128-NEXT: .ascii "atomics"
+; SIMD128-NEXT: .int8 43
+; SIMD128-NEXT: .int8 7
+; SIMD128-NEXT: .ascii "simd128"
+
+; =atomics
+; ATOMICS-NEXT: .int8 1
+; ATOMICS-NEXT: .int8 61
+; ATOMICS-NEXT: .int8 7
+; ATOMICS-NEXT: .ascii "atomics"
+
+; =atomics, +nontrapping-fptoint, +sign-ext, +simd128
+; BLEEDING-EDGE-NEXT: .int8   4
+; BLEEDING-EDGE-NEXT: .int8   61
+; BLEEDING-EDGE-NEXT: .int8   7
+; BLEEDING-EDGE-NEXT: .ascii  "atomics"
+; BLEEDING-EDGE-NEXT: .int8   43
+; BLEEDING-EDGE-NEXT: .int8   19
+; BLEEDING-EDGE-NEXT: .ascii  "nontrapping-fptoint"
+; BLEEDING-EDGE-NEXT: .int8   43
+; BLEEDING-EDGE-NEXT: .int8   8
+; BLEEDING-EDGE-NEXT: .ascii  "sign-ext"
+; BLEEDING-EDGE-NEXT: .int8   43
+; BLEEDING-EDGE-NEXT: .int8   7
+; BLEEDING-EDGE-NEXT: .ascii  "simd128"
+
+; CHECK-NEXT: .text

Modified: llvm/trunk/test/MC/WebAssembly/array-fill.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/array-fill.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/array-fill.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/array-fill.ll Wed Mar 20 13:26:45 2019
@@ -24,4 +24,9 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT:         Name:            .data
 ; CHECK-NEXT:         Alignment:       0
 ; CHECK-NEXT:         Flags:           [ ]
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/assembler-binary.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/assembler-binary.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/assembler-binary.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/assembler-binary.ll Wed Mar 20 13:26:45 2019
@@ -87,4 +87,9 @@ entry:
 ; CHECK-NEXT:         Name:            bar
 ; CHECK-NEXT:         Flags:           [ UNDEFINED ]
 ; CHECK-NEXT:         Function:        0
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/bss.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/bss.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/bss.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/bss.ll Wed Mar 20 13:26:45 2019
@@ -78,4 +78,9 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT:         Name:            .bss.bar
 ; CHECK-NEXT:         Alignment:       0
 ; CHECK-NEXT:         Flags:           [ ]
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/comdat.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/comdat.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/comdat.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/comdat.ll Wed Mar 20 13:26:45 2019
@@ -119,4 +119,9 @@ define linkonce_odr i32 @sharedFn() #1 c
 ; CHECK-NEXT:            Index:           3
 ; CHECK-NEXT:          - Kind:            DATA
 ; CHECK-NEXT:            Index:           0
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/debug-info.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/debug-info.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/debug-info.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/debug-info.ll Wed Mar 20 13:26:45 2019
@@ -130,6 +130,12 @@
 ; CHECK-NEXT:    Offset: 1021
 ; CHECK-NEXT:    Name: producers
 ; CHECK-NEXT:  }
+; CHECK-NEXT:  Section {
+; CHECK-NEXT:    Type: CUSTOM (0x0)
+; CHECK-NEXT:    Size: 10
+; CHECK-NEXT:    Offset: 1114
+; CHECK-NEXT:    Name: target_features
+; CHECK-NEXT:  }
 ; CHECK-NEXT:]
 ; CHECK-NEXT:Relocations [
 ; CHECK-NEXT:  Section (6) DATA {

Modified: llvm/trunk/test/MC/WebAssembly/explicit-sections.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/explicit-sections.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/explicit-sections.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/explicit-sections.ll Wed Mar 20 13:26:45 2019
@@ -70,4 +70,9 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT:         Name:            .sec2
 ; CHECK-NEXT:         Alignment:       3
 ; CHECK-NEXT:         Flags:           [ ]
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll Wed Mar 20 13:26:45 2019
@@ -181,4 +181,9 @@ declare void @func3()
 ; CHECK-NEXT:         Symbol: 10
 ; CHECK-NEXT:       - Priority: 65535
 ; CHECK-NEXT:         Symbol: 7
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/visibility.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/visibility.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/visibility.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/visibility.ll Wed Mar 20 13:26:45 2019
@@ -25,4 +25,9 @@ entry:
 ; CHECK-NEXT:         Name:            hiddenVis
 ; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
 ; CHECK-NEXT:         Function:        1
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Modified: llvm/trunk/test/MC/WebAssembly/weak-alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/weak-alias.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/weak-alias.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/weak-alias.ll Wed Mar 20 13:26:45 2019
@@ -207,6 +207,11 @@ entry:
 ; CHECK-NEXT:         Name:            .data.alias_address
 ; CHECK-NEXT:         Alignment:       3
 ; CHECK-NEXT:         Flags:           [ ]
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...
 
 ; CHECK-SYMS: SYMBOL TABLE:

Modified: llvm/trunk/test/MC/WebAssembly/weak.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/weak.ll?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/weak.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/weak.ll Wed Mar 20 13:26:45 2019
@@ -30,4 +30,9 @@ entry:
 ; CHECK-NEXT:         Kind:            DATA
 ; CHECK-NEXT:         Name:            weak_external_data
 ; CHECK-NEXT:         Flags:           [ BINDING_WEAK, UNDEFINED ]
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            target_features
+; CHECK-NEXT:     Features:
+; CHECK-NEXT:       - Prefix:          DISALLOWED
+; CHECK-NEXT:         Name:            atomics
 ; CHECK-NEXT: ...

Added: llvm/trunk/test/ObjectYAML/wasm/target-features-section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/wasm/target-features-section.yaml?rev=356610&view=auto
==============================================================================
--- llvm/trunk/test/ObjectYAML/wasm/target-features-section.yaml (added)
+++ llvm/trunk/test/ObjectYAML/wasm/target-features-section.yaml Wed Mar 20 13:26:45 2019
@@ -0,0 +1,25 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+  - Type:            CUSTOM
+    Name:            target_features
+    Features:
+      - Prefix:        USED
+        Name:          "foo"
+      - Prefix:        REQUIRED
+        Name:          "bar"
+      - Prefix:        DISALLOWED
+        Name:          ""
+...
+# CHECK-LABEL:  Sections:
+# CHECK-NEXT:     - Type:            CUSTOM
+# CHECK-NEXT:       Name:            target_features
+# CHECK-NEXT:       Features:
+# CHECK-NEXT:         - Prefix:        USED
+# CHECK-NEXT:           Name:          foo
+# CHECK-NEXT:         - Prefix:        REQUIRED
+# CHECK-NEXT:           Name:          bar
+# CHECK-NEXT:         - Prefix:        DISALLOWED
+# CHECK-NEXT:           Name:          ''

Modified: llvm/trunk/tools/obj2yaml/wasm2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/wasm2yaml.cpp?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/wasm2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/wasm2yaml.cpp Wed Mar 20 13:26:45 2019
@@ -155,6 +155,16 @@ WasmDumper::dumpCustomSection(const Wasm
       ProducersSec->SDKs.push_back(Producer);
     }
     CustomSec = std::move(ProducersSec);
+  } else if (WasmSec.Name == "target_features") {
+    std::unique_ptr<WasmYAML::TargetFeaturesSection> TargetFeaturesSec =
+        make_unique<WasmYAML::TargetFeaturesSection>();
+    for (auto &E : Obj.getTargetFeatures()) {
+      WasmYAML::FeatureEntry Feature;
+      Feature.Prefix = E.Prefix;
+      Feature.Name = E.Name;
+      TargetFeaturesSec->Features.push_back(Feature);
+    }
+    CustomSec = std::move(TargetFeaturesSec);
   } else {
     CustomSec = make_unique<WasmYAML::CustomSection>(WasmSec.Name);
   }

Modified: llvm/trunk/tools/yaml2obj/yaml2wasm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2wasm.cpp?rev=356610&r1=356609&r2=356610&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2wasm.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2wasm.cpp Wed Mar 20 13:26:45 2019
@@ -49,6 +49,8 @@ private:
   int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
   int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
   int writeSectionContent(raw_ostream &OS, WasmYAML::ProducersSection &Section);
+  int writeSectionContent(raw_ostream &OS,
+                          WasmYAML::TargetFeaturesSection &Section);
   WasmYAML::Object &Obj;
   uint32_t NumImportedFunctions = 0;
   uint32_t NumImportedGlobals = 0;
@@ -280,6 +282,17 @@ int WasmWriter::writeSectionContent(raw_
 }
 
 int WasmWriter::writeSectionContent(raw_ostream &OS,
+                                    WasmYAML::TargetFeaturesSection &Section) {
+  writeStringRef(Section.Name, OS);
+  encodeULEB128(Section.Features.size(), OS);
+  for (auto &E : Section.Features) {
+    writeUint8(OS, E.Prefix);
+    writeStringRef(E.Name, OS);
+  }
+  return 0;
+}
+
+int WasmWriter::writeSectionContent(raw_ostream &OS,
                                     WasmYAML::CustomSection &Section) {
   if (auto S = dyn_cast<WasmYAML::DylinkSection>(&Section)) {
     if (auto Err = writeSectionContent(OS, *S))
@@ -293,6 +306,9 @@ int WasmWriter::writeSectionContent(raw_
   } else if (auto S = dyn_cast<WasmYAML::ProducersSection>(&Section)) {
     if (auto Err = writeSectionContent(OS, *S))
       return Err;
+  } else if (auto S = dyn_cast<WasmYAML::TargetFeaturesSection>(&Section)) {
+    if (auto Err = writeSectionContent(OS, *S))
+      return Err;
   } else {
     writeStringRef(Section.Name, OS);
     Section.Payload.writeAsBinary(OS);




More information about the llvm-commits mailing list