[llvm] r299141 - [WebAssembly] Initial linking metadata support

Dan Gohman via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 30 16:58:20 PDT 2017


Author: djg
Date: Thu Mar 30 18:58:19 2017
New Revision: 299141

URL: http://llvm.org/viewvc/llvm-project?rev=299141&view=rev
Log:
[WebAssembly] Initial linking metadata support

Add support for the new relocations and linking metadata section support in
https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md. In
particular, this allows LLVM to indicate which variable is the stack pointer,
so that it can be linked with other objects.

This also adds support for emitting type relocations for call_indirect
instructions.

Right now, this is mainly tested by using wabt and hexdump to examine the
output on selected testcases. We'll add more tests as the design stablizes
and more of the pieces are in place.

Modified:
    llvm/trunk/include/llvm/CodeGen/MachineModuleInfoImpls.h
    llvm/trunk/include/llvm/Support/Wasm.h
    llvm/trunk/include/llvm/Support/WasmRelocs/WebAssembly.def
    llvm/trunk/lib/MC/WasmObjectWriter.cpp
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfoImpls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfoImpls.h?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineModuleInfoImpls.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfoImpls.h Thu Mar 30 18:58:19 2017
@@ -17,6 +17,7 @@
 
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Support/Wasm.h"
 
 namespace llvm {
 class MCSymbol;
@@ -79,9 +80,10 @@ public:
 /// MachineModuleInfoWasm - This is a MachineModuleInfoImpl implementation
 /// for Wasm targets.
 class MachineModuleInfoWasm : public MachineModuleInfoImpl {
-  /// GVStubs - These stubs are used to materialize global addresses in PIC
-  /// mode.
-  std::vector<MVT> Globals;
+  /// WebAssembly global variables defined by CodeGen.
+  std::vector<wasm::Global> Globals;
+
+  /// The WebAssembly global variable which is the stack pointer.
   unsigned StackPointerGlobal;
 
   virtual void anchor(); // Out of line virtual method.
@@ -89,8 +91,8 @@ public:
   MachineModuleInfoWasm(const MachineModuleInfo &)
     : StackPointerGlobal(-1U) {}
 
-  void addGlobal(MVT VT) { Globals.push_back(VT); }
-  const std::vector<MVT> &getGlobals() const { return Globals; }
+  void addGlobal(const wasm::Global &G) { Globals.push_back(G); }
+  const std::vector<wasm::Global> &getGlobals() const { return Globals; }
 
   bool hasStackPointerGlobal() const {
     return StackPointerGlobal != -1U;

Modified: llvm/trunk/include/llvm/Support/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Wasm.h?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Wasm.h (original)
+++ llvm/trunk/include/llvm/Support/Wasm.h Thu Mar 30 18:58:19 2017
@@ -170,6 +170,11 @@ enum class ValType {
   F64 = WASM_TYPE_F64,
 };
 
+// Linking metadata kinds.
+enum : unsigned {
+  WASM_STACK_POINTER = 0x1,
+};
+
 #define WASM_RELOC(name, value) name = value,
 
 enum : unsigned {
@@ -178,6 +183,19 @@ enum : unsigned {
 
 #undef WASM_RELOC
 
+struct Global {
+  ValType Type;
+  bool Mutable;
+
+  // The initial value for this global is either the value of an imported
+  // global, in which case InitialModule and InitialName specify the global
+  // import, or a value, in which case InitialModule is empty and InitialValue
+  // holds the value.
+  StringRef InitialModule;
+  StringRef InitialName;
+  uint64_t InitialValue;
+};
+
 } // end namespace wasm
 } // end namespace llvm
 

Modified: llvm/trunk/include/llvm/Support/WasmRelocs/WebAssembly.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/WasmRelocs/WebAssembly.def?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/WasmRelocs/WebAssembly.def (original)
+++ llvm/trunk/include/llvm/Support/WasmRelocs/WebAssembly.def Thu Mar 30 18:58:19 2017
@@ -9,3 +9,5 @@ WASM_RELOC(R_WEBASSEMBLY_TABLE_INDEX_I32
 WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_LEB,      3)
 WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_SLEB,     4)
 WASM_RELOC(R_WEBASSEMBLY_GLOBAL_ADDR_I32,      5)
+WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB,       6)
+WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB,     7)

Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Thu Mar 30 18:58:19 2017
@@ -50,16 +50,6 @@ struct SectionBookkeeping {
   uint64_t ContentsOffset;
 };
 
