diff options
author | Derek Schuff <dschuff@google.com> | 2016-06-03 18:34:36 +0000 |
---|---|---|
committer | Derek Schuff <dschuff@google.com> | 2016-06-03 18:34:36 +0000 |
commit | 5859a9ed80829bf3eee5f8e9946b0ab0d2142600 (patch) | |
tree | 0cb6a628d9d33ce3eebbaf07026d3f3462039f86 /llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp | |
parent | 96938d67b601dc7a9b9f1b4f70c1371ea406d08b (diff) | |
download | bcm5719-llvm-5859a9ed80829bf3eee5f8e9946b0ab0d2142600.tar.gz bcm5719-llvm-5859a9ed80829bf3eee5f8e9946b0ab0d2142600.zip |
[WebAssembly] Emit type signatures for declared functions
Under emscripten, C code can take the address of a function implemented
in Javascript (which is exposed via an import in wasm). Because imports
do not have linear memory address in wasm, we need to generate a thunk
to be the target of the indirect call; it call the import directly.
To make this possible, LLVM needs to emit the type signatures for these
functions, because they may not be called directly or referred to other
than where the address is taken.
This uses s new .s directive (.functype) which specifies the signature.
Differential Revision: http://reviews.llvm.org/D20891
Re-apply r271599 but instead of bailing with an error when a declared
function has multiple returns, replace it with a pointer argument. Also
add the test case I forgot to 'git add' last time around.
llvm-svn: 271703
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 64128bf031e..54e9f7f5290 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -67,6 +67,7 @@ private: // AsmPrinter Implementation. //===------------------------------------------------------------------===// + void EmitEndOfAsmFile(Module &M) override; void EmitJumpTableInfo() override; void EmitConstantPool() override; void EmitFunctionBodyStart() override; @@ -124,16 +125,6 @@ WebAssemblyTargetStreamer *WebAssemblyAsmPrinter::getTargetStreamer() { //===----------------------------------------------------------------------===// // WebAssemblyAsmPrinter Implementation. //===----------------------------------------------------------------------===// - -void WebAssemblyAsmPrinter::EmitConstantPool() { - assert(MF->getConstantPool()->getConstants().empty() && - "WebAssembly disables constant pools"); -} - -void WebAssemblyAsmPrinter::EmitJumpTableInfo() { - // Nothing to do; jump tables are incorporated into the instruction stream. -} - static void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, SmallVectorImpl<MVT> &ValueVTs) { const DataLayout &DL(F.getParent()->getDataLayout()); @@ -150,6 +141,42 @@ static void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, } } +void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { + for (const auto &F : M) { + // Emit function type info for all undefined functions + if (F.isDeclarationForLinker() && !F.isIntrinsic()) { + SmallVector<MVT, 4> SignatureVTs; + ComputeLegalValueVTs(F, TM, F.getReturnType(), SignatureVTs); + size_t NumResults = SignatureVTs.size(); + if (SignatureVTs.size() > 1) { + // WebAssembly currently can't lower returns of multiple values without + // demoting to sret (see WebAssemblyTargetLowering::CanLowerReturn). So + // replace multiple return values with a pointer parameter. + SignatureVTs.clear(); + SignatureVTs.push_back( + MVT::getIntegerVT(M.getDataLayout().getPointerSizeInBits())); + NumResults = 0; + } + + for (auto &Arg : F.args()) { + ComputeLegalValueVTs(F, TM, Arg.getType(), SignatureVTs); + } + + getTargetStreamer()->emitIndirectFunctionType(F.getName(), SignatureVTs, + NumResults); + } + } +} + +void WebAssemblyAsmPrinter::EmitConstantPool() { + assert(MF->getConstantPool()->getConstants().empty() && + "WebAssembly disables constant pools"); +} + +void WebAssemblyAsmPrinter::EmitJumpTableInfo() { + // Nothing to do; jump tables are incorporated into the instruction stream. +} + void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { if (!MFI->getParams().empty()) getTargetStreamer()->emitParam(MFI->getParams()); |