From 3aa0189bfe3606c48af75cde04562f29273dfbcc Mon Sep 17 00:00:00 2001 From: JF Bastien Date: Wed, 21 Oct 2015 02:23:09 +0000 Subject: [PATCH] WebAssembly: support imports C/C++ code can declare an extern function, which will show up as an import in WebAssembly's output. It's expected that the linker will resolve these, and mark unresolved imports as call_import (I have a patch which does this in wasmate). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250875 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 24 ++++++++++++++++++- test/CodeGen/WebAssembly/import.ll | 21 ++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/WebAssembly/import.ll diff --git a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index e20ee695e6f..f3e3170dad2 100644 --- a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -77,8 +77,8 @@ private: void EmitJumpTableInfo() override; void EmitConstantPool() override; void EmitFunctionBodyStart() override; - void EmitInstruction(const MachineInstr *MI) override; + void EmitEndOfAsmFile(Module &M) override; std::string getRegTypeName(unsigned RegNo) const; static std::string toString(const APFloat &APF); @@ -330,6 +330,28 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) { } } +void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { + SmallString<128> Str; + raw_svector_ostream OS(Str); + for (const Function &F : M) + if (F.isDeclarationForLinker()) { + assert(F.hasName() && "imported functions must have a name"); + if (F.getName().startswith("llvm.")) + continue; + if (Str.empty()) + OS << "\t.imports\n"; + Type *Rt = F.getReturnType(); + OS << "\t.import " << toSymbol(F.getName()) << " \"\" \"" << F.getName() + << "\""; + for (const Argument &A : F.args()) + OS << " (param " << toString(A.getType()) << ')'; + if (!Rt->isVoidTy()) + OS << " (result " << toString(Rt) << ')'; + OS << '\n'; + } + OutStreamer->EmitRawText(OS.str()); +} + // Force static initialization. extern "C" void LLVMInitializeWebAssemblyAsmPrinter() { RegisterAsmPrinter X(TheWebAssemblyTarget32); diff --git a/test/CodeGen/WebAssembly/import.ll b/test/CodeGen/WebAssembly/import.ll new file mode 100644 index 00000000000..d1dca7fa8bb --- /dev/null +++ b/test/CodeGen/WebAssembly/import.ll @@ -0,0 +1,21 @@ +; RUN: llc < %s -asm-verbose=false | FileCheck %s + +target datalayout = "e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +; CHECK-LABEL: .text +; CHECK-LABEL: f: +define void @f(i32 %a, float %b) { + tail call i32 @printi(i32 %a) + tail call float @printf(float %b) + tail call void @printv() + ret void +} + +; CHECK-LABEL: .imports +; CHECK-NEXT: .import $printi "" "printi" (param i32) (result i32) +; CHECK-NEXT: .import $printf "" "printf" (param f32) (result f32) +; CHECK-NEXT: .import $printv "" "printv" +declare i32 @printi(i32) +declare float @printf(float) +declare void @printv() -- 2.34.1