-// This record records information about a call_indirect which needs its
-// type index fixed up once we've computed type indices.
-struct TypeIndexFixup {
-  uint64_t Offset;
-  const MCSymbolWasm *Symbol;
-  const MCSectionWasm *FixupSection;
-  TypeIndexFixup(uint64_t O, const MCSymbolWasm *S, MCSectionWasm *F)
-    : Offset(O), Symbol(S), FixupSection(F) {}
-};
-
 class WasmObjectWriter : public MCObjectWriter {
   /// Helper struct for containing some precomputed information on symbols.
   struct WasmSymbolData {
@@ -80,7 +70,7 @@ class WasmObjectWriter : public MCObject
   std::vector<WasmRelocationEntry> DataRelocations;
 
   // Fixups for call_indirect type indices.
-  std::vector<TypeIndexFixup> TypeIndexFixups;
+  std::vector<WasmRelocationEntry> TypeIndexFixups;
 
   // Index values to use for fixing up call_indirect type indices.
   std::vector<uint32_t> TypeIndexFixupTypes;
@@ -269,8 +259,11 @@ void WasmObjectWriter::recordRelocation(
 
   if (RefA) {
     if (RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX) {
-      TypeIndexFixups.push_back(TypeIndexFixup(FixupOffset, SymA,
-                                               &FixupSection));
+      assert(C == 0);
+      WasmRelocationEntry Rec(FixupOffset, SymA, C,
+                              wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB,
+                              &FixupSection);
+      TypeIndexFixups.push_back(Rec);
       return;
     }
   }
@@ -358,7 +351,9 @@ struct WasmExport {
 struct WasmGlobal {
   wasm::ValType Type;
   bool IsMutable;
-  uint32_t InitialValue;
+  bool HasImport;
+  uint64_t InitialValue;
+  uint32_t ImportIndex;
 };
 
 } // end anonymous namespace
@@ -507,6 +502,29 @@ static void WriteRelocations(
   }
 }
 
+// Write out the the type relocation records that the linker will
+// need to handle.
+static void WriteTypeRelocations(
+    ArrayRef<WasmRelocationEntry> TypeIndexFixups,
+    ArrayRef<uint32_t> TypeIndexFixupTypes,
+    raw_pwrite_stream &Stream)
+{
+  for (size_t i = 0, e = TypeIndexFixups.size(); i < e; ++i) {
+    const WasmRelocationEntry &Fixup = TypeIndexFixups[i];
+    uint32_t Type = TypeIndexFixupTypes[i];
+
+    assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
+    assert(Fixup.Addend == 0);
+
+    uint64_t Offset = Fixup.Offset +
+                      Fixup.FixupSection->getSectionOffset();
+
+    encodeULEB128(Fixup.Type, Stream);
+    encodeULEB128(Offset, Stream);
+    encodeULEB128(Type, Stream);
+  }
+}
+
 void WasmObjectWriter::writeObject(MCAssembler &Asm,
                                    const MCAsmLayout &Layout) {
   MCContext &Ctx = Asm.getContext();
@@ -526,6 +544,8 @@ void WasmObjectWriter::writeObject(MCAss
   unsigned NumFuncImports = 0;
   unsigned NumGlobalImports = 0;
   SmallVector<char, 0> DataBytes;
+  uint32_t StackPointerGlobal = 0;
+  bool HasStackPointer = false;
 
   // Populate the IsAddressTaken set.
   for (WasmRelocationEntry RelEntry : CodeRelocations) {
@@ -605,15 +625,68 @@ void WasmObjectWriter::writeObject(MCAss
     if (!DataFrag.getFixups().empty())
       report_fatal_error("fixups not supported in .global_variables");
     const SmallVectorImpl<char> &Contents = DataFrag.getContents();
-    for (char p : Contents) {
+    for (const uint8_t *p = (const uint8_t *)Contents.data(),
+                     *end = (const uint8_t *)Contents.data() + Contents.size();
+         p != end; ) {
       WasmGlobal G;
-      G.Type = wasm::ValType(p);
-      G.IsMutable = true;
-      G.InitialValue = 0;
+      if (end - p < 3)
+        report_fatal_error("truncated global variable encoding");
+      G.Type = wasm::ValType(int8_t(*p++));
+      G.IsMutable = bool(*p++);
+      G.HasImport = bool(*p++);
+      if (G.HasImport) {
+        G.InitialValue = 0;
+
+        WasmImport Import;
+        Import.ModuleName = (const char *)p;
+        const uint8_t *nul = (const uint8_t *)memchr(p, '\0', end - p);
+        if (!nul)
+          report_fatal_error("global module name must be nul-terminated");
+        p = nul + 1;
+        nul = (const uint8_t *)memchr(p, '\0', end - p);
+        if (!nul)
+          report_fatal_error("global base name must be nul-terminated");
+        Import.FieldName = (const char *)p;
+        p = nul + 1;
+
+        Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
+        Import.Type = int32_t(G.Type);
+
+        G.ImportIndex = NumGlobalImports;
+        ++NumGlobalImports;
+
+        Imports.push_back(Import);
+      } else {
+        unsigned n;
+        G.InitialValue = decodeSLEB128(p, &n);
+        G.ImportIndex = 0;
+        if (n > end - p)
+          report_fatal_error("global initial value must be valid SLEB128");
+        p += n;
+      }
       Globals.push_back(G);
     }
   }
 
+  // In the special .stack_pointer section, we've encoded the stack pointer
+  // index.
+  MCSectionWasm *StackPtr = Ctx.getWasmSection(".stack_pointer", 0, 0);
+  if (!StackPtr->getFragmentList().empty()) {
+    if (StackPtr->getFragmentList().size() != 1)
+      report_fatal_error("only one .stack_pointer fragment supported");
+    const MCFragment &Frag = *StackPtr->begin();
+    if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
+      report_fatal_error("only data supported in .stack_pointer");
+    const MCDataFragment &DataFrag = cast<MCDataFragment>(Frag);
+    if (!DataFrag.getFixups().empty())
+      report_fatal_error("fixups not supported in .stack_pointer");
+    const SmallVectorImpl<char> &Contents = DataFrag.getContents();
+    if (Contents.size() != 4)
+      report_fatal_error("only one entry supported in .stack_pointer");
+    HasStackPointer = true;
+    StackPointerGlobal = NumGlobalImports + *(const int32_t *)Contents.data();
+  }
+
   // Handle defined symbols.
   for (const MCSymbol &S : Asm.symbols()) {
     // Ignore unnamed temporary symbols, which aren't ever exported, imported,
@@ -712,7 +785,9 @@ void WasmObjectWriter::writeObject(MCAss
           WasmGlobal Global;
           Global.Type = PtrType;
           Global.IsMutable = false;
+          Global.HasImport = false;
           Global.InitialValue = DataSection.getSectionOffset();
+          Global.ImportIndex = 0;
           SymbolIndices[&WS] = Index;
           Globals.push_back(Global);
         }
@@ -736,7 +811,10 @@ void WasmObjectWriter::writeObject(MCAss
   }
 
   // Add types for indirect function calls.
-  for (const TypeIndexFixup &Fixup : TypeIndexFixups) {
+  for (const WasmRelocationEntry &Fixup : TypeIndexFixups) {
+    assert(Fixup.Addend == 0);
+    assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
+
     WasmFunctionType F;
     F.Returns = Fixup.Symbol->getReturns();
     F.Params = Fixup.Symbol->getParams();
@@ -793,7 +871,7 @@ void WasmObjectWriter::writeObject(MCAss
         encodeULEB128(Import.Type, getStream());
         break;
       case wasm::WASM_EXTERNAL_GLOBAL:
-        encodeSLEB128(Import.Type, getStream());
+        encodeSLEB128(int32_t(Import.Type), getStream());
         encodeULEB128(0, getStream()); // mutability
         break;
       default:
@@ -853,8 +931,15 @@ void WasmObjectWriter::writeObject(MCAss
       writeValueType(Global.Type);
       write8(Global.IsMutable);
 
-      write8(wasm::WASM_OPCODE_I32_CONST);
-      encodeSLEB128(Global.InitialValue, getStream()); // offset
+      if (Global.HasImport) {
+        assert(Global.InitialValue == 0);
+        write8(wasm::WASM_OPCODE_GET_GLOBAL);
+        encodeULEB128(Global.ImportIndex, getStream());
+      } else {
+        assert(Global.ImportIndex == 0);
+        write8(wasm::WASM_OPCODE_I32_CONST);
+        encodeSLEB128(Global.InitialValue, getStream()); // offset
+      }
       write8(wasm::WASM_OPCODE_END);
     }
 
@@ -944,7 +1029,9 @@ void WasmObjectWriter::writeObject(MCAss
       uint32_t Type = TypeIndexFixupTypes[i];
       unsigned Padding = PaddingFor5ByteULEB128(Type);
 
-      const TypeIndexFixup &Fixup = TypeIndexFixups[i];
+      const WasmRelocationEntry &Fixup = TypeIndexFixups[i];
+      assert(Fixup.Addend == 0);
+      assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
       uint64_t Offset = Fixup.Offset +
                         Fixup.FixupSection->getSectionOffset();
 
@@ -1021,6 +1108,7 @@ void WasmObjectWriter::writeObject(MCAss
     encodeULEB128(CodeRelocations.size(), getStream());
 
     WriteRelocations(CodeRelocations, getStream(), SymbolIndices);
+    WriteTypeRelocations(TypeIndexFixups, TypeIndexFixupTypes, getStream());
 
     endSection(Section);
   }
@@ -1037,6 +1125,18 @@ void WasmObjectWriter::writeObject(MCAss
 
     endSection(Section);
   }
+
+  // === Linking Metadata Section ==============================================
+  if (HasStackPointer) {
+    startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
+
+    encodeULEB128(1, getStream()); // count
+
+    encodeULEB128(wasm::WASM_STACK_POINTER, getStream()); // type
+    encodeULEB128(StackPointerGlobal, getStream()); // id
+
+    endSection(Section);
+  }
 
   // TODO: Translate the .comment section to the output.
 

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp Thu Mar 30 18:58:19 2017
@@ -242,3 +242,18 @@ const char *llvm::WebAssembly::TypeToStr
     llvm_unreachable("unsupported type");
   }
 }
+
+const char *llvm::WebAssembly::TypeToString(wasm::ValType Type) {
+  switch (Type) {
+  case wasm::ValType::I32:
+    return "i32";
+  case wasm::ValType::I64:
+    return "i64";
+  case wasm::ValType::F32:
+    return "f32";
+  case wasm::ValType::F64:
+    return "f64";
+  default:
+    llvm_unreachable("unsupported type");
+  }
+}

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h Thu Mar 30 18:58:19 2017
@@ -18,6 +18,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/CodeGen/MachineValueType.h"
 #include "llvm/MC/MCInstPrinter.h"
+#include "llvm/Support/Wasm.h"
 
 namespace llvm {
 
@@ -50,6 +51,7 @@ public:
 namespace WebAssembly {
 
 const char *TypeToString(MVT Ty);
+const char *TypeToString(wasm::ValType Type);
 
 } // end namespace WebAssembly
 

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp Thu Mar 30 18:58:19 2017
@@ -25,7 +25,6 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Wasm.h"
 using namespace llvm;
 
 WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)
@@ -88,13 +87,31 @@ void WebAssemblyTargetAsmStreamer::emitL
   }
 }
 
-void WebAssemblyTargetAsmStreamer::emitGlobal(ArrayRef<MVT> Types) {
-  if (!Types.empty()) {
+void WebAssemblyTargetAsmStreamer::emitGlobal(
+    ArrayRef<wasm::Global> Globals) {
+  if (!Globals.empty()) {
     OS << "\t.globalvar  \t";
-    PrintTypes(OS, Types);
+
+    bool First = true;
+    for (const wasm::Global &G : Globals) {
+      if (First)
+        First = false;
+      else
+        OS << ", ";
+      OS << WebAssembly::TypeToString(G.Type);
+      if (!G.InitialModule.empty())
+        OS << '=' << G.InitialModule << ':' << G.InitialName;
+      else
+        OS << '=' << G.InitialValue;
+    }
+    OS << '\n';
   }
 }
 
+void WebAssemblyTargetAsmStreamer::emitStackPointer(uint32_t Index) {
+  OS << "\t.stack_pointer\t" << Index << '\n';
+}
+
 void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
 
 void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
@@ -135,10 +152,16 @@ void WebAssemblyTargetELFStreamer::emitL
     emitValueType(WebAssembly::toValType(Type));
 }
 
-void WebAssemblyTargetELFStreamer::emitGlobal(ArrayRef<MVT> Types) {
+void WebAssemblyTargetELFStreamer::emitGlobal(
+    ArrayRef<wasm::Global> Globals) {
   llvm_unreachable(".globalvar encoding not yet implemented");
 }
 
+void WebAssemblyTargetELFStreamer::emitStackPointer(
+    uint32_t Index) {
+  llvm_unreachable(".stack_pointer encoding not yet implemented");
+}
+
 void WebAssemblyTargetELFStreamer::emitEndFunc() {
   Streamer.EmitIntValue(WebAssembly::End, 1);
 }
@@ -190,15 +213,36 @@ void WebAssemblyTargetWasmStreamer::emit
   }
 }
 
-void WebAssemblyTargetWasmStreamer::emitGlobal(ArrayRef<MVT> Types) {
+void WebAssemblyTargetWasmStreamer::emitGlobal(
+    ArrayRef<wasm::Global> Globals) {
   // Encode the globals use by the funciton into the special .global_variables
   // section. This will later be decoded and turned into contents for the
   // Globals Section.
   Streamer.PushSection();
   Streamer.SwitchSection(Streamer.getContext()
                                  .getWasmSection(".global_variables", 0, 0));
-  for (MVT Ty : Types)
-    Streamer.EmitIntValue(int64_t(WebAssembly::toValType(Ty)), 1);
+  for (const wasm::Global &G : Globals) {
+    Streamer.EmitIntValue(int32_t(G.Type), 1);
+    Streamer.EmitIntValue(G.Mutable, 1);
+    if (G.InitialModule.empty()) {
+      Streamer.EmitIntValue(0, 1); // indicate that we have an int value
+      Streamer.EmitSLEB128IntValue(0);
+    } else {
+      Streamer.EmitIntValue(1, 1); // indicate that we have a module import
+      Streamer.EmitBytes(G.InitialModule);
+      Streamer.EmitIntValue(0, 1); // nul-terminate
+      Streamer.EmitBytes(G.InitialName);
+      Streamer.EmitIntValue(0, 1); // nul-terminate
+    }
+  }
+  Streamer.PopSection();
+}
+
+void WebAssemblyTargetWasmStreamer::emitStackPointer(uint32_t Index) {
+  Streamer.PushSection();
+  Streamer.SwitchSection(Streamer.getContext()
+                                 .getWasmSection(".stack_pointer", 0, 0));
+  Streamer.EmitIntValue(Index, 4);
   Streamer.PopSection();
 }
 

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h Thu Mar 30 18:58:19 2017
@@ -38,7 +38,9 @@ public:
   /// .local
   virtual void emitLocal(ArrayRef<MVT> Types) = 0;
   /// .globalvar
-  virtual void emitGlobal(ArrayRef<MVT> Types) = 0;
+  virtual void emitGlobal(ArrayRef<wasm::Global> Globals) = 0;
+  /// .stack_pointer
+  virtual void emitStackPointer(uint32_t Index) = 0;
   /// .endfunc
   virtual void emitEndFunc() = 0;
   /// .functype
@@ -66,7 +68,8 @@ public:
   void emitParam(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitLocal(ArrayRef<MVT> Types) override;
-  void emitGlobal(ArrayRef<MVT> Types) override;
+  void emitGlobal(ArrayRef<wasm::Global> Globals) override;
+  void emitStackPointer(uint32_t Index) override;
   void emitEndFunc() override;
   void emitIndirectFunctionType(StringRef name,
                                 SmallVectorImpl<MVT> &Params,
@@ -83,7 +86,8 @@ public:
   void emitParam(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitLocal(ArrayRef<MVT> Types) override;
-  void emitGlobal(ArrayRef<MVT> Types) override;
+  void emitGlobal(ArrayRef<wasm::Global> Globals) override;
+  void emitStackPointer(uint32_t Index) override;
   void emitEndFunc() override;
   void emitIndirectFunctionType(StringRef name,
                                 SmallVectorImpl<MVT> &Params,
@@ -100,7 +104,8 @@ public:
   void emitParam(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override;
   void emitLocal(ArrayRef<MVT> Types) override;
-  void emitGlobal(ArrayRef<MVT> Types) override;
+  void emitGlobal(ArrayRef<wasm::Global> Globals) override;
+  void emitStackPointer(uint32_t Index) override;
   void emitEndFunc() override;
   void emitIndirectFunctionType(StringRef name,
                                 SmallVectorImpl<MVT> &Params,

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Thu Mar 30 18:58:19 2017
@@ -97,6 +97,8 @@ void WebAssemblyAsmPrinter::EmitEndOfAsm
   if (!TM.getTargetTriple().isOSBinFormatELF()) {
     MachineModuleInfoWasm &MMIW = MMI->getObjFileInfo<MachineModuleInfoWasm>();
     getTargetStreamer()->emitGlobal(MMIW.getGlobals());
+    if (MMIW.hasStackPointerGlobal())
+      getTargetStreamer()->emitStackPointer(MMIW.getStackPointerGlobal());
   }
 }
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp?rev=299141&r1=299140&r2=299141&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp Thu Mar 30 18:58:19 2017
@@ -192,7 +192,16 @@ void WebAssemblyFrameLowering::emitProlo
     auto &MMIW = MF.getMMI().getObjFileInfo<MachineModuleInfoWasm>();
     if (!MMIW.hasStackPointerGlobal()) {
       MMIW.setStackPointerGlobal(MMIW.getGlobals().size());
-      MMIW.addGlobal(MVT::i32);
+
+      // Create the stack-pointer global. For now, just use the
+      // Emscripten/Binaryen ABI names.
+      wasm::Global G;
+      G.Type = wasm::ValType::I32;
+      G.Mutable = true;
+      G.InitialValue = 0;
+      G.InitialModule = "env";
+      G.InitialName = "STACKTOP";
+      MMIW.addGlobal(G);
     }
     BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GET_GLOBAL_I32), SPReg)
         .addImm(MMIW.getStackPointerGlobal());




More information about the llvm-commits mailing list