diff options
Diffstat (limited to 'contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp | 92 |
1 files changed, 40 insertions, 52 deletions
diff --git a/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 54e9f7f..5b4b82e 100644 --- a/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/contrib/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -14,10 +14,10 @@ /// //===----------------------------------------------------------------------===// -#include "WebAssembly.h" #include "InstPrinter/WebAssemblyInstPrinter.h" #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "MCTargetDesc/WebAssemblyTargetStreamer.h" +#include "WebAssembly.h" #include "WebAssemblyMCInstLower.h" #include "WebAssemblyMachineFunctionInfo.h" #include "WebAssemblyRegisterInfo.h" @@ -42,14 +42,14 @@ namespace { class WebAssemblyAsmPrinter final : public AsmPrinter { const MachineRegisterInfo *MRI; - const WebAssemblyFunctionInfo *MFI; + WebAssemblyFunctionInfo *MFI; public: WebAssemblyAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) : AsmPrinter(TM, std::move(Streamer)), MRI(nullptr), MFI(nullptr) {} private: - const char *getPassName() const override { + StringRef getPassName() const override { return "WebAssembly Assembly Printer"; } @@ -82,7 +82,6 @@ private: raw_ostream &OS) override; MVT getRegType(unsigned RegNo) const; - const char *toString(MVT VT) const; std::string regToString(const MachineOperand &MO); WebAssemblyTargetStreamer *getTargetStreamer(); }; @@ -95,7 +94,8 @@ private: MVT WebAssemblyAsmPrinter::getRegType(unsigned RegNo) const { const TargetRegisterClass *TRC = MRI->getRegClass(RegNo); - for (MVT T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64}) + for (MVT T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64, MVT::v16i8, MVT::v8i16, + MVT::v4i32, MVT::v4f32}) if (TRC->hasType(T)) return T; DEBUG(errs() << "Unknown type for register number: " << RegNo); @@ -103,10 +103,6 @@ MVT WebAssemblyAsmPrinter::getRegType(unsigned RegNo) const { return MVT::Other; } -const char *WebAssemblyAsmPrinter::toString(MVT VT) const { - return WebAssembly::TypeToString(VT); -} - std::string WebAssemblyAsmPrinter::regToString(const MachineOperand &MO) { unsigned RegNo = MO.getReg(); assert(TargetRegisterInfo::isVirtualRegister(RegNo) && @@ -125,45 +121,21 @@ WebAssemblyTargetStreamer *WebAssemblyAsmPrinter::getTargetStreamer() { //===----------------------------------------------------------------------===// // WebAssemblyAsmPrinter Implementation. //===----------------------------------------------------------------------===// -static void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, - Type *Ty, SmallVectorImpl<MVT> &ValueVTs) { - const DataLayout &DL(F.getParent()->getDataLayout()); - const WebAssemblyTargetLowering &TLI = - *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering(); - SmallVector<EVT, 4> VTs; - ComputeValueVTs(TLI, DL, Ty, VTs); - - for (EVT VT : VTs) { - unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT); - MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT); - for (unsigned i = 0; i != NumRegs; ++i) - ValueVTs.push_back(RegisterVT); - } -} 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); + SmallVector<MVT, 4> Results; + SmallVector<MVT, 4> Params; + ComputeSignatureVTs(F, TM, Params, Results); + getTargetStreamer()->emitIndirectFunctionType(F.getName(), Params, + Results); + } + } + for (const auto &G : M.globals()) { + if (!G.hasInitializer() && G.hasExternalLinkage()) { + getTargetStreamer()->emitGlobalImport(G.getGlobalIdentifier()); } } } @@ -183,6 +155,15 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { SmallVector<MVT, 4> ResultVTs; const Function &F(*MF->getFunction()); + + // Emit the function index. + if (MDNode *Idx = F.getMetadata("wasm.index")) { + assert(Idx->getNumOperands() == 1); + + getTargetStreamer()->emitIndIdx(AsmPrinter::lowerConstant( + 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 @@ -190,8 +171,8 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { if (ResultVTs.size() == 1) getTargetStreamer()->emitResult(ResultVTs); - bool AnyWARegs = false; - SmallVector<MVT, 16> LocalTypes; + // FIXME: When ExplicitLocals is enabled by default, we won't need + // to define the locals here (and MFI can go back to being pointer-to-const). for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) { unsigned VReg = TargetRegisterInfo::index2VirtReg(Idx); unsigned WAReg = MFI->getWAReg(VReg); @@ -204,11 +185,10 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { // Don't declare stackified registers. if (int(WAReg) < 0) continue; - LocalTypes.push_back(getRegType(VReg)); - AnyWARegs = true; + MFI->addLocal(getRegType(VReg)); } - if (AnyWARegs) - getTargetStreamer()->emitLocal(LocalTypes); + + getTargetStreamer()->emitLocal(MFI->getLocals()); AsmPrinter::EmitFunctionBodyStart(); } @@ -225,13 +205,21 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) { case WebAssembly::ARGUMENT_I64: case WebAssembly::ARGUMENT_F32: case WebAssembly::ARGUMENT_F64: + case WebAssembly::ARGUMENT_v16i8: + case WebAssembly::ARGUMENT_v8i16: + case WebAssembly::ARGUMENT_v4i32: + case WebAssembly::ARGUMENT_v4f32: // These represent values which are live into the function entry, so there's // no instruction to emit. break; case WebAssembly::FALLTHROUGH_RETURN_I32: case WebAssembly::FALLTHROUGH_RETURN_I64: case WebAssembly::FALLTHROUGH_RETURN_F32: - case WebAssembly::FALLTHROUGH_RETURN_F64: { + case WebAssembly::FALLTHROUGH_RETURN_F64: + case WebAssembly::FALLTHROUGH_RETURN_v16i8: + case WebAssembly::FALLTHROUGH_RETURN_v8i16: + case WebAssembly::FALLTHROUGH_RETURN_v4i32: + case WebAssembly::FALLTHROUGH_RETURN_v4f32: { // These instructions represent the implicit return at the end of a // function body. The operand is always a pop. assert(MFI->isVRegStackified(MI->getOperand(0).getReg())); @@ -329,6 +317,6 @@ bool WebAssemblyAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, // Force static initialization. extern "C" void LLVMInitializeWebAssemblyAsmPrinter() { - RegisterAsmPrinter<WebAssemblyAsmPrinter> X(TheWebAssemblyTarget32); - RegisterAsmPrinter<WebAssemblyAsmPrinter> Y(TheWebAssemblyTarget64); + RegisterAsmPrinter<WebAssemblyAsmPrinter> X(getTheWebAssemblyTarget32()); + RegisterAsmPrinter<WebAssemblyAsmPrinter> Y(getTheWebAssemblyTarget64()); } |