[PATCH] D104945: [WebAssembly] Added initial type checker to MC Assembler

Sam Clegg via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 28 14:45:26 PDT 2021


sbc100 added a subscriber: pmatos.
sbc100 added a comment.

lgtm

We should probably wait for @dschuff input before landing.



================
Comment at: llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h:113
+
+  StringSet<> MachineSymbolsUsed;
+};
----------------
The classes above seem to track sets of `MCSymbol*` (see SymbolListTy).  Would that make sense here too (rather than StringRef)?


================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp:248
+  std::map<unsigned, TypeStack> TypedLabels;
+  std::vector<wasm::ValType> LocalTypes;
+  std::vector<wasm::ValType> ReturnTypes;
----------------
Why not SmallVector like above?  


================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp:257
       : MCTargetAsmParser(Options, STI, MII), Parser(Parser),
         Lexer(Parser.getLexer()) {
     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
----------------
Can we do `SkipTypeCheck(Options.MCNoTypeCheck)` here in the member initializer?   (same with `is64(STI.getTargetTriple().isArch64Bit())`?

Then the don't need to inline `= false` above either I guess?


================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp:269
+    if (BufferName == "<inline asm>")
+      SkipTypeCheck = true;
   }
----------------
Is this a permanent caveat or should we have a TODO here? 


================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp:1195
+    return false;
+  }
+
----------------
All this new code here makes me wonder if the typechecker should be its own class with its own state.   Maybe not worth it?


================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp:1361
+  assert(false && "mnemonic not found");
+  return StringRef();
+}
----------------
I surprised this functionality doesn't exist somewhere else already..


================
Comment at: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp:212
+MCSymbol *WebAssemblyAsmPrinter::SetWasmSymType(StringRef Name) {
+  auto *WasmSym = cast<MCSymbolWasm>(GetExternalSymbolSymbol(Name));
+  const WebAssemblySubtarget &Subtarget = getSubtarget();
----------------
Is this function called maybe times with the same name?   Can/shouldSetWasmSymType we avoid re-doing the work herein?

I just saw you have a FIXME for that already below.  Maybe we can tell if this symbols has already had its type set and early out?


================
Comment at: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp:366
+  for (const auto &F : M) {
+    if (F.hasAddressTaken()) {
+      MCSymbolWasm *FunctionTable =
----------------
The old `HasAddressTakenFunction` was only set if `!F.isIntrinsic()` too.. is this change OK/indended?


================
Comment at: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp:375
   for (const auto &G : M.globals()) {
+    auto S = G.getName();
     if (!G.hasInitializer() && G.hasExternalLinkage() &&
----------------
Left over debugging?


================
Comment at: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp:528
+  AsmPrinter::emitLinkage(GV, Sym);
+  // This gets called before the function label and type are emitted.
+  // We use it to emit signatures of external functions.
----------------
So other AsmPrinters use this print the linkage of a single symbol, but we are co-opting to print the all signatures?   


================
Comment at: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp:531
+  // FIXME casts!
+  ((WebAssemblyAsmPrinter *)this)->emitExternalDecls(*MMI->getModule());
+}
----------------
Is this just const cast?  Why not use `const_cast`?  


================
Comment at: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h:86
                                        bool &InvokeDetected);
+  MCSymbol *SetWasmSymType(StringRef Name);
+  void emitExternalDecls(const Module &M);
----------------
I think the direction is towards `lowerSnakeCase` in this API.   Also it would match better with `getMCSymbolForFunction` above to call this `setWasmSymType`.


================
Comment at: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td:16
 multiclass TABLE<WebAssemblyRegClass rt> {
-  defm TABLE_GET_#rt : I<(outs rt:$res), (ins table32_op:$table),
+  defm TABLE_GET_#rt : I<(outs rt:$res), (ins table32_op:$table, I32:$i),
                          (outs), (ins table32_op:$table),
----------------
I don't really grok this part of the change.   @pmatos will know more.   Can we split part out since it feels like its own bugfix.   How was it not breaking stuff?  (Or was it?)


================
Comment at: llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp:94
     const MachineOperand &MO) const {
-  const char *Name = MO.getSymbolName();
-  auto *WasmSym = cast<MCSymbolWasm>(Printer.GetExternalSymbolSymbol(Name));
-  const WebAssemblySubtarget &Subtarget = Printer.getSubtarget();
-
-  // Except for certain known symbols, all symbols used by CodeGen are
-  // functions. It's OK to hardcode knowledge of specific symbols here; this
-  // method is precisely there for fetching the signatures of known
-  // Clang-provided symbols.
-  if (strcmp(Name, "__stack_pointer") == 0 || strcmp(Name, "__tls_base") == 0 ||
-      strcmp(Name, "__memory_base") == 0 || strcmp(Name, "__table_base") == 0 ||
-      strcmp(Name, "__tls_size") == 0 || strcmp(Name, "__tls_align") == 0) {
-    bool Mutable =
-        strcmp(Name, "__stack_pointer") == 0 || strcmp(Name, "__tls_base") == 0;
-    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
-    WasmSym->setGlobalType(wasm::WasmGlobalType{
-        uint8_t(Subtarget.hasAddr64() ? wasm::WASM_TYPE_I64
-                                      : wasm::WASM_TYPE_I32),
-        Mutable});
-    return WasmSym;
-  }
-
-  SmallVector<wasm::ValType, 4> Returns;
-  SmallVector<wasm::ValType, 4> Params;
-  if (strcmp(Name, "__cpp_exception") == 0) {
-    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_EVENT);
-    // We can't confirm its signature index for now because there can be
-    // imported exceptions. Set it to be 0 for now.
-    WasmSym->setEventType(
-        {wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION, /* SigIndex */ 0});
-    // We may have multiple C++ compilation units to be linked together, each of
-    // which defines the exception symbol. To resolve them, we declare them as
-    // weak.
-    WasmSym->setWeak(true);
-    WasmSym->setExternal(true);
-
-    // All C++ exceptions are assumed to have a single i32 (for wasm32) or i64
-    // (for wasm64) param type and void return type. The reaon is, all C++
-    // exception values are pointers, and to share the type section with
-    // functions, exceptions are assumed to have void return type.
-    Params.push_back(Subtarget.hasAddr64() ? wasm::ValType::I64
-                                           : wasm::ValType::I32);
-  } else { // Function symbols
-    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
-    getLibcallSignature(Subtarget, Name, Returns, Params);
-  }
-  auto Signature =
-      std::make_unique<wasm::WasmSignature>(std::move(Returns), std::move(Params));
-  WasmSym->setSignature(Signature.get());
-  Printer.addSignature(std::move(Signature));
-
-  return WasmSym;
+  return Printer.SetWasmSymType(MO.getSymbolName());
 }
----------------
Actually maybe we should just call this method something like getOrCreateWasmSymbol?  (don't feel strongly about this).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D104945/new/

https://reviews.llvm.org/D104945



More information about the llvm-commits mailing list