diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly')
10 files changed, 106 insertions, 118 deletions
diff --git a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp index 045d4fb4fd6..b7b8c4fe039 100644 --- a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp @@ -235,26 +235,19 @@ void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI, } } -const char *llvm::WebAssembly::TypeToString(MVT Ty) { - switch (Ty.SimpleTy) { - case MVT::i32: +const char *llvm::WebAssembly::TypeToString(wasm::ValType Ty) { + switch (Ty) { + case wasm::ValType::I32: return "i32"; - case MVT::i64: + case wasm::ValType::I64: return "i64"; - case MVT::f32: + case wasm::ValType::F32: return "f32"; - case MVT::f64: + case wasm::ValType::F64: return "f64"; - case MVT::v16i8: - case MVT::v8i16: - case MVT::v4i32: - case MVT::v2i64: - case MVT::v4f32: - case MVT::v2f64: + case wasm::ValType::V128: return "v128"; - case MVT::ExceptRef: + case wasm::ValType::EXCEPT_REF: return "except_ref"; - default: - llvm_unreachable("unsupported type"); } } diff --git a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h index 2bb6dcea9e0..18023328b38 100644 --- a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h @@ -50,7 +50,7 @@ public: namespace WebAssembly { -const char *TypeToString(MVT Ty); +const char *TypeToString(wasm::ValType Ty); } // end namespace WebAssembly diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp index 961ef8146a9..2158ee3be04 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -46,7 +46,7 @@ static void PrintTypes(formatted_raw_ostream &OS, ArrayRef<MVT> Types) { First = false; else OS << ", "; - OS << WebAssembly::TypeToString(Type); + OS << WebAssembly::TypeToString(WebAssembly::toValType(Type)); } OS << '\n'; } @@ -85,16 +85,16 @@ void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<MVT> Types) { void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; } void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType( - MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, - SmallVectorImpl<MVT> &Results) { + MCSymbolWasm *Symbol) { OS << "\t.functype\t" << Symbol->getName(); - if (Results.empty()) + if (Symbol->getSignature()->Returns.empty()) OS << ", void"; else { - assert(Results.size() == 1); - OS << ", " << WebAssembly::TypeToString(Results.front()); + assert(Symbol->getSignature()->Returns.size() == 1); + OS << ", " + << WebAssembly::TypeToString(Symbol->getSignature()->Returns.front()); } - for (auto Ty : Params) + for (auto Ty : Symbol->getSignature()->Params) OS << ", " << WebAssembly::TypeToString(Ty); OS << '\n'; } @@ -114,20 +114,12 @@ void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) { void WebAssemblyTargetWasmStreamer::emitParam(MCSymbol *Symbol, ArrayRef<MVT> Types) { - SmallVector<wasm::ValType, 4> Params; - for (MVT Ty : Types) - Params.push_back(WebAssembly::toValType(Ty)); - - cast<MCSymbolWasm>(Symbol)->setParams(std::move(Params)); + // The Symbol already has its signature } void WebAssemblyTargetWasmStreamer::emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) { - SmallVector<wasm::ValType, 4> Returns; - for (MVT Ty : Types) - Returns.push_back(WebAssembly::toValType(Ty)); - - cast<MCSymbolWasm>(Symbol)->setReturns(std::move(Returns)); + // The Symbol already has its signature } void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<MVT> Types) { @@ -155,25 +147,9 @@ void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) { } void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType( - MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, - SmallVectorImpl<MVT> &Results) { - MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Symbol); - if (WasmSym->isFunction()) { - // Symbol already has its arguments and result set. - return; - } - - SmallVector<wasm::ValType, 4> ValParams; - for (MVT Ty : Params) - ValParams.push_back(WebAssembly::toValType(Ty)); - - SmallVector<wasm::ValType, 1> ValResults; - for (MVT Ty : Results) - ValResults.push_back(WebAssembly::toValType(Ty)); - - WasmSym->setParams(std::move(ValParams)); - WasmSym->setReturns(std::move(ValResults)); - WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); + MCSymbolWasm *Symbol) { + // Symbol already has its arguments and result set. + Symbol->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); } void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) { diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h index 124161c5579..43c422d593a 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h @@ -40,9 +40,7 @@ public: /// .endfunc virtual void emitEndFunc() = 0; /// .functype - virtual void emitIndirectFunctionType(MCSymbol *Symbol, - SmallVectorImpl<MVT> &Params, - SmallVectorImpl<MVT> &Results) = 0; + virtual void emitIndirectFunctionType(MCSymbolWasm *Symbol) = 0; /// .indidx virtual void emitIndIdx(const MCExpr *Value) = 0; /// .import_global @@ -65,8 +63,7 @@ public: void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override; void emitLocal(ArrayRef<MVT> Types) override; void emitEndFunc() override; - void emitIndirectFunctionType(MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, - SmallVectorImpl<MVT> &Results) override; + void emitIndirectFunctionType(MCSymbolWasm *Symbol) override; void emitIndIdx(const MCExpr *Value) override; void emitGlobalImport(StringRef name) override; void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) override; @@ -81,8 +78,7 @@ public: void emitResult(MCSymbol *Symbol, ArrayRef<MVT> Types) override; void emitLocal(ArrayRef<MVT> Types) override; void emitEndFunc() override; - void emitIndirectFunctionType(MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, - SmallVectorImpl<MVT> &Results) override; + void emitIndirectFunctionType(MCSymbolWasm *Symbol) override; void emitIndIdx(const MCExpr *Value) override; void emitGlobalImport(StringRef name) override; void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) override; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 20b41e1ffab..2ea3760b923 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -83,16 +83,25 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { if (F.isDeclarationForLinker() && !F.isIntrinsic()) { SmallVector<MVT, 4> Results; SmallVector<MVT, 4> Params; - ComputeSignatureVTs(F, TM, Params, Results); - MCSymbol *Sym = getSymbol(&F); - getTargetStreamer()->emitIndirectFunctionType(Sym, Params, Results); + ComputeSignatureVTs(F.getFunctionType(), F, TM, Params, Results); + auto *Sym = cast<MCSymbolWasm>(getSymbol(&F)); + if (!Sym->getSignature()) { + auto Signature = SignatureFromMVTs(Results, Params); + Sym->setSignature(Signature.get()); + addSignature(std::move(Signature)); + } + // FIXME: this was originally intended for post-linking and was only used + // for imports that were only called indirectly (i.e. s2wasm could not + // infer the type from a call). With object files it applies to all + // imports. so fix the names and the tests, or rethink how import + // delcarations work in asm files. + getTargetStreamer()->emitIndirectFunctionType(Sym); if (TM.getTargetTriple().isOSBinFormatWasm() && F.hasFnAttribute("wasm-import-module")) { - MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Sym); StringRef Name = F.getFnAttribute("wasm-import-module").getValueAsString(); - getTargetStreamer()->emitImportModule(WasmSym, Name); + getTargetStreamer()->emitImportModule(Sym, Name); } } } @@ -137,10 +146,17 @@ void WebAssemblyAsmPrinter::EmitJumpTableInfo() { } void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { - getTargetStreamer()->emitParam(CurrentFnSym, MFI->getParams()); - - SmallVector<MVT, 4> ResultVTs; const Function &F = MF->getFunction(); + SmallVector<MVT, 1> ResultVTs; + SmallVector<MVT, 4> ParamVTs; + ComputeSignatureVTs(F.getFunctionType(), F, TM, ParamVTs, ResultVTs); + auto Signature = SignatureFromMVTs(ResultVTs, ParamVTs); + auto *WasmSym = cast<MCSymbolWasm>(CurrentFnSym); + WasmSym->setSignature(Signature.get()); + addSignature(std::move(Signature)); + + // FIXME: clean up how params and results are emitted (use signatures) + getTargetStreamer()->emitParam(CurrentFnSym, ParamVTs); // Emit the function index. if (MDNode *Idx = F.getMetadata("wasm.index")) { @@ -150,15 +166,7 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { cast<ConstantAsMetadata>(Idx->getOperand(0))->getValue())); } - ComputeLegalValueVTs(F, TM, F.getReturnType(), ResultVTs); - - // If the return type needs to be legalized it will get converted into - // passing a pointer. - if (ResultVTs.size() == 1) - getTargetStreamer()->emitResult(CurrentFnSym, ResultVTs); - else - getTargetStreamer()->emitResult(CurrentFnSym, ArrayRef<MVT>()); - + getTargetStreamer()->emitResult(CurrentFnSym, ResultVTs); getTargetStreamer()->emitLocal(MFI->getLocals()); AsmPrinter::EmitFunctionBodyStart(); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h index 97b1ae578b5..f6cb5610bad 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h @@ -25,6 +25,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter { const WebAssemblySubtarget *Subtarget; const MachineRegisterInfo *MRI; WebAssemblyFunctionInfo *MFI; + // TODO: Do the uniquing of Signatures here instead of ObjectFileWriter? + std::vector<std::unique_ptr<wasm::WasmSignature>> Signatures; public: explicit WebAssemblyAsmPrinter(TargetMachine &TM, @@ -37,6 +39,9 @@ public: } const WebAssemblySubtarget &getSubtarget() const { return *Subtarget; } + void addSignature(std::unique_ptr<wasm::WasmSignature> &&Sig) { + Signatures.push_back(std::move(Sig)); + } //===------------------------------------------------------------------===// // MachineFunctionPass Implementation. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 55c963b7b40..a8992d89ca3 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -769,12 +769,18 @@ SDValue WebAssemblyTargetLowering::LowerFormalArguments( MFI->addParam(PtrVT); } - // Record the number and types of results. + // Record the number and types of arguments and results. SmallVector<MVT, 4> Params; SmallVector<MVT, 4> Results; - ComputeSignatureVTs(MF.getFunction(), DAG.getTarget(), Params, Results); + ComputeSignatureVTs(MF.getFunction().getFunctionType(), MF.getFunction(), + DAG.getTarget(), Params, Results); for (MVT VT : Results) MFI->addResult(VT); + // TODO: Use signatures in WebAssemblyMachineFunctionInfo too and unify + // the param logic here with ComputeSignatureVTs + assert(MFI->getParams().size() == Params.size() && + std::equal(MFI->getParams().begin(), MFI->getParams().end(), + Params.begin())); return Chain; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index a52bedd9f29..e9a0cf51905 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -51,34 +51,13 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const { const TargetMachine &TM = MF.getTarget(); const Function &CurrentFunc = MF.getFunction(); - SmallVector<wasm::ValType, 4> Returns; - SmallVector<wasm::ValType, 4> Params; + SmallVector<MVT, 1> ResultMVTs; + SmallVector<MVT, 4> ParamMVTs; + ComputeSignatureVTs(FuncTy, CurrentFunc, TM, ParamMVTs, ResultMVTs); - wasm::ValType iPTR = MF.getSubtarget<WebAssemblySubtarget>().hasAddr64() - ? wasm::ValType::I64 - : wasm::ValType::I32; - - SmallVector<MVT, 4> ResultMVTs; - ComputeLegalValueVTs(CurrentFunc, TM, FuncTy->getReturnType(), ResultMVTs); - // WebAssembly can't currently handle returning tuples. - if (ResultMVTs.size() <= 1) - for (MVT ResultMVT : ResultMVTs) - Returns.push_back(WebAssembly::toValType(ResultMVT)); - else - Params.push_back(iPTR); - - for (Type *Ty : FuncTy->params()) { - SmallVector<MVT, 4> ParamMVTs; - ComputeLegalValueVTs(CurrentFunc, TM, Ty, ParamMVTs); - for (MVT ParamMVT : ParamMVTs) - Params.push_back(WebAssembly::toValType(ParamMVT)); - } - - if (FuncTy->isVarArg()) - Params.push_back(iPTR); - - WasmSym->setReturns(std::move(Returns)); - WasmSym->setParams(std::move(Params)); + auto Signature = SignatureFromMVTs(ResultMVTs, ParamMVTs); + WasmSym->setSignature(Signature.get()); + Printer.addSignature(std::move(Signature)); WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); } @@ -108,9 +87,10 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol( SmallVector<wasm::ValType, 4> Returns; SmallVector<wasm::ValType, 4> Params; GetLibcallSignature(Subtarget, Name, Returns, Params); - - WasmSym->setReturns(std::move(Returns)); - WasmSym->setParams(std::move(Params)); + auto Signature = + make_unique<wasm::WasmSignature>(std::move(Returns), std::move(Params)); + WasmSym->setSignature(Signature.get()); + Printer.addSignature(std::move(Signature)); WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); return WasmSym; @@ -203,8 +183,10 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI, Params.pop_back(); MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Sym); - WasmSym->setReturns(std::move(Returns)); - WasmSym->setParams(std::move(Params)); + auto Signature = make_unique<wasm::WasmSignature>(std::move(Returns), + std::move(Params)); + WasmSym->setSignature(Signature.get()); + Printer.addSignature(std::move(Signature)); WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); const MCExpr *Expr = MCSymbolRefExpr::create( diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp index e511e574050..073706e567e 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp @@ -43,20 +43,34 @@ void llvm::ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, } } -void llvm::ComputeSignatureVTs(const Function &F, const TargetMachine &TM, +void llvm::ComputeSignatureVTs(const FunctionType *Ty, const Function &F, + const TargetMachine &TM, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) { - ComputeLegalValueVTs(F, TM, F.getReturnType(), Results); + ComputeLegalValueVTs(F, TM, Ty->getReturnType(), Results); + MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()); if (Results.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. Results.clear(); - Params.push_back( - MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits())); + Params.push_back(PtrVT); } - for (auto &Arg : F.args()) - ComputeLegalValueVTs(F, TM, Arg.getType(), Params); + for (auto *Param : Ty->params()) + ComputeLegalValueVTs(F, TM, Param, Params); + if (Ty->isVarArg()) + Params.push_back(PtrVT); +} + +std::unique_ptr<wasm::WasmSignature> +llvm::SignatureFromMVTs(const SmallVectorImpl<MVT> &Results, + const SmallVectorImpl<MVT> &Params) { + auto Sig = make_unique<wasm::WasmSignature>(); + for (MVT Ty : Results) + Sig->Returns.push_back(WebAssembly::toValType(Ty)); + for (MVT Ty : Params) + Sig->Params.push_back(WebAssembly::toValType(Ty)); + return Sig; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index 5a2602f87ee..cde44d24599 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -17,7 +17,9 @@ #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" +#include "llvm/BinaryFormat/Wasm.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/MC/MCSymbolWasm.h" namespace llvm { @@ -121,10 +123,16 @@ public: void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, SmallVectorImpl<MVT> &ValueVTs); -void ComputeSignatureVTs(const Function &F, const TargetMachine &TM, - SmallVectorImpl<MVT> &Params, +// Compute the signature for a given FunctionType (Ty). Note that it's not the +// signature for F (F is just used to get varous context) +void ComputeSignatureVTs(const FunctionType *Ty, const Function &F, + const TargetMachine &TM, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results); +std::unique_ptr<wasm::WasmSignature> +SignatureFromMVTs(const SmallVectorImpl<MVT> &Results, + const SmallVectorImpl<MVT> &Params); + } // end namespace llvm #endif |