
WebAssemblyUtils depends on CodeGen which depends on all middle end optimization libraries. This component is used by WebAssembly's AsmParser, Disassembler, and MCTargetDesc libraries. Because of this, any MC layer tool built with WebAssembly support includes a larger portion of LLVM than it should. To fix this I've created an MC only version of WebAssemblyTypeUtilities.cpp in MCTargetDesc to be used by the MC components. This shrinks llvm-objdump and llvm-mc on my local release+asserts build by 5-6 MB. Reviewed By: MaskRay, aheejin Differential Revision: https://reviews.llvm.org/D144354
140 lines
4.7 KiB
C++
140 lines
4.7 KiB
C++
//==-- WebAssemblyTargetStreamer.cpp - WebAssembly Target Streamer Methods --=//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This file defines WebAssembly-specific target streamer classes.
|
|
/// These are for implementing support for target-specific assembly directives.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "MCTargetDesc/WebAssemblyTargetStreamer.h"
|
|
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
|
|
#include "MCTargetDesc/WebAssemblyMCTypeUtilities.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCSectionWasm.h"
|
|
#include "llvm/MC/MCSubtargetInfo.h"
|
|
#include "llvm/MC/MCSymbolWasm.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/FormattedStream.h"
|
|
using namespace llvm;
|
|
|
|
WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)
|
|
: MCTargetStreamer(S) {}
|
|
|
|
void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {
|
|
Streamer.emitIntValue(uint8_t(Type), 1);
|
|
}
|
|
|
|
WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
|
|
MCStreamer &S, formatted_raw_ostream &OS)
|
|
: WebAssemblyTargetStreamer(S), OS(OS) {}
|
|
|
|
WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
|
|
: WebAssemblyTargetStreamer(S) {}
|
|
|
|
static void printTypes(formatted_raw_ostream &OS,
|
|
ArrayRef<wasm::ValType> Types) {
|
|
bool First = true;
|
|
for (auto Type : Types) {
|
|
if (First)
|
|
First = false;
|
|
else
|
|
OS << ", ";
|
|
OS << WebAssembly::typeToString(Type);
|
|
}
|
|
OS << '\n';
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
|
|
if (!Types.empty()) {
|
|
OS << "\t.local \t";
|
|
printTypes(OS, Types);
|
|
}
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {
|
|
assert(Sym->isFunction());
|
|
OS << "\t.functype\t" << Sym->getName() << " ";
|
|
OS << WebAssembly::signatureToString(Sym->getSignature());
|
|
OS << "\n";
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
|
|
assert(Sym->isGlobal());
|
|
OS << "\t.globaltype\t" << Sym->getName() << ", "
|
|
<< WebAssembly::typeToString(
|
|
static_cast<wasm::ValType>(Sym->getGlobalType().Type));
|
|
if (!Sym->getGlobalType().Mutable)
|
|
OS << ", immutable";
|
|
OS << '\n';
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitTableType(const MCSymbolWasm *Sym) {
|
|
assert(Sym->isTable());
|
|
const wasm::WasmTableType &Type = Sym->getTableType();
|
|
OS << "\t.tabletype\t" << Sym->getName() << ", "
|
|
<< WebAssembly::typeToString(static_cast<wasm::ValType>(Type.ElemType));
|
|
bool HasMaximum = Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX;
|
|
if (Type.Limits.Minimum != 0 || HasMaximum) {
|
|
OS << ", " << Type.Limits.Minimum;
|
|
if (HasMaximum)
|
|
OS << ", " << Type.Limits.Maximum;
|
|
}
|
|
OS << '\n';
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitTagType(const MCSymbolWasm *Sym) {
|
|
assert(Sym->isTag());
|
|
OS << "\t.tagtype\t" << Sym->getName() << " ";
|
|
OS << WebAssembly::typeListToString(Sym->getSignature()->Params);
|
|
OS << "\n";
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
|
|
StringRef ImportModule) {
|
|
OS << "\t.import_module\t" << Sym->getName() << ", "
|
|
<< ImportModule << '\n';
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym,
|
|
StringRef ImportName) {
|
|
OS << "\t.import_name\t" << Sym->getName() << ", "
|
|
<< ImportName << '\n';
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitExportName(const MCSymbolWasm *Sym,
|
|
StringRef ExportName) {
|
|
OS << "\t.export_name\t" << Sym->getName() << ", "
|
|
<< ExportName << '\n';
|
|
}
|
|
|
|
void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
|
|
OS << "\t.indidx \t" << *Value << '\n';
|
|
}
|
|
|
|
void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {
|
|
SmallVector<std::pair<wasm::ValType, uint32_t>, 4> Grouped;
|
|
for (auto Type : Types) {
|
|
if (Grouped.empty() || Grouped.back().first != Type)
|
|
Grouped.push_back(std::make_pair(Type, 1));
|
|
else
|
|
++Grouped.back().second;
|
|
}
|
|
|
|
Streamer.emitULEB128IntValue(Grouped.size());
|
|
for (auto Pair : Grouped) {
|
|
Streamer.emitULEB128IntValue(Pair.second);
|
|
emitValueType(Pair.first);
|
|
}
|
|
}
|
|
|
|
void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
|
|
llvm_unreachable(".indidx encoding not yet implemented");
|
|
}
|