[WebAssembly] clang-format (NFC)

Summary: This patch runs clang-format on all wasm-only files.

Reviewers: aardappel, dschuff, sunfish, tlively

Subscribers: MatzeB, sbc100, jgravelle-google, llvm-commits

Differential Revision: https://reviews.llvm.org/D51447

llvm-svn: 341439
This commit is contained in:
Heejin Ahn 2018-09-05 01:27:38 +00:00
parent 5d05be84b7
commit f208f6311b
51 changed files with 818 additions and 722 deletions

View File

@ -104,8 +104,8 @@ struct WasmFunction {
uint32_t Size;
uint32_t CodeOffset; // start of Locals and Body
StringRef SymbolName; // from the "linking" section
StringRef DebugName; // from the "name" section
uint32_t Comdat; // from the "comdat info" section
StringRef DebugName; // from the "name" section
uint32_t Comdat; // from the "comdat info" section
};
struct WasmDataSegment {
@ -231,21 +231,21 @@ enum class ValType {
// Kind codes used in the custom "name" section
enum : unsigned {
WASM_NAMES_FUNCTION = 0x1,
WASM_NAMES_LOCAL = 0x2,
WASM_NAMES_LOCAL = 0x2,
};
// Kind codes used in the custom "linking" section
enum : unsigned {
WASM_SEGMENT_INFO = 0x5,
WASM_INIT_FUNCS = 0x6,
WASM_COMDAT_INFO = 0x7,
WASM_SYMBOL_TABLE = 0x8,
WASM_SEGMENT_INFO = 0x5,
WASM_INIT_FUNCS = 0x6,
WASM_COMDAT_INFO = 0x7,
WASM_SYMBOL_TABLE = 0x8,
};
// Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO
enum : unsigned {
WASM_COMDAT_DATA = 0x0,
WASM_COMDAT_FUNCTION = 0x1,
WASM_COMDAT_DATA = 0x0,
WASM_COMDAT_FUNCTION = 0x1,
};
// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
@ -256,15 +256,15 @@ enum WasmSymbolType : unsigned {
WASM_SYMBOL_TYPE_SECTION = 0x3,
};
const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
#define WASM_RELOC(name, value) name = value,

View File

@ -14,8 +14,8 @@
#ifndef LLVM_CODEGEN_WASMEHFUNCINFO_H
#define LLVM_CODEGEN_WASMEHFUNCINFO_H
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/IR/BasicBlock.h"

View File

@ -19,6 +19,6 @@ class MCAsmInfoWasm : public MCAsmInfo {
protected:
MCAsmInfoWasm();
};
}
} // namespace llvm
#endif

View File

@ -35,8 +35,7 @@ public:
// Use a module name of "env" for now, for compatibility with existing tools.
// This is temporary, and may change, as the ABI is not yet stable.
MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
: MCSymbol(SymbolKindWasm, Name, isTemporary),
ModuleName("env") {}
: MCSymbol(SymbolKindWasm, Name, isTemporary), ModuleName("env") {}
static bool classof(const MCSymbol *S) { return S->isWasm(); }
const MCExpr *getSize() const { return SymbolSize; }
@ -92,6 +91,6 @@ public:
}
};
} // end namespace llvm
} // end namespace llvm
#endif // LLVM_MC_MCSYMBOLWASM_H

View File

@ -51,6 +51,6 @@ std::unique_ptr<MCObjectWriter>
createWasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
raw_pwrite_stream &OS);
} // End llvm namespace
} // namespace llvm
#endif

View File

@ -18,8 +18,8 @@
#define LLVM_OBJECT_WASM_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Object/Binary.h"
@ -98,9 +98,9 @@ public:
struct WasmSection {
WasmSection() = default;
uint32_t Type = 0; // Section type (See below)
uint32_t Offset = 0; // Offset with in the file
StringRef Name; // Section name (User-defined sections only)
uint32_t Type = 0; // Section type (See below)
uint32_t Offset = 0; // Offset with in the file
StringRef Name; // Section name (User-defined sections only)
ArrayRef<uint8_t> Content; // Section content
std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
};
@ -119,7 +119,7 @@ public:
const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
const WasmSection &getWasmSection(const SectionRef &Section) const;
const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const;
const wasm::WasmRelocation &getWasmRelocation(const RelocationRef &Ref) const;
static bool classof(const Binary *v) { return v->isWasm(); }
@ -131,7 +131,7 @@ public:
ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
ArrayRef<wasm::WasmExport> exports() const { return Exports; }
ArrayRef<WasmSymbol> syms() const { return Symbols; }
const wasm::WasmLinkingData& linkingData() const { return LinkingData; }
const wasm::WasmLinkingData &linkingData() const { return LinkingData; }
uint32_t getNumberOfSymbols() const { return Symbols.size(); }
ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
@ -151,7 +151,7 @@ public:
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
uint64_t getWasmSymbolValue(const WasmSymbol& Sym) const;
uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const;
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
@ -264,8 +264,7 @@ private:
} // end namespace object
inline raw_ostream &operator<<(raw_ostream &OS,
const object::WasmSymbol &Sym) {
inline raw_ostream &operator<<(raw_ostream &OS, const object::WasmSymbol &Sym) {
Sym.print(OS);
return OS;
}

View File

@ -25,7 +25,9 @@ std::string llvm::wasm::toString(wasm::WasmSymbolType type) {
std::string llvm::wasm::relocTypetoString(uint32_t type) {
switch (type) {
#define WASM_RELOC(NAME, VALUE) case VALUE: return #NAME;
#define WASM_RELOC(NAME, VALUE) \
case VALUE: \
return #NAME;
#include "llvm/BinaryFormat/WasmRelocs.def"
#undef WASM_RELOC
default:

View File

@ -15,7 +15,7 @@
#include "llvm/MC/MCAsmInfoWasm.h"
using namespace llvm;
void MCAsmInfoWasm::anchor() { }
void MCAsmInfoWasm::anchor() {}
MCAsmInfoWasm::MCAsmInfoWasm() {
HasIdentDirective = true;

View File

@ -137,11 +137,11 @@ struct WasmComdatEntry {
// Information about a single relocation.
struct WasmRelocationEntry {
uint64_t Offset; // Where is the relocation.
const MCSymbolWasm *Symbol; // The symbol to relocate with.
int64_t Addend; // A value to add to the symbol.
unsigned Type; // The type of the relocation.
const MCSectionWasm *FixupSection;// The section the relocation is targeting.
uint64_t Offset; // Where is the relocation.
const MCSymbolWasm *Symbol; // The symbol to relocate with.
int64_t Addend; // A value to add to the symbol.
unsigned Type; // The type of the relocation.
const MCSectionWasm *FixupSection; // The section the relocation is targeting.
WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol,
int64_t Addend, unsigned Type,
@ -163,8 +163,8 @@ struct WasmRelocationEntry {
}
void print(raw_ostream &Out) const {
Out << wasm::relocTypetoString(Type)
<< " Off=" << Offset << ", Sym=" << *Symbol << ", Addend=" << Addend
Out << wasm::relocTypetoString(Type) << " Off=" << Offset
<< ", Sym=" << *Symbol << ", Addend=" << Addend
<< ", FixupSection=" << FixupSection->getSectionName();
}
@ -291,9 +291,7 @@ private:
W.OS << Str;
}
void writeValueType(wasm::ValType Ty) {
W.OS << static_cast<char>(Ty);
}
void writeValueType(wasm::ValType Ty) { W.OS << static_cast<char>(Ty); }
void writeTypeSection(ArrayRef<WasmFunctionType> FunctionTypes);
void writeImportSection(ArrayRef<wasm::WasmImport> Imports, uint32_t DataSize,
@ -306,7 +304,7 @@ private:
ArrayRef<WasmFunction> Functions);
void writeDataSection();
void writeRelocSection(uint32_t SectionIndex, StringRef Name,
std::vector<WasmRelocationEntry>& Relocations);
std::vector<WasmRelocationEntry> &Relocations);
void writeLinkingMetaDataSection(
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
@ -529,8 +527,8 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
// Write X as an (unsigned) LEB value at offset Offset in Stream, padded
// to allow patching.
static void
WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
static void WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X,
uint64_t Offset) {
uint8_t Buffer[5];
unsigned SizeLen = encodeULEB128(X, Buffer, 5);
assert(SizeLen == 5);
@ -539,8 +537,8 @@ WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
// Write X as an signed LEB value at offset Offset in Stream, padded
// to allow patching.
static void
WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X, uint64_t Offset) {
static void WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X,
uint64_t Offset) {
uint8_t Buffer[5];
unsigned SizeLen = encodeSLEB128(X, Buffer, 5);
assert(SizeLen == 5);
@ -554,7 +552,7 @@ static void WriteI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
}
static const MCSymbolWasm* ResolveSymbol(const MCSymbolWasm& Symbol) {
static const MCSymbolWasm *ResolveSymbol(const MCSymbolWasm &Symbol) {
if (Symbol.isVariable()) {
const MCExpr *Expr = Symbol.getVariableValue();
auto *Inner = cast<MCSymbolRefExpr>(Expr);
@ -626,10 +624,9 @@ static void addData(SmallVectorImpl<char> &DataBytes,
report_fatal_error("only byte values supported for alignment");
// If nops are requested, use zeros, as this is the data section.
uint8_t Value = Align->hasEmitNops() ? 0 : Align->getValue();
uint64_t Size = std::min<uint64_t>(alignTo(DataBytes.size(),
Align->getAlignment()),
DataBytes.size() +
Align->getMaxBytesToEmit());
uint64_t Size =
std::min<uint64_t>(alignTo(DataBytes.size(), Align->getAlignment()),
DataBytes.size() + Align->getMaxBytesToEmit());
DataBytes.resize(Size, Value);
} else if (auto *Fill = dyn_cast<MCFillFragment>(&Frag)) {
int64_t NumValues;
@ -745,12 +742,12 @@ void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports,
W.OS << char(Import.Global.Mutable ? 1 : 0);
break;
case wasm::WASM_EXTERNAL_MEMORY:
encodeULEB128(0, W.OS); // flags
encodeULEB128(0, W.OS); // flags
encodeULEB128(NumPages, W.OS); // initial
break;
case wasm::WASM_EXTERNAL_TABLE:
W.OS << char(Import.Table.ElemType);
encodeULEB128(0, W.OS); // flags
encodeULEB128(0, W.OS); // flags
encodeULEB128(NumElements, W.OS); // initial
break;
default:
@ -892,7 +889,7 @@ void WasmObjectWriter::writeDataSection() {
void WasmObjectWriter::writeRelocSection(
uint32_t SectionIndex, StringRef Name,
std::vector<WasmRelocationEntry>& Relocs) {
std::vector<WasmRelocationEntry> &Relocs) {
// See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
// for descriptions of the reloc sections.
@ -916,9 +913,9 @@ void WasmObjectWriter::writeRelocSection(
encodeULEB128(SectionIndex, W.OS);
encodeULEB128(Relocs.size(), W.OS);
for (const WasmRelocationEntry& RelEntry : Relocs) {
uint64_t Offset = RelEntry.Offset +
RelEntry.FixupSection->getSectionOffset();
for (const WasmRelocationEntry &RelEntry : Relocs) {
uint64_t Offset =
RelEntry.Offset + RelEntry.FixupSection->getSectionOffset();
uint32_t Index = getRelocationIndexValue(RelEntry);
W.OS << char(RelEntry.Type);
@ -996,7 +993,7 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
startSection(SubSection, wasm::WASM_INIT_FUNCS);
encodeULEB128(InitFuncs.size(), W.OS);
for (auto &StartFunc : InitFuncs) {
encodeULEB128(StartFunc.first, W.OS); // priority
encodeULEB128(StartFunc.first, W.OS); // priority
encodeULEB128(StartFunc.second, W.OS); // function index
}
endSection(SubSection);
@ -1041,17 +1038,17 @@ void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
}
}
uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm& Symbol) {
uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm &Symbol) {
assert(Symbol.isFunction());
assert(TypeIndices.count(&Symbol));
return TypeIndices[&Symbol];
}
uint32_t WasmObjectWriter::registerFunctionType(const MCSymbolWasm& Symbol) {
uint32_t WasmObjectWriter::registerFunctionType(const MCSymbolWasm &Symbol) {
assert(Symbol.isFunction());
WasmFunctionType F;
const MCSymbolWasm* ResolvedSym = ResolveSymbol(Symbol);
const MCSymbolWasm *ResolvedSym = ResolveSymbol(Symbol);
F.Returns = ResolvedSym->getReturns();
F.Params = ResolvedSym->getParams();
@ -1207,7 +1204,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
if (Name.startswith(".custom_section."))
Name = Name.substr(strlen(".custom_section."));
MCSymbol* Begin = Sec.getBeginSymbol();
MCSymbol *Begin = Sec.getBeginSymbol();
if (Begin) {
WasmIndices[cast<MCSymbolWasm>(Begin)] = CustomSections.size();
if (SectionName != Begin->getName())
@ -1436,7 +1433,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
unsigned PrefixLength = strlen(".init_array");
if (WS.getSectionName().size() > PrefixLength) {
if (WS.getSectionName()[PrefixLength] != '.')
report_fatal_error(".init_array section priority should start with '.'");
report_fatal_error(
".init_array section priority should start with '.'");
if (WS.getSectionName()
.substr(PrefixLength + 1)
.getAsInteger(10, Priority))
@ -1444,14 +1442,16 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
}
const auto &DataFrag = cast<MCDataFragment>(Frag);
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
for (const uint8_t *p = (const uint8_t *)Contents.data(),
*end = (const uint8_t *)Contents.data() + Contents.size();
for (const uint8_t *
p = (const uint8_t *)Contents.data(),
*end = (const uint8_t *)Contents.data() + Contents.size();
p != end; ++p) {
if (*p != 0)
report_fatal_error("non-symbolic data in .init_array section");
}
for (const MCFixup &Fixup : DataFrag.getFixups()) {
assert(Fixup.getKind() == MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
assert(Fixup.getKind() ==
MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
const MCExpr *Expr = Fixup.getValue();
auto *Sym = dyn_cast<MCSymbolRefExpr>(Expr);
if (!Sym)

View File

@ -37,8 +37,8 @@ using namespace object;
void WasmSymbol::print(raw_ostream &Out) const {
Out << "Name=" << Info.Name
<< ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind))
<< ", Flags=" << Info.Flags;
<< ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind))
<< ", Flags=" << Info.Flags;
if (!isTypeData()) {
Out << ", ElemIndex=" << Info.ElementIndex;
} else if (isDefined()) {
@ -62,9 +62,9 @@ ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) {
return std::move(ObjectFile);
}
#define VARINT7_MAX ((1<<7)-1)
#define VARINT7_MIN (-(1<<7))
#define VARUINT7_MAX (1<<7)
#define VARINT7_MAX ((1 << 7) - 1)
#define VARINT7_MIN (-(1 << 7))
#define VARUINT7_MAX (1 << 7)
#define VARUINT1_MAX (1)
static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx) {
@ -101,7 +101,7 @@ static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx) {
static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx) {
unsigned Count;
const char* Error = nullptr;
const char *Error = nullptr;
uint64_t Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
if (Error)
report_fatal_error(Error);
@ -121,7 +121,7 @@ static StringRef readString(WasmObjectFile::ReadContext &Ctx) {
static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx) {
unsigned Count;
const char* Error = nullptr;
const char *Error = nullptr;
uint64_t Result = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
if (Error)
report_fatal_error(Error);
@ -241,8 +241,8 @@ WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
ErrorAsOutParameter ErrAsOutParam(&Err);
Header.Magic = getData().substr(0, 4);
if (Header.Magic != StringRef("\0asm", 4)) {
Err = make_error<StringError>("Bad magic number",
object_error::parse_failed);
Err =
make_error<StringError>("Bad magic number", object_error::parse_failed);
return;
}
@ -347,8 +347,8 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
break;
}
if (Ctx.Ptr != SubSectionEnd)
return make_error<GenericBinaryError>("Name sub-section ended prematurely",
object_error::parse_failed);
return make_error<GenericBinaryError>(
"Name sub-section ended prematurely", object_error::parse_failed);
}
if (Ctx.Ptr != Ctx.End)
@ -361,7 +361,8 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
HasLinkingSection = true;
if (Functions.size() != FunctionTypes.size()) {
return make_error<GenericBinaryError>(
"Linking data must come after code section", object_error::parse_failed);
"Linking data must come after code section",
object_error::parse_failed);
}
LinkingData.Version = readVaruint32(Ctx);
@ -484,9 +485,8 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
return make_error<GenericBinaryError>("invalid global symbol index",
object_error::parse_failed);
if (!IsDefined &&
(Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
wasm::WASM_SYMBOL_BINDING_WEAK)
if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
wasm::WASM_SYMBOL_BINDING_WEAK)
return make_error<GenericBinaryError>("undefined weak global symbol",
object_error::parse_failed);
if (IsDefined) {
@ -558,7 +558,8 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
StringRef Name = readString(Ctx);
if (Name.empty() || !ComdatSet.insert(Name).second)
return make_error<GenericBinaryError>("Bad/duplicate COMDAT name " + Twine(Name),
return make_error<GenericBinaryError>("Bad/duplicate COMDAT name " +
Twine(Name),
object_error::parse_failed);
LinkingData.Comdats.emplace_back(Name);
uint32_t Flags = readVaruint32(Ctx);
@ -576,8 +577,8 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
object_error::parse_failed);
case wasm::WASM_COMDAT_DATA:
if (Index >= DataSegments.size())
return make_error<GenericBinaryError>("COMDAT data index out of range",
object_error::parse_failed);
return make_error<GenericBinaryError>(
"COMDAT data index out of range", object_error::parse_failed);
if (DataSegments[Index].Data.Comdat != UINT32_MAX)
return make_error<GenericBinaryError>("Data segment in two COMDATs",
object_error::parse_failed);
@ -585,8 +586,8 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
break;
case wasm::WASM_COMDAT_FUNCTION:
if (!isDefinedFunctionIndex(Index))
return make_error<GenericBinaryError>("COMDAT function index out of range",
object_error::parse_failed);
return make_error<GenericBinaryError>(
"COMDAT function index out of range", object_error::parse_failed);
if (getDefinedFunction(Index).Comdat != UINT32_MAX)
return make_error<GenericBinaryError>("Function in two COMDATs",
object_error::parse_failed);
@ -603,7 +604,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
if (SectionIndex >= Sections.size())
return make_error<GenericBinaryError>("Invalid section index",
object_error::parse_failed);
WasmSection& Section = Sections[SectionIndex];
WasmSection &Section = Sections[SectionIndex];
uint32_t RelocCount = readVaruint32(Ctx);
uint32_t EndOffset = Section.Content.size();
uint32_t PreviousOffset = 0;
@ -756,8 +757,8 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
object_error::parse_failed);
break;
default:
return make_error<GenericBinaryError>(
"Unexpected import kind", object_error::parse_failed);
return make_error<GenericBinaryError>("Unexpected import kind",
object_error::parse_failed);
}
Imports.push_back(Im);
}
@ -854,8 +855,8 @@ Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
case wasm::WASM_EXTERNAL_TABLE:
break;
default:
return make_error<GenericBinaryError>(
"Unexpected export kind", object_error::parse_failed);
return make_error<GenericBinaryError>("Unexpected export kind",
object_error::parse_failed);
}
Exports.push_back(Ex);
}
@ -1066,7 +1067,7 @@ Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
return getSymbolValue(Symb);
}
uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
switch (Sym.Info.Kind) {
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
@ -1120,7 +1121,7 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
Expected<section_iterator>
WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
const WasmSymbol& Sym = getWasmSymbol(Symb);
const WasmSymbol &Sym = getWasmSymbol(Symb);
if (Sym.isUndefined())
return section_end();
@ -1234,9 +1235,7 @@ relocation_iterator WasmObjectFile::section_rel_end(DataRefImpl Ref) const {
return relocation_iterator(RelocationRef(RelocRef, this));
}
void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
Rel.d.b++;
}
void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const { Rel.d.b++; }
uint64_t WasmObjectFile::getRelocationOffset(DataRefImpl Ref) const {
const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
@ -1260,12 +1259,12 @@ uint64_t WasmObjectFile::getRelocationType(DataRefImpl Ref) const {
void WasmObjectFile::getRelocationTypeName(
DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
const wasm::WasmRelocation& Rel = getWasmRelocation(Ref);
const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
StringRef Res = "Unknown";
#define WASM_RELOC(name, value) \
case wasm::name: \
Res = #name; \
#define WASM_RELOC(name, value) \
case wasm::name: \
Res = #name; \
break;
switch (Rel.Type) {
@ -1299,9 +1298,7 @@ SubtargetFeatures WasmObjectFile::getFeatures() const {
return SubtargetFeatures();
}
bool WasmObjectFile::isRelocatableObject() const {
return HasLinkingSection;
}
bool WasmObjectFile::isRelocatableObject() const { return HasLinkingSection; }
const WasmSection &WasmObjectFile::getWasmSection(DataRefImpl Ref) const {
assert(Ref.d.a < Sections.size());
@ -1321,7 +1318,7 @@ WasmObjectFile::getWasmRelocation(const RelocationRef &Ref) const {
const wasm::WasmRelocation &
WasmObjectFile::getWasmRelocation(DataRefImpl Ref) const {
assert(Ref.d.a < Sections.size());
const WasmSection& Sec = Sections[Ref.d.a];
const WasmSection &Sec = Sections[Ref.d.a];
assert(Ref.d.b < Sec.Relocations.size());
return Sec.Relocations[Ref.d.b];
}

View File

@ -309,7 +309,7 @@ void MappingTraits<WasmYAML::Import>::mapping(IO &IO,
IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable);
} else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) {
IO.mapRequired("Table", Import.TableImport);
} else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY ) {
} else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY) {
IO.mapRequired("Memory", Import.Memory);
} else {
llvm_unreachable("unhandled import type");
@ -383,8 +383,8 @@ void MappingTraits<WasmYAML::ComdatEntry>::mapping(
IO.mapRequired("Index", ComdatEntry.Index);
}
void MappingTraits<WasmYAML::Comdat>::mapping(
IO &IO, WasmYAML::Comdat &Comdat) {
void MappingTraits<WasmYAML::Comdat>::mapping(IO &IO,
WasmYAML::Comdat &Comdat) {
IO.mapRequired("Name", Comdat.Name);
IO.mapRequired("Entries", Comdat.Entries);
}
@ -420,16 +420,16 @@ void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
}
void ScalarBitSetTraits<WasmYAML::SegmentFlags>::bitset(
IO &IO, WasmYAML::SegmentFlags &Value) {
}
IO &IO, WasmYAML::SegmentFlags &Value) {}
void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset(
IO &IO, WasmYAML::SymbolFlags &Value) {
#define BCaseMask(M, X) IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M)
//BCaseMask(BINDING_MASK, BINDING_GLOBAL);
#define BCaseMask(M, X) \
IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M)
// BCaseMask(BINDING_MASK, BINDING_GLOBAL);
BCaseMask(BINDING_MASK, BINDING_WEAK);
BCaseMask(BINDING_MASK, BINDING_LOCAL);
//BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
// BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
BCaseMask(UNDEFINED, UNDEFINED);
#undef BCaseMask

View File

@ -18,13 +18,13 @@
#include "MCTargetDesc/WebAssemblyTargetStreamer.h"
#include "WebAssembly.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/TargetRegistry.h"
@ -65,18 +65,18 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
};
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, TokOp T)
: Kind(K), StartLoc(Start), EndLoc(End), Tok(T) {}
: Kind(K), StartLoc(Start), EndLoc(End), Tok(T) {}
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, IntOp I)
: Kind(K), StartLoc(Start), EndLoc(End), Int(I) {}
: Kind(K), StartLoc(Start), EndLoc(End), Int(I) {}
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, FltOp F)
: Kind(K), StartLoc(Start), EndLoc(End), Flt(F) {}
: Kind(K), StartLoc(Start), EndLoc(End), Flt(F) {}
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, SymOp S)
: Kind(K), StartLoc(Start), EndLoc(End), Sym(S) {}
: Kind(K), StartLoc(Start), EndLoc(End), Sym(S) {}
bool isToken() const override { return Kind == Token; }
bool isImm() const override { return Kind == Integer ||
Kind == Float ||
Kind == Symbol; }
bool isImm() const override {
return Kind == Integer || Kind == Float || Kind == Symbol;
}
bool isMem() const override { return false; }
bool isReg() const override { return false; }
@ -145,8 +145,8 @@ public:
#include "WebAssemblyGenAsmMatcher.inc"
// TODO: This is required to be implemented, but appears unused.
bool ParseRegister(unsigned &/*RegNo*/, SMLoc &/*StartLoc*/,
SMLoc &/*EndLoc*/) override {
bool ParseRegister(unsigned & /*RegNo*/, SMLoc & /*StartLoc*/,
SMLoc & /*EndLoc*/) override {
llvm_unreachable("ParseRegister is not implemented.");
}
@ -156,7 +156,8 @@ public:
bool IsNext(AsmToken::TokenKind Kind) {
auto ok = Lexer.is(Kind);
if (ok) Parser.Lex();
if (ok)
Parser.Lex();
return ok;
}
@ -190,15 +191,15 @@ public:
void ParseSingleInteger(bool IsNegative, OperandVector &Operands) {
auto &Int = Lexer.getTok();
int64_t Val = Int.getIntVal();
if (IsNegative) Val = -Val;
if (IsNegative)
Val = -Val;
Operands.push_back(make_unique<WebAssemblyOperand>(
WebAssemblyOperand::Integer, Int.getLoc(),
Int.getEndLoc(), WebAssemblyOperand::IntOp{Val}));
WebAssemblyOperand::Integer, Int.getLoc(), Int.getEndLoc(),
WebAssemblyOperand::IntOp{Val}));
Parser.Lex();
}
bool ParseOperandStartingWithInteger(bool IsNegative,
OperandVector &Operands,
bool ParseOperandStartingWithInteger(bool IsNegative, OperandVector &Operands,
StringRef InstName) {
ParseSingleInteger(IsNegative, Operands);
// FIXME: there is probably a cleaner way to do this.
@ -217,25 +218,24 @@ public:
// We can't just call WebAssembly::GetDefaultP2Align since we don't have
// an opcode until after the assembly matcher.
Operands.push_back(make_unique<WebAssemblyOperand>(
WebAssemblyOperand::Integer, Offset.getLoc(),
Offset.getEndLoc(), WebAssemblyOperand::IntOp{0}));
WebAssemblyOperand::Integer, Offset.getLoc(), Offset.getEndLoc(),
WebAssemblyOperand::IntOp{0}));
}
}
return false;
}
bool ParseInstruction(ParseInstructionInfo &/*Info*/, StringRef Name,
bool ParseInstruction(ParseInstructionInfo & /*Info*/, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override {
Operands.push_back(
make_unique<WebAssemblyOperand>(WebAssemblyOperand::Token, NameLoc,
SMLoc::getFromPointer(
NameLoc.getPointer() + Name.size()),
WebAssemblyOperand::TokOp{
StringRef(NameLoc.getPointer(),
Name.size())}));
Operands.push_back(make_unique<WebAssemblyOperand>(
WebAssemblyOperand::Token, NameLoc,
SMLoc::getFromPointer(NameLoc.getPointer() + Name.size()),
WebAssemblyOperand::TokOp{
StringRef(NameLoc.getPointer(), Name.size())}));
auto NamePair = Name.split('.');
// If no '.', there is no type prefix.
if (NamePair.second.empty()) std::swap(NamePair.first, NamePair.second);
if (NamePair.second.empty())
std::swap(NamePair.first, NamePair.second);
while (Lexer.isNot(AsmToken::EndOfStatement)) {
auto &Tok = Lexer.getTok();
switch (Tok.getKind()) {
@ -246,8 +246,8 @@ public:
if (Parser.parsePrimaryExpr(Val, End))
return Error("Cannot parse symbol: ", Lexer.getTok());
Operands.push_back(make_unique<WebAssemblyOperand>(
WebAssemblyOperand::Symbol, Id.getLoc(),
Id.getEndLoc(), WebAssemblyOperand::SymOp{Val}));
WebAssemblyOperand::Symbol, Id.getLoc(), Id.getEndLoc(),
WebAssemblyOperand::SymOp{Val}));
break;
}
case AsmToken::Minus:
@ -266,8 +266,8 @@ public:
if (Tok.getString().getAsDouble(Val, false))
return Error("Cannot parse real: ", Tok);
Operands.push_back(make_unique<WebAssemblyOperand>(
WebAssemblyOperand::Float, Tok.getLoc(),
Tok.getEndLoc(), WebAssemblyOperand::FltOp{Val}));
WebAssemblyOperand::Float, Tok.getLoc(), Tok.getEndLoc(),
WebAssemblyOperand::FltOp{Val}));
Parser.Lex();
break;
}
@ -275,7 +275,8 @@ public:
return Error("Unexpected token in operand: ", Tok);
}
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (Expect(AsmToken::Comma, ",")) return true;
if (Expect(AsmToken::Comma, ","))
return true;
}
}
Parser.Lex();
@ -285,34 +286,30 @@ public:
// the wasm module is generated).
if (NamePair.second == "block" || NamePair.second == "loop") {
Operands.push_back(make_unique<WebAssemblyOperand>(
WebAssemblyOperand::Integer, NameLoc,
NameLoc, WebAssemblyOperand::IntOp{-1}));
WebAssemblyOperand::Integer, NameLoc, NameLoc,
WebAssemblyOperand::IntOp{-1}));
}
return false;
}
void onLabelParsed(MCSymbol *Symbol) override {
LastLabel = Symbol;
}
void onLabelParsed(MCSymbol *Symbol) override { LastLabel = Symbol; }
bool ParseDirective(AsmToken DirectiveID) override {
assert(DirectiveID.getKind() == AsmToken::Identifier);
auto &Out = getStreamer();
auto &TOut = reinterpret_cast<WebAssemblyTargetStreamer &>(
*Out.getTargetStreamer());
auto &TOut =
reinterpret_cast<WebAssemblyTargetStreamer &>(*Out.getTargetStreamer());
// TODO: we're just parsing the subset of directives we're interested in,
// and ignoring ones we don't recognise. We should ideally verify
// all directives here.
if (DirectiveID.getString() == ".type") {
// This could be the start of a function, check if followed by
// "label,@function"
if (!(IsNext(AsmToken::Identifier) &&
IsNext(AsmToken::Comma) &&
IsNext(AsmToken::At) &&
Lexer.is(AsmToken::Identifier)))
if (!(IsNext(AsmToken::Identifier) && IsNext(AsmToken::Comma) &&
IsNext(AsmToken::At) && Lexer.is(AsmToken::Identifier)))
return Error("Expected label,@type declaration, got: ", Lexer.getTok());
Parser.Lex();
//Out.EmitSymbolAttribute(??, MCSA_ELF_TypeFunction);
// Out.EmitSymbolAttribute(??, MCSA_ELF_TypeFunction);
} else if (DirectiveID.getString() == ".param" ||
DirectiveID.getString() == ".local") {
// Track the number of locals, needed for correct virtual register
@ -322,28 +319,31 @@ public:
std::vector<MVT> Locals;
while (Lexer.is(AsmToken::Identifier)) {
auto RegType = ParseRegType(Lexer.getTok().getString());
if (RegType == MVT::INVALID_SIMPLE_VALUE_TYPE) return true;
if (RegType == MVT::INVALID_SIMPLE_VALUE_TYPE)
return true;
if (DirectiveID.getString() == ".param") {
Params.push_back(RegType);
} else {
Locals.push_back(RegType);
}
Parser.Lex();
if (!IsNext(AsmToken::Comma)) break;
if (!IsNext(AsmToken::Comma))
break;
}
assert(LastLabel);
TOut.emitParam(LastLabel, Params);
TOut.emitLocal(Locals);
} else {
// For now, ignore anydirective we don't recognize:
while (Lexer.isNot(AsmToken::EndOfStatement)) Parser.Lex();
while (Lexer.isNot(AsmToken::EndOfStatement))
Parser.Lex();
}
return Expect(AsmToken::EndOfStatement, "EOL");
}
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &/*Opcode*/,
OperandVector &Operands,
MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned & /*Opcode*/,
OperandVector &Operands, MCStreamer &Out,
uint64_t &ErrorInfo,
bool MatchingInlineAsm) override {
MCInst Inst;
unsigned MatchResult =
@ -354,8 +354,8 @@ public:
return false;
}
case Match_MissingFeature:
return Parser.Error(IDLoc,
"instruction requires a WASM feature not currently enabled");
return Parser.Error(
IDLoc, "instruction requires a WASM feature not currently enabled");
case Match_MnemonicFail:
return Parser.Error(IDLoc, "invalid instruction");
case Match_NearMisses:

View File

@ -57,10 +57,9 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
// FIXME: For CALL_INDIRECT_VOID, don't print a leading comma, because
// we have an extra flags operand which is not currently printed, for
// compatiblity reasons.
if (i != 0 &&
((MI->getOpcode() != WebAssembly::CALL_INDIRECT_VOID &&
MI->getOpcode() != WebAssembly::CALL_INDIRECT_VOID_S) ||
i != Desc.getNumOperands()))
if (i != 0 && ((MI->getOpcode() != WebAssembly::CALL_INDIRECT_VOID &&
MI->getOpcode() != WebAssembly::CALL_INDIRECT_VOID_S) ||
i != Desc.getNumOperands()))
OS << ", ";
printOperand(MI, i, OS);
}
@ -88,12 +87,14 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
case WebAssembly::END_LOOP_S:
// Have to guard against an empty stack, in case of mismatched pairs
// in assembly parsing.
if (!ControlFlowStack.empty()) ControlFlowStack.pop_back();
if (!ControlFlowStack.empty())
ControlFlowStack.pop_back();
break;
case WebAssembly::END_BLOCK:
case WebAssembly::END_BLOCK_S:
if (!ControlFlowStack.empty()) printAnnotation(
OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
if (!ControlFlowStack.empty())
printAnnotation(
OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
break;
}
@ -118,17 +119,15 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
static std::string toString(const APFloat &FP) {
// Print NaNs with custom payloads specially.
if (FP.isNaN() &&
!FP.bitwiseIsEqual(APFloat::getQNaN(FP.getSemantics())) &&
if (FP.isNaN() && !FP.bitwiseIsEqual(APFloat::getQNaN(FP.getSemantics())) &&
!FP.bitwiseIsEqual(
APFloat::getQNaN(FP.getSemantics(), /*Negative=*/true))) {
APInt AI = FP.bitcastToAPInt();
return
std::string(AI.isNegative() ? "-" : "") + "nan:0x" +
utohexstr(AI.getZExtValue() &
(AI.getBitWidth() == 32 ? INT64_C(0x007fffff) :
INT64_C(0x000fffffffffffff)),
/*LowerCase=*/true);
return std::string(AI.isNegative() ? "-" : "") + "nan:0x" +
utohexstr(AI.getZExtValue() &
(AI.getBitWidth() == 32 ? INT64_C(0x007fffff)
: INT64_C(0x000fffffffffffff)),
/*LowerCase=*/true);
}
// Use C99's hexadecimal floating-point representation.
@ -199,25 +198,40 @@ void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
}
void WebAssemblyInstPrinter::printWebAssemblyP2AlignOperand(
const MCInst *MI, unsigned OpNo, raw_ostream &O) {
void WebAssemblyInstPrinter::printWebAssemblyP2AlignOperand(const MCInst *MI,
unsigned OpNo,
raw_ostream &O) {
int64_t Imm = MI->getOperand(OpNo).getImm();
if (Imm == WebAssembly::GetDefaultP2Align(MI->getOpcode()))
return;
O << ":p2align=" << Imm;
}
void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(
const MCInst *MI, unsigned OpNo, raw_ostream &O) {
void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI,
unsigned OpNo,
raw_ostream &O) {
int64_t Imm = MI->getOperand(OpNo).getImm();
switch (WebAssembly::ExprType(Imm)) {
case WebAssembly::ExprType::Void: break;
case WebAssembly::ExprType::I32: O << "i32"; break;
case WebAssembly::ExprType::I64: O << "i64"; break;
case WebAssembly::ExprType::F32: O << "f32"; break;
case WebAssembly::ExprType::F64: O << "f64"; break;
case WebAssembly::ExprType::V128: O << "v128"; break;
case WebAssembly::ExprType::ExceptRef: O << "except_ref"; break;
case WebAssembly::ExprType::Void:
break;
case WebAssembly::ExprType::I32:
O << "i32";
break;
case WebAssembly::ExprType::I64:
O << "i64";
break;
case WebAssembly::ExprType::F32:
O << "f32";
break;
case WebAssembly::ExprType::F64:
O << "f64";
break;
case WebAssembly::ExprType::V128:
O << "v128";
break;
case WebAssembly::ExprType::ExceptRef:
O << "except_ref";
break;
}
}

View File

@ -73,13 +73,13 @@ public:
const MCFixupKindInfo &
WebAssemblyAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
const static MCFixupKindInfo Infos[WebAssembly::NumTargetFixupKinds] = {
// This table *must* be in the order that the fixup_* kinds are defined in
// WebAssemblyFixupKinds.h.
//
// Name Offset (bits) Size (bits) Flags
{ "fixup_code_sleb128_i32", 0, 5*8, 0 },
{ "fixup_code_sleb128_i64", 0, 10*8, 0 },
{ "fixup_code_uleb128_i32", 0, 5*8, 0 },
// This table *must* be in the order that the fixup_* kinds are defined in
// WebAssemblyFixupKinds.h.
//
// Name Offset (bits) Size (bits) Flags
{"fixup_code_sleb128_i32", 0, 5 * 8, 0},
{"fixup_code_sleb128_i64", 0, 10 * 8, 0},
{"fixup_code_uleb128_i32", 0, 5 * 8, 0},
};
if (Kind < FirstTargetFixupKind)

View File

@ -15,9 +15,9 @@
namespace llvm {
namespace WebAssembly {
enum Fixups {
fixup_code_sleb128_i32 = FirstTargetFixupKind, // 32-bit signed
fixup_code_sleb128_i64, // 64-bit signed
fixup_code_uleb128_i32, // 32-bit unsigned
fixup_code_sleb128_i32 = FirstTargetFixupKind, // 32-bit signed
fixup_code_sleb128_i64, // 64-bit signed
fixup_code_uleb128_i32, // 32-bit unsigned
// Marker
LastTargetFixupKind,

View File

@ -67,8 +67,7 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
OS << uint8_t(Binary);
} else {
assert(Binary <= UINT16_MAX && "Several-byte opcodes not supported yet");
OS << uint8_t(Binary >> 8)
<< uint8_t(Binary);
OS << uint8_t(Binary >> 8) << uint8_t(Binary);
}
// For br_table instructions, encode the size of the table. In the MCInst,
@ -162,9 +161,8 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
} else {
llvm_unreachable("unexpected symbolic operand kind");
}
Fixups.push_back(MCFixup::create(
OS.tell() - Start, MO.getExpr(),
FixupKind, MI.getLoc()));
Fixups.push_back(MCFixup::create(OS.tell() - Start, MO.getExpr(),
FixupKind, MI.getLoc()));
++MCNumFixups;
encodeULEB128(0, OS, PaddedSize);
} else {

View File

@ -125,11 +125,17 @@ extern "C" void LLVMInitializeWebAssemblyTargetMC() {
wasm::ValType WebAssembly::toValType(const MVT &Ty) {
switch (Ty.SimpleTy) {
case MVT::i32: return wasm::ValType::I32;
case MVT::i64: return wasm::ValType::I64;
case MVT::f32: return wasm::ValType::F32;
case MVT::f64: return wasm::ValType::F64;
case MVT::ExceptRef: return wasm::ValType::EXCEPT_REF;
default: llvm_unreachable("unexpected type");
case MVT::i32:
return wasm::ValType::I32;
case MVT::i64:
return wasm::ValType::I64;
case MVT::f32:
return wasm::ValType::F32;
case MVT::f64:
return wasm::ValType::F64;
case MVT::ExceptRef:
return wasm::ValType::EXCEPT_REF;
default:
llvm_unreachable("unexpected type");
}
}

View File

@ -96,8 +96,8 @@ enum TOF {
// Flags to indicate the type of the symbol being referenced
MO_SYMBOL_FUNCTION = 0x1,
MO_SYMBOL_GLOBAL = 0x2,
MO_SYMBOL_MASK = 0x3,
MO_SYMBOL_GLOBAL = 0x2,
MO_SYMBOL_MASK = 0x3,
};
} // end namespace WebAssemblyII

View File

@ -85,7 +85,8 @@ void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<MVT> Types) {
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) {
OS << "\t.functype\t" << Symbol->getName();
if (Results.empty())
OS << ", void";

View File

@ -65,8 +65,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,
void emitIndirectFunctionType(MCSymbol *Symbol, SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) override;
void emitIndIdx(const MCExpr *Value) override;
void emitGlobalImport(StringRef name) override;
@ -82,8 +81,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,
void emitIndirectFunctionType(MCSymbol *Symbol, SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) override;
void emitIndIdx(const MCExpr *Value) override;
void emitGlobalImport(StringRef name) override;

View File

@ -86,9 +86,8 @@ static bool IsGlobalType(const MCValue &Target) {
return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_GLOBAL;
}
unsigned
WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
const MCFixup &Fixup) const {
unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
const MCFixup &Fixup) const {
// WebAssembly functions are not allocated in the data address space. To
// resolve a pointer to a function, we must use a special relocation type.
bool IsFunction = IsFunctionExpr(Fixup.getValue());

View File

@ -24,10 +24,10 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
using namespace llvm;
#define DEBUG_TYPE "wasm-add-missing-prototypes"
@ -62,14 +62,15 @@ ModulePass *llvm::createWebAssemblyAddMissingPrototypes() {
bool WebAssemblyAddMissingPrototypes::runOnModule(Module &M) {
LLVM_DEBUG(dbgs() << "runnning AddMissingPrototypes\n");
std::vector<std::pair<Function*, Function*>> Replacements;
std::vector<std::pair<Function *, Function *>> Replacements;
// Find all the prototype-less function declarations
for (Function &F : M) {
if (!F.isDeclaration() || !F.hasFnAttribute("no-prototype"))
continue;
LLVM_DEBUG(dbgs() << "Found no-prototype function: " << F.getName() << "\n");
LLVM_DEBUG(dbgs() << "Found no-prototype function: " << F.getName()
<< "\n");
// When clang emits prototype-less C functions it uses (...), i.e. varargs
// function that take no arguments (have no sentinel). When we see a
@ -83,11 +84,10 @@ bool WebAssemblyAddMissingPrototypes::runOnModule(Module &M) {
"Functions with 'no-prototype' attribute should not have params: " +
F.getName());
// Create a function prototype based on the first call site (first bitcast)
// that we find.
FunctionType *NewType = nullptr;
Function* NewF = nullptr;
Function *NewF = nullptr;
for (Use &U : F.uses()) {
LLVM_DEBUG(dbgs() << "prototype-less use: " << F.getName() << "\n");
if (BitCastOperator *BC = dyn_cast<BitCastOperator>(U.getUser())) {
@ -134,8 +134,8 @@ bool WebAssemblyAddMissingPrototypes::runOnModule(Module &M) {
// Finally replace the old function declarations with the new ones
for (auto &Pair : Replacements) {
Function* Old = Pair.first;
Function* New = Pair.second;
Function *Old = Pair.first;
Function *New = Pair.second;
Old->eraseFromParent();
M.getFunctionList().push_back(New);
}

View File

@ -90,8 +90,8 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
if (TM.getTargetTriple().isOSBinFormatWasm() &&
F.hasFnAttribute("wasm-import-module")) {
MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Sym);
StringRef Name = F.getFnAttribute("wasm-import-module")
.getValueAsString();
StringRef Name =
F.getFnAttribute("wasm-import-module").getValueAsString();
getTargetStreamer()->emitImportModule(WasmSym, Name);
}
}

View File

@ -29,8 +29,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter {
public:
explicit WebAssemblyAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)),
Subtarget(nullptr), MRI(nullptr), MFI(nullptr) {}
: AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr), MRI(nullptr),
MFI(nullptr) {}
StringRef getPassName() const override {
return "WebAssembly Assembly Printer";

View File

@ -97,8 +97,8 @@ public:
char WebAssemblyCFGStackify::ID = 0;
INITIALIZE_PASS(WebAssemblyCFGStackify, DEBUG_TYPE,
"Insert BLOCK and LOOP markers for WebAssembly scopes",
false, false)
"Insert BLOCK and LOOP markers for WebAssembly scopes", false,
false)
FunctionPass *llvm::createWebAssemblyCFGStackify() {
return new WebAssemblyCFGStackify();
@ -633,10 +633,18 @@ void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) {
WebAssembly::ExprType retType;
switch (MFI.getResults().front().SimpleTy) {
case MVT::i32: retType = WebAssembly::ExprType::I32; break;
case MVT::i64: retType = WebAssembly::ExprType::I64; break;
case MVT::f32: retType = WebAssembly::ExprType::F32; break;
case MVT::f64: retType = WebAssembly::ExprType::F64; break;
case MVT::i32:
retType = WebAssembly::ExprType::I32;
break;
case MVT::i64:
retType = WebAssembly::ExprType::I64;
break;
case MVT::f32:
retType = WebAssembly::ExprType::F32;
break;
case MVT::f64:
retType = WebAssembly::ExprType::F64;
break;
case MVT::v16i8:
case MVT::v8i16:
case MVT::v4i32:
@ -645,8 +653,11 @@ void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) {
case MVT::v2f64:
retType = WebAssembly::ExprType::V128;
break;
case MVT::ExceptRef: retType = WebAssembly::ExprType::ExceptRef; break;
default: llvm_unreachable("unexpected return type");
case MVT::ExceptRef:
retType = WebAssembly::ExprType::ExceptRef;
break;
default:
llvm_unreachable("unexpected return type");
}
for (MachineBasicBlock &MBB : reverse(MF)) {
@ -669,9 +680,8 @@ void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) {
// WebAssembly functions end with an end instruction, as if the function body
// were a block.
static void AppendEndToFunction(
MachineFunction &MF,
const WebAssemblyInstrInfo &TII) {
static void AppendEndToFunction(MachineFunction &MF,
const WebAssemblyInstrInfo &TII) {
BuildMI(MF.back(), MF.back().end(),
MF.back().findPrevDebugLoc(MF.back().end()),
TII.get(WebAssembly::END_FUNCTION));

View File

@ -64,18 +64,30 @@ FunctionPass *llvm::createWebAssemblyCallIndirectFixup() {
static unsigned GetNonPseudoCallIndirectOpcode(const MachineInstr &MI) {
switch (MI.getOpcode()) {
using namespace WebAssembly;
case PCALL_INDIRECT_VOID: return CALL_INDIRECT_VOID;
case PCALL_INDIRECT_I32: return CALL_INDIRECT_I32;
case PCALL_INDIRECT_I64: return CALL_INDIRECT_I64;
case PCALL_INDIRECT_F32: return CALL_INDIRECT_F32;
case PCALL_INDIRECT_F64: return CALL_INDIRECT_F64;
case PCALL_INDIRECT_v16i8: return CALL_INDIRECT_v16i8;
case PCALL_INDIRECT_v8i16: return CALL_INDIRECT_v8i16;
case PCALL_INDIRECT_v4i32: return CALL_INDIRECT_v4i32;
case PCALL_INDIRECT_v2i64: return CALL_INDIRECT_v2i64;
case PCALL_INDIRECT_v4f32: return CALL_INDIRECT_v4f32;
case PCALL_INDIRECT_v2f64: return CALL_INDIRECT_v2f64;
default: return INSTRUCTION_LIST_END;
case PCALL_INDIRECT_VOID:
return CALL_INDIRECT_VOID;
case PCALL_INDIRECT_I32:
return CALL_INDIRECT_I32;
case PCALL_INDIRECT_I64:
return CALL_INDIRECT_I64;
case PCALL_INDIRECT_F32:
return CALL_INDIRECT_F32;
case PCALL_INDIRECT_F64:
return CALL_INDIRECT_F64;
case PCALL_INDIRECT_v16i8:
return CALL_INDIRECT_v16i8;
case PCALL_INDIRECT_v8i16:
return CALL_INDIRECT_v8i16;
case PCALL_INDIRECT_v4i32:
return CALL_INDIRECT_v4i32;
case PCALL_INDIRECT_v2i64:
return CALL_INDIRECT_v2i64;
case PCALL_INDIRECT_v4f32:
return CALL_INDIRECT_v4f32;
case PCALL_INDIRECT_v2f64:
return CALL_INDIRECT_v2f64;
default:
return INSTRUCTION_LIST_END;
}
}
@ -112,10 +124,8 @@ bool WebAssemblyCallIndirectFixup::runOnMachineFunction(MachineFunction &MF) {
Ops.push_back(MachineOperand::CreateImm(0));
for (const MachineOperand &MO :
make_range(MI.operands_begin() +
MI.getDesc().getNumDefs() + 1,
MI.operands_begin() +
MI.getNumExplicitOperands()))
make_range(MI.operands_begin() + MI.getDesc().getNumDefs() + 1,
MI.operands_begin() + MI.getNumExplicitOperands()))
Ops.push_back(MO);
Ops.push_back(MI.getOperand(MI.getDesc().getNumDefs()));

View File

@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "WebAssemblyExceptionInfo.h"
#include "WebAssemblyUtilities.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyUtilities.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/MachineDominanceFrontier.h"
#include "llvm/CodeGen/MachineDominators.h"

View File

@ -114,8 +114,8 @@ private:
// Utility helper routines
MVT::SimpleValueType getSimpleType(Type *Ty) {
EVT VT = TLI.getValueType(DL, Ty, /*HandleUnknown=*/true);
return VT.isSimple() ? VT.getSimpleVT().SimpleTy :
MVT::INVALID_SIMPLE_VALUE_TYPE;
return VT.isSimple() ? VT.getSimpleVT().SimpleTy
: MVT::INVALID_SIMPLE_VALUE_TYPE;
}
MVT::SimpleValueType getLegalType(MVT::SimpleValueType VT) {
switch (VT) {
@ -155,11 +155,9 @@ private:
MVT::SimpleValueType From);
unsigned signExtendToI32(unsigned Reg, const Value *V,
MVT::SimpleValueType From);
unsigned zeroExtend(unsigned Reg, const Value *V,
MVT::SimpleValueType From,
unsigned zeroExtend(unsigned Reg, const Value *V, MVT::SimpleValueType From,
MVT::SimpleValueType To);
unsigned signExtend(unsigned Reg, const Value *V,
MVT::SimpleValueType From,
unsigned signExtend(unsigned Reg, const Value *V, MVT::SimpleValueType From,
MVT::SimpleValueType To);
unsigned getRegForUnsignedValue(const Value *V);
unsigned getRegForSignedValue(const Value *V);
@ -376,14 +374,12 @@ void WebAssemblyFastISel::materializeLoadStoreOperands(Address &Addr) {
if (Addr.isRegBase()) {
unsigned Reg = Addr.getReg();
if (Reg == 0) {
Reg = createResultReg(Subtarget->hasAddr64() ?
&WebAssembly::I64RegClass :
&WebAssembly::I32RegClass);
unsigned Opc = Subtarget->hasAddr64() ?
WebAssembly::CONST_I64 :
WebAssembly::CONST_I32;
Reg = createResultReg(Subtarget->hasAddr64() ? &WebAssembly::I64RegClass
: &WebAssembly::I32RegClass);
unsigned Opc = Subtarget->hasAddr64() ? WebAssembly::CONST_I64
: WebAssembly::CONST_I32;
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), Reg)
.addImm(0);
.addImm(0);
Addr.setReg(Reg);
}
}
@ -459,13 +455,13 @@ unsigned WebAssemblyFastISel::zeroExtendToI32(unsigned Reg, const Value *V,
unsigned Imm = createResultReg(&WebAssembly::I32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(WebAssembly::CONST_I32), Imm)
.addImm(~(~uint64_t(0) << MVT(From).getSizeInBits()));
.addImm(~(~uint64_t(0) << MVT(From).getSizeInBits()));
unsigned Result = createResultReg(&WebAssembly::I32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(WebAssembly::AND_I32), Result)
.addReg(Reg)
.addReg(Imm);
.addReg(Reg)
.addReg(Imm);
return Result;
}
@ -489,19 +485,19 @@ unsigned WebAssemblyFastISel::signExtendToI32(unsigned Reg, const Value *V,
unsigned Imm = createResultReg(&WebAssembly::I32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(WebAssembly::CONST_I32), Imm)
.addImm(32 - MVT(From).getSizeInBits());
.addImm(32 - MVT(From).getSizeInBits());
unsigned Left = createResultReg(&WebAssembly::I32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(WebAssembly::SHL_I32), Left)
.addReg(Reg)
.addReg(Imm);
.addReg(Reg)
.addReg(Imm);
unsigned Right = createResultReg(&WebAssembly::I32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(WebAssembly::SHR_S_I32), Right)
.addReg(Left)
.addReg(Imm);
.addReg(Left)
.addReg(Imm);
return Right;
}
@ -564,8 +560,7 @@ unsigned WebAssemblyFastISel::getRegForSignedValue(const Value *V) {
unsigned WebAssemblyFastISel::getRegForPromotedValue(const Value *V,
bool IsSigned) {
return IsSigned ? getRegForSignedValue(V) :
getRegForUnsignedValue(V);
return IsSigned ? getRegForSignedValue(V) : getRegForUnsignedValue(V);
}
unsigned WebAssemblyFastISel::notValue(unsigned Reg) {
@ -574,15 +569,15 @@ unsigned WebAssemblyFastISel::notValue(unsigned Reg) {
unsigned NotReg = createResultReg(&WebAssembly::I32RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(WebAssembly::EQZ_I32), NotReg)
.addReg(Reg);
.addReg(Reg);
return NotReg;
}
unsigned WebAssemblyFastISel::copyValue(unsigned Reg) {
unsigned ResultReg = createResultReg(MRI.getRegClass(Reg));
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(WebAssembly::COPY), ResultReg)
.addReg(Reg);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(WebAssembly::COPY),
ResultReg)
.addReg(Reg);
return ResultReg;
}
@ -591,12 +586,11 @@ unsigned WebAssemblyFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
FuncInfo.StaticAllocaMap.find(AI);
if (SI != FuncInfo.StaticAllocaMap.end()) {
unsigned ResultReg = createResultReg(Subtarget->hasAddr64() ?
&WebAssembly::I64RegClass :
&WebAssembly::I32RegClass);
unsigned Opc = Subtarget->hasAddr64() ?
WebAssembly::COPY_I64 :
WebAssembly::COPY_I32;
unsigned ResultReg =
createResultReg(Subtarget->hasAddr64() ? &WebAssembly::I64RegClass
: &WebAssembly::I32RegClass);
unsigned Opc =
Subtarget->hasAddr64() ? WebAssembly::COPY_I64 : WebAssembly::COPY_I32;
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
.addFrameIndex(SI->second);
return ResultReg;
@ -607,14 +601,13 @@ unsigned WebAssemblyFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
unsigned WebAssemblyFastISel::fastMaterializeConstant(const Constant *C) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
unsigned ResultReg = createResultReg(Subtarget->hasAddr64() ?
&WebAssembly::I64RegClass :
&WebAssembly::I32RegClass);
unsigned Opc = Subtarget->hasAddr64() ?
WebAssembly::CONST_I64 :
WebAssembly::CONST_I32;
unsigned ResultReg =
createResultReg(Subtarget->hasAddr64() ? &WebAssembly::I64RegClass
: &WebAssembly::I32RegClass);
unsigned Opc = Subtarget->hasAddr64() ? WebAssembly::CONST_I64
: WebAssembly::CONST_I32;
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
.addGlobalAddress(GV);
.addGlobalAddress(GV);
return ResultReg;
}
@ -701,7 +694,7 @@ bool WebAssemblyFastISel::fastLowerArguments() {
}
unsigned ResultReg = createResultReg(RC);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
.addImm(i);
.addImm(i);
updateValueMap(&Arg, ResultReg);
++i;
@ -720,7 +713,8 @@ bool WebAssemblyFastISel::fastLowerArguments() {
}
if (!F->getReturnType()->isVoidTy()) {
MVT::SimpleValueType RetTy = getLegalType(getSimpleType(F->getReturnType()));
MVT::SimpleValueType RetTy =
getLegalType(getSimpleType(F->getReturnType()));
if (RetTy == MVT::INVALID_SIMPLE_VALUE_TYPE) {
MFI->clearParamsAndResults();
return false;
@ -778,33 +772,33 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
ResultReg = createResultReg(&WebAssembly::F64RegClass);
break;
case MVT::v16i8:
Opc =
IsDirect ? WebAssembly::CALL_v16i8 : WebAssembly::PCALL_INDIRECT_v16i8;
Opc = IsDirect ? WebAssembly::CALL_v16i8
: WebAssembly::PCALL_INDIRECT_v16i8;
ResultReg = createResultReg(&WebAssembly::V128RegClass);
break;
case MVT::v8i16:
Opc =
IsDirect ? WebAssembly::CALL_v8i16 : WebAssembly::PCALL_INDIRECT_v8i16;
Opc = IsDirect ? WebAssembly::CALL_v8i16
: WebAssembly::PCALL_INDIRECT_v8i16;
ResultReg = createResultReg(&WebAssembly::V128RegClass);
break;
case MVT::v4i32:
Opc =
IsDirect ? WebAssembly::CALL_v4i32 : WebAssembly::PCALL_INDIRECT_v4i32;
Opc = IsDirect ? WebAssembly::CALL_v4i32
: WebAssembly::PCALL_INDIRECT_v4i32;
ResultReg = createResultReg(&WebAssembly::V128RegClass);
break;
case MVT::v2i64:
Opc =
IsDirect ? WebAssembly::CALL_v2i64 : WebAssembly::PCALL_INDIRECT_v2i64;
Opc = IsDirect ? WebAssembly::CALL_v2i64
: WebAssembly::PCALL_INDIRECT_v2i64;
ResultReg = createResultReg(&WebAssembly::V128RegClass);
break;
case MVT::v4f32:
Opc =
IsDirect ? WebAssembly::CALL_v4f32 : WebAssembly::PCALL_INDIRECT_v4f32;
Opc = IsDirect ? WebAssembly::CALL_v4f32
: WebAssembly::PCALL_INDIRECT_v4f32;
ResultReg = createResultReg(&WebAssembly::V128RegClass);
break;
case MVT::v2f64:
Opc =
IsDirect ? WebAssembly::CALL_v2f64 : WebAssembly::PCALL_INDIRECT_v2f64;
Opc = IsDirect ? WebAssembly::CALL_v2f64
: WebAssembly::PCALL_INDIRECT_v2f64;
ResultReg = createResultReg(&WebAssembly::V128RegClass);
break;
case MVT::ExceptRef:
@ -873,11 +867,11 @@ bool WebAssemblyFastISel::selectSelect(const Instruction *I) {
const SelectInst *Select = cast<SelectInst>(I);
bool Not;
unsigned CondReg = getRegForI1Value(Select->getCondition(), Not);
unsigned CondReg = getRegForI1Value(Select->getCondition(), Not);
if (CondReg == 0)
return false;
unsigned TrueReg = getRegForValue(Select->getTrueValue());
unsigned TrueReg = getRegForValue(Select->getTrueValue());
if (TrueReg == 0)
return false;
@ -920,9 +914,9 @@ bool WebAssemblyFastISel::selectSelect(const Instruction *I) {
unsigned ResultReg = createResultReg(RC);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
.addReg(TrueReg)
.addReg(FalseReg)
.addReg(CondReg);
.addReg(TrueReg)
.addReg(FalseReg)
.addReg(CondReg);
updateValueMap(Select, ResultReg);
return true;
@ -1022,7 +1016,8 @@ bool WebAssemblyFastISel::selectICmp(const Instruction *I) {
Opc = I32 ? WebAssembly::LE_S_I32 : WebAssembly::LE_S_I64;
isSigned = true;
break;
default: return false;
default:
return false;
}
unsigned LHS = getRegForPromotedValue(ICmp->getOperand(0), isSigned);
@ -1230,7 +1225,8 @@ bool WebAssemblyFastISel::selectStore(const Instruction *I) {
case MVT::f64:
Opc = WebAssembly::STORE_F64;
break;
default: return false;
default:
return false;
}
materializeLoadStoreOperands(Addr);
@ -1295,8 +1291,10 @@ bool WebAssemblyFastISel::selectRet(const Instruction *I) {
unsigned Opc;
switch (getSimpleType(RV->getType())) {
case MVT::i1: case MVT::i8:
case MVT::i16: case MVT::i32:
case MVT::i1:
case MVT::i8:
case MVT::i16:
case MVT::i32:
Opc = WebAssembly::RETURN_I32;
break;
case MVT::i64:
@ -1329,7 +1327,8 @@ bool WebAssemblyFastISel::selectRet(const Instruction *I) {
case MVT::ExceptRef:
Opc = WebAssembly::RETURN_EXCEPT_REF;
break;
default: return false;
default:
return false;
}
unsigned Reg;
@ -1359,19 +1358,32 @@ bool WebAssemblyFastISel::fastSelectInstruction(const Instruction *I) {
if (selectCall(I))
return true;
break;
case Instruction::Select: return selectSelect(I);
case Instruction::Trunc: return selectTrunc(I);
case Instruction::ZExt: return selectZExt(I);
case Instruction::SExt: return selectSExt(I);
case Instruction::ICmp: return selectICmp(I);
case Instruction::FCmp: return selectFCmp(I);
case Instruction::BitCast: return selectBitCast(I);
case Instruction::Load: return selectLoad(I);
case Instruction::Store: return selectStore(I);
case Instruction::Br: return selectBr(I);
case Instruction::Ret: return selectRet(I);
case Instruction::Unreachable: return selectUnreachable(I);
default: break;
case Instruction::Select:
return selectSelect(I);
case Instruction::Trunc:
return selectTrunc(I);
case Instruction::ZExt:
return selectZExt(I);
case Instruction::SExt:
return selectSExt(I);
case Instruction::ICmp:
return selectICmp(I);
case Instruction::FCmp:
return selectFCmp(I);
case Instruction::BitCast:
return selectBitCast(I);
case Instruction::Load:
return selectLoad(I);
case Instruction::Store:
return selectStore(I);
case Instruction::Br:
return selectBr(I);
case Instruction::Ret:
return selectRet(I);
case Instruction::Unreachable:
return selectUnreachable(I);
default:
break;
}
// Fall back to target-independent instruction selection.

View File

@ -36,10 +36,10 @@ using namespace llvm;
#define DEBUG_TYPE "wasm-fix-function-bitcasts"
static cl::opt<bool> TemporaryWorkarounds(
"wasm-temporary-workarounds",
cl::desc("Apply certain temporary workarounds"),
cl::init(true), cl::Hidden);
static cl::opt<bool>
TemporaryWorkarounds("wasm-temporary-workarounds",
cl::desc("Apply certain temporary workarounds"),
cl::init(true), cl::Hidden);
namespace {
class FixFunctionBitcasts final : public ModulePass {
@ -108,7 +108,7 @@ static void FindUses(Value *V, Function &F,
// instead).
//
// If there is a type mismatch that we know would result in an invalid wasm
// module then generate wrapper that contains unreachable (i.e. abort at
// module then generate wrapper that contains unreachable (i.e. abort at
// runtime). Such programs are deep into undefined behaviour territory,
// but we choose to fail at runtime rather than generate and invalid module
// or fail at compiler time. The reason we delay the error is that we want
@ -117,7 +117,7 @@ static void FindUses(Value *V, Function &F,
// CMake detects the existence of a function in a toolchain).
//
// For bitcasts that involve struct types we don't know at this stage if they
// would be equivalent at the wasm level and so we can't know if we need to
// would be equivalent at the wasm level and so we can't know if we need to
// generate a wrapper.
static Function *CreateWrapper(Function *F, FunctionType *Ty) {
Module *M = F->getParent();
@ -212,7 +212,8 @@ static Function *CreateWrapper(Function *F, FunctionType *Ty) {
if (TypeMismatch) {
// Create a new wrapper that simply contains `unreachable`.
Wrapper->eraseFromParent();
Wrapper = Function::Create(Ty, Function::PrivateLinkage, F->getName() + "_bitcast_invalid", M);
Wrapper = Function::Create(Ty, Function::PrivateLinkage,
F->getName() + "_bitcast_invalid", M);
BasicBlock *BB = BasicBlock::Create(M->getContext(), "body", Wrapper);
new UnreachableInst(M->getContext(), BB);
Wrapper->setName(F->getName() + "_bitcast_invalid");
@ -243,19 +244,15 @@ bool FixFunctionBitcasts::runOnModule(Module &M) {
if (!TemporaryWorkarounds && !F.isDeclaration() && F.getName() == "main") {
Main = &F;
LLVMContext &C = M.getContext();
Type *MainArgTys[] = {
PointerType::get(Type::getInt8PtrTy(C), 0),
Type::getInt32Ty(C)
};
Type *MainArgTys[] = {PointerType::get(Type::getInt8PtrTy(C), 0),
Type::getInt32Ty(C)};
FunctionType *MainTy = FunctionType::get(Type::getInt32Ty(C), MainArgTys,
/*isVarArg=*/false);
if (F.getFunctionType() != MainTy) {
Value *Args[] = {
UndefValue::get(MainArgTys[0]),
UndefValue::get(MainArgTys[1])
};
Value *Casted = ConstantExpr::getBitCast(Main,
PointerType::get(MainTy, 0));
Value *Args[] = {UndefValue::get(MainArgTys[0]),
UndefValue::get(MainArgTys[1])};
Value *Casted =
ConstantExpr::getBitCast(Main, PointerType::get(MainTy, 0));
CallMain = CallInst::Create(Casted, Args, "call_main");
Use *UseMain = &CallMain->getOperandUse(2);
Uses.push_back(std::make_pair(UseMain, &F));

View File

@ -43,8 +43,7 @@ using namespace llvm;
/// require stricter alignment than the stack pointer itself. Because we need
/// to shift the stack pointer by some unknown amount to force the alignment,
/// we need to record the value of the stack pointer on entry to the function.
bool WebAssemblyFrameLowering::hasBP(
const MachineFunction &MF) const {
bool WebAssemblyFrameLowering::hasBP(const MachineFunction &MF) const {
const auto *RegInfo =
MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();
return RegInfo->needsStackRealignment(MF);
@ -158,7 +157,8 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
assert(MFI.getCalleeSavedInfo().empty() &&
"WebAssembly should not have callee-saved registers");
if (!needsSP(MF)) return;
if (!needsSP(MF))
return;
uint64_t StackSize = MFI.getStackSize();
const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
@ -202,7 +202,7 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
unsigned BitmaskReg = MRI.createVirtualRegister(PtrRC);
unsigned Alignment = MFI.getMaxAlignment();
assert((1u << countTrailingZeros(Alignment)) == Alignment &&
"Alignment must be a power of 2");
"Alignment must be a power of 2");
BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), BitmaskReg)
.addImm((int)~(Alignment - 1));
BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::AND_I32),
@ -214,8 +214,7 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
// Unlike most conventional targets (where FP points to the saved FP),
// FP points to the bottom of the fixed-size locals, so we can use positive
// offsets in load/store instructions.
BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY),
WebAssembly::FP32)
BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY), WebAssembly::FP32)
.addReg(WebAssembly::SP32);
}
if (StackSize && needsSPWriteback(MF)) {
@ -226,7 +225,8 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
void WebAssemblyFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
uint64_t StackSize = MF.getFrameInfo().getStackSize();
if (!needsSP(MF) || !needsSPWriteback(MF)) return;
if (!needsSP(MF) || !needsSPWriteback(MF))
return;
const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
auto &MRI = MF.getRegInfo();
auto InsertPt = MBB.getFirstTerminator();

View File

@ -22,7 +22,7 @@ namespace llvm {
class MachineFrameInfo;
class WebAssemblyFrameLowering final : public TargetFrameLowering {
public:
public:
/// Size of the red zone for the user stack (leaf functions can use this much
/// space below the stack pointer without writing it back to __stack_pointer
/// global).
@ -35,9 +35,9 @@ class WebAssemblyFrameLowering final : public TargetFrameLowering {
/*TransientStackAlignment=*/16,
/*StackRealignable=*/true) {}
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
/// These methods insert prolog and epilog code into the function.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
@ -61,6 +61,6 @@ private:
bool needsSPWriteback(const MachineFunction &MF) const;
};
} // end namespace llvm
} // end namespace llvm
#endif

View File

@ -95,8 +95,8 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
ISD::SETULT, ISD::SETULE, ISD::SETUGT, ISD::SETUGE})
setCondCodeAction(CC, T, Expand);
// Expand floating-point library function operators.
for (auto Op : {ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW, ISD::FREM,
ISD::FMA})
for (auto Op :
{ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW, ISD::FREM, ISD::FMA})
setOperationAction(Op, T, Expand);
// Note supported floating-point library function operators that otherwise
// default to expand.
@ -116,10 +116,9 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
for (auto T : {MVT::i32, MVT::i64}) {
// Expand unavailable integer operations.
for (auto Op :
{ISD::BSWAP, ISD::SMUL_LOHI, ISD::UMUL_LOHI,
ISD::MULHS, ISD::MULHU, ISD::SDIVREM, ISD::UDIVREM, ISD::SHL_PARTS,
ISD::SRA_PARTS, ISD::SRL_PARTS, ISD::ADDC, ISD::ADDE, ISD::SUBC,
ISD::SUBE}) {
{ISD::BSWAP, ISD::SMUL_LOHI, ISD::UMUL_LOHI, ISD::MULHS, ISD::MULHU,
ISD::SDIVREM, ISD::UDIVREM, ISD::SHL_PARTS, ISD::SRA_PARTS,
ISD::SRL_PARTS, ISD::ADDC, ISD::ADDE, ISD::SUBC, ISD::SUBE}) {
setOperationAction(Op, T, Expand);
}
}
@ -201,7 +200,8 @@ bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/,
EVT VT) const {
unsigned BitWidth = NextPowerOf2(VT.getSizeInBits() - 1);
if (BitWidth > 1 && BitWidth < 8) BitWidth = 8;
if (BitWidth > 1 && BitWidth < 8)
BitWidth = 8;
if (BitWidth > 64) {
// The shift will be lowered to a libcall, and compiler-rt libcalls expect
@ -220,17 +220,11 @@ MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/,
// Lower an fp-to-int conversion operator from the LLVM opcode, which has an
// undefined result on invalid/overflow, to the WebAssembly opcode, which
// traps on invalid/overflow.
static MachineBasicBlock *
LowerFPToInt(
MachineInstr &MI,
DebugLoc DL,
MachineBasicBlock *BB,
const TargetInstrInfo &TII,
bool IsUnsigned,
bool Int64,
bool Float64,
unsigned LoweredOpcode
) {
static MachineBasicBlock *LowerFPToInt(MachineInstr &MI, DebugLoc DL,
MachineBasicBlock *BB,
const TargetInstrInfo &TII,
bool IsUnsigned, bool Int64,
bool Float64, unsigned LoweredOpcode) {
MachineRegisterInfo &MRI = BB->getParent()->getRegInfo();
unsigned OutReg = MI.getOperand(0).getReg();
@ -262,8 +256,7 @@ LowerFPToInt(
// Transfer the remainder of BB and its successor edges to DoneMBB.
DoneMBB->splice(DoneMBB->begin(), BB,
std::next(MachineBasicBlock::iterator(MI)),
BB->end());
std::next(MachineBasicBlock::iterator(MI)), BB->end());
DoneMBB->transferSuccessorsAndUpdatePHIs(BB);
BB->addSuccessor(TrueMBB);
@ -285,45 +278,33 @@ LowerFPToInt(
if (IsUnsigned) {
Tmp0 = InReg;
} else {
BuildMI(BB, DL, TII.get(Abs), Tmp0)
.addReg(InReg);
BuildMI(BB, DL, TII.get(Abs), Tmp0).addReg(InReg);
}
BuildMI(BB, DL, TII.get(FConst), Tmp1)
.addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, CmpVal)));
BuildMI(BB, DL, TII.get(LT), CmpReg)
.addReg(Tmp0)
.addReg(Tmp1);
BuildMI(BB, DL, TII.get(LT), CmpReg).addReg(Tmp0).addReg(Tmp1);
// For unsigned numbers, we have to do a separate comparison with zero.
if (IsUnsigned) {
Tmp1 = MRI.createVirtualRegister(MRI.getRegClass(InReg));
unsigned SecondCmpReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
unsigned SecondCmpReg =
MRI.createVirtualRegister(&WebAssembly::I32RegClass);
unsigned AndReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
BuildMI(BB, DL, TII.get(FConst), Tmp1)
.addFPImm(cast<ConstantFP>(ConstantFP::get(Ty, 0.0)));
BuildMI(BB, DL, TII.get(GE), SecondCmpReg)
.addReg(Tmp0)
.addReg(Tmp1);
BuildMI(BB, DL, TII.get(And), AndReg)
.addReg(CmpReg)
.addReg(SecondCmpReg);
BuildMI(BB, DL, TII.get(GE), SecondCmpReg).addReg(Tmp0).addReg(Tmp1);
BuildMI(BB, DL, TII.get(And), AndReg).addReg(CmpReg).addReg(SecondCmpReg);
CmpReg = AndReg;
}
BuildMI(BB, DL, TII.get(Eqz), EqzReg)
.addReg(CmpReg);
BuildMI(BB, DL, TII.get(Eqz), EqzReg).addReg(CmpReg);
// Create the CFG diamond to select between doing the conversion or using
// the substitute value.
BuildMI(BB, DL, TII.get(WebAssembly::BR_IF))
.addMBB(TrueMBB)
.addReg(EqzReg);
BuildMI(FalseMBB, DL, TII.get(LoweredOpcode), FalseReg)
.addReg(InReg);
BuildMI(FalseMBB, DL, TII.get(WebAssembly::BR))
.addMBB(DoneMBB);
BuildMI(TrueMBB, DL, TII.get(IConst), TrueReg)
.addImm(Substitute);
BuildMI(BB, DL, TII.get(WebAssembly::BR_IF)).addMBB(TrueMBB).addReg(EqzReg);
BuildMI(FalseMBB, DL, TII.get(LoweredOpcode), FalseReg).addReg(InReg);
BuildMI(FalseMBB, DL, TII.get(WebAssembly::BR)).addMBB(DoneMBB);
BuildMI(TrueMBB, DL, TII.get(IConst), TrueReg).addImm(Substitute);
BuildMI(*DoneMBB, DoneMBB->begin(), DL, TII.get(TargetOpcode::PHI), OutReg)
.addReg(FalseReg)
.addMBB(FalseMBB)
@ -333,16 +314,14 @@ LowerFPToInt(
return DoneMBB;
}
MachineBasicBlock *
WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
MachineInstr &MI,
MachineBasicBlock *BB
) const {
MachineBasicBlock *WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
MachineInstr &MI, MachineBasicBlock *BB) const {
const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
DebugLoc DL = MI.getDebugLoc();
switch (MI.getOpcode()) {
default: llvm_unreachable("Unexpected instr type to insert");
default:
llvm_unreachable("Unexpected instr type to insert");
case WebAssembly::FP_TO_SINT_I32_F32:
return LowerFPToInt(MI, DL, BB, TII, false, false, false,
WebAssembly::I32_TRUNC_S_F32);
@ -367,17 +346,17 @@ WebAssemblyTargetLowering::EmitInstrWithCustomInserter(
case WebAssembly::FP_TO_UINT_I64_F64:
return LowerFPToInt(MI, DL, BB, TII, true, true, true,
WebAssembly::I64_TRUNC_U_F64);
llvm_unreachable("Unexpected instruction to emit with custom inserter");
llvm_unreachable("Unexpected instruction to emit with custom inserter");
}
}
const char *WebAssemblyTargetLowering::getTargetNodeName(
unsigned Opcode) const {
const char *
WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
case WebAssemblyISD::FIRST_NUMBER:
break;
#define HANDLE_NODETYPE(NODE) \
case WebAssemblyISD::NODE: \
case WebAssemblyISD::FIRST_NUMBER:
break;
#define HANDLE_NODETYPE(NODE) \
case WebAssemblyISD::NODE: \
return "WebAssemblyISD::" #NODE;
#include "WebAssemblyISD.def"
#undef HANDLE_NODETYPE
@ -392,21 +371,21 @@ WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
// WebAssembly register class.
if (Constraint.size() == 1) {
switch (Constraint[0]) {
case 'r':
assert(VT != MVT::iPTR && "Pointer MVT not expected here");
if (Subtarget->hasSIMD128() && VT.isVector()) {
if (VT.getSizeInBits() == 128)
return std::make_pair(0U, &WebAssembly::V128RegClass);
}
if (VT.isInteger() && !VT.isVector()) {
if (VT.getSizeInBits() <= 32)
return std::make_pair(0U, &WebAssembly::I32RegClass);
if (VT.getSizeInBits() <= 64)
return std::make_pair(0U, &WebAssembly::I64RegClass);
}
break;
default:
break;
case 'r':
assert(VT != MVT::iPTR && "Pointer MVT not expected here");
if (Subtarget->hasSIMD128() && VT.isVector()) {
if (VT.getSizeInBits() == 128)
return std::make_pair(0U, &WebAssembly::V128RegClass);
}
if (VT.isInteger() && !VT.isVector()) {
if (VT.getSizeInBits() <= 32)
return std::make_pair(0U, &WebAssembly::I32RegClass);
if (VT.getSizeInBits() <= 64)
return std::make_pair(0U, &WebAssembly::I64RegClass);
}
break;
default:
break;
}
}
@ -425,16 +404,17 @@ bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const {
bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL,
const AddrMode &AM,
Type *Ty,
unsigned AS,
Type *Ty, unsigned AS,
Instruction *I) const {
// WebAssembly offsets are added as unsigned without wrapping. The
// isLegalAddressingMode gives us no way to determine if wrapping could be
// happening, so we approximate this by accepting only non-negative offsets.
if (AM.BaseOffs < 0) return false;
if (AM.BaseOffs < 0)
return false;
// WebAssembly has no scale register operands.
if (AM.Scale != 0) return false;
if (AM.Scale != 0)
return false;
// Everything else is legal.
return true;
@ -448,7 +428,8 @@ bool WebAssemblyTargetLowering::allowsMisalignedMemoryAccesses(
// for the kinds of things that LLVM uses this for (merging adjacent stores
// of constants, etc.), WebAssembly implementations will either want the
// unaligned access or they'll split anyway.
if (Fast) *Fast = true;
if (Fast)
*Fast = true;
return true;
}
@ -535,8 +516,9 @@ static bool CallingConvSupported(CallingConv::ID CallConv) {
CallConv == CallingConv::CXX_FAST_TLS;
}
SDValue WebAssemblyTargetLowering::LowerCall(
CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const {
SDValue
WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc DL = CLI.DL;
SDValue Chain = CLI.Chain;
@ -638,9 +620,9 @@ SDValue WebAssemblyTargetLowering::LowerCall(
FINode = DAG.getFrameIndex(FI, getPointerTy(Layout));
SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, FINode,
DAG.getConstant(Offset, DL, PtrVT));
Chains.push_back(DAG.getStore(
Chain, DL, Arg, Add,
MachinePointerInfo::getFixedStack(MF, FI, Offset), 0));
Chains.push_back(
DAG.getStore(Chain, DL, Arg, Add,
MachinePointerInfo::getFixedStack(MF, FI, Offset), 0));
}
if (!Chains.empty())
Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
@ -658,7 +640,8 @@ SDValue WebAssemblyTargetLowering::LowerCall(
Ops.append(OutVals.begin(),
IsVarArg ? OutVals.begin() + NumFixedArgs : OutVals.end());
// Add a pointer to the vararg buffer.
if (IsVarArg) Ops.push_back(FINode);
if (IsVarArg)
Ops.push_back(FINode);
SmallVector<EVT, 8> InTys;
for (const auto &In : Ins) {
@ -752,11 +735,10 @@ SDValue WebAssemblyTargetLowering::LowerFormalArguments(
fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
// Ignore In.getOrigAlign() because all our arguments are passed in
// registers.
InVals.push_back(
In.Used
? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
DAG.getTargetConstant(InVals.size(), DL, MVT::i32))
: DAG.getUNDEF(In.VT));
InVals.push_back(In.Used ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
DAG.getTargetConstant(InVals.size(),
DL, MVT::i32))
: DAG.getUNDEF(In.VT));
// Record the number and types of arguments.
MFI->addParam(In.VT);
@ -794,34 +776,34 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
switch (Op.getOpcode()) {
default:
llvm_unreachable("unimplemented operation lowering");
return SDValue();
case ISD::FrameIndex:
return LowerFrameIndex(Op, DAG);
case ISD::GlobalAddress:
return LowerGlobalAddress(Op, DAG);
case ISD::ExternalSymbol:
return LowerExternalSymbol(Op, DAG);
case ISD::JumpTable:
return LowerJumpTable(Op, DAG);
case ISD::BR_JT:
return LowerBR_JT(Op, DAG);
case ISD::VASTART:
return LowerVASTART(Op, DAG);
case ISD::BlockAddress:
case ISD::BRIND:
fail(DL, DAG, "WebAssembly hasn't implemented computed gotos");
return SDValue();
case ISD::RETURNADDR: // Probably nothing meaningful can be returned here.
fail(DL, DAG, "WebAssembly hasn't implemented __builtin_return_address");
return SDValue();
case ISD::FRAMEADDR:
return LowerFRAMEADDR(Op, DAG);
case ISD::CopyToReg:
return LowerCopyToReg(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN:
return LowerINTRINSIC_WO_CHAIN(Op, DAG);
default:
llvm_unreachable("unimplemented operation lowering");
return SDValue();
case ISD::FrameIndex:
return LowerFrameIndex(Op, DAG);
case ISD::GlobalAddress:
return LowerGlobalAddress(Op, DAG);
case ISD::ExternalSymbol:
return LowerExternalSymbol(Op, DAG);
case ISD::JumpTable:
return LowerJumpTable(Op, DAG);
case ISD::BR_JT:
return LowerBR_JT(Op, DAG);
case ISD::VASTART:
return LowerVASTART(Op, DAG);
case ISD::BlockAddress:
case ISD::BRIND:
fail(DL, DAG, "WebAssembly hasn't implemented computed gotos");
return SDValue();
case ISD::RETURNADDR: // Probably nothing meaningful can be returned here.
fail(DL, DAG, "WebAssembly hasn't implemented __builtin_return_address");
return SDValue();
case ISD::FRAMEADDR:
return LowerFRAMEADDR(Op, DAG);
case ISD::CopyToReg:
return LowerCopyToReg(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN:
return LowerINTRINSIC_WO_CHAIN(Op, DAG);
}
}
@ -838,16 +820,15 @@ SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op,
SDLoc DL(Op);
unsigned Reg = cast<RegisterSDNode>(Op.getOperand(1))->getReg();
EVT VT = Src.getValueType();
SDValue Copy(
DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_I32
: WebAssembly::COPY_I64,
DL, VT, Src),
0);
SDValue Copy(DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_I32
: WebAssembly::COPY_I64,
DL, VT, Src),
0);
return Op.getNode()->getNumValues() == 1
? DAG.getCopyToReg(Chain, DL, Reg, Copy)
: DAG.getCopyToReg(Chain, DL, Reg, Copy, Op.getNumOperands() == 4
? Op.getOperand(3)
: SDValue());
: DAG.getCopyToReg(Chain, DL, Reg, Copy,
Op.getNumOperands() == 4 ? Op.getOperand(3)
: SDValue());
}
return SDValue();
}
@ -887,8 +868,9 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset()));
}
SDValue WebAssemblyTargetLowering::LowerExternalSymbol(
SDValue Op, SelectionDAG &DAG) const {
SDValue
WebAssemblyTargetLowering::LowerExternalSymbol(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
const auto *ES = cast<ExternalSymbolSDNode>(Op);
EVT VT = Op.getValueType();
@ -899,9 +881,10 @@ SDValue WebAssemblyTargetLowering::LowerExternalSymbol(
// we don't know anything about the symbol other than its name, because all
// external symbols used in target-independent SelectionDAG code are for
// functions.
return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
DAG.getTargetExternalSymbol(ES->getSymbol(), VT,
WebAssemblyII::MO_SYMBOL_FUNCTION));
return DAG.getNode(
WebAssemblyISD::Wrapper, DL, VT,
DAG.getTargetExternalSymbol(ES->getSymbol(), VT,
WebAssemblyII::MO_SYMBOL_FUNCTION));
}
SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op,
@ -930,7 +913,8 @@ SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op,
const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs;
// Add an operand for each case.
for (auto MBB : MBBs) Ops.push_back(DAG.getBasicBlock(MBB));
for (auto MBB : MBBs)
Ops.push_back(DAG.getBasicBlock(MBB));
// TODO: For now, we just pick something arbitrary for a default case for now.
// We really want to sniff out the guard and put in the real default case (and

View File

@ -29,17 +29,17 @@ enum NodeType : unsigned {
#undef HANDLE_NODETYPE
};
} // end namespace WebAssemblyISD
} // end namespace WebAssemblyISD
class WebAssemblySubtarget;
class WebAssemblyTargetMachine;
class WebAssemblyTargetLowering final : public TargetLowering {
public:
public:
WebAssemblyTargetLowering(const TargetMachine &TM,
const WebAssemblySubtarget &STI);
private:
private:
/// Keep a pointer to the WebAssemblySubtarget around so that we can make the
/// right decision when generating code for different targets.
const WebAssemblySubtarget *Subtarget;
@ -53,9 +53,9 @@ class WebAssemblyTargetLowering final : public TargetLowering {
EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *MBB) const override;
const char *getTargetNodeName(unsigned Opcode) const override;
std::pair<unsigned, const TargetRegisterClass *> getRegForInlineAsmConstraint(
const TargetRegisterInfo *TRI, StringRef Constraint,
MVT VT) const override;
std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint, MVT VT) const override;
bool isCheapToSpeculateCttz() const override;
bool isCheapToSpeculateCtlz() const override;
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
@ -103,8 +103,8 @@ class WebAssemblyTargetLowering final : public TargetLowering {
namespace WebAssembly {
FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo);
} // end namespace WebAssembly
} // end namespace WebAssembly
} // end namespace llvm
} // end namespace llvm
#endif

View File

@ -77,10 +77,8 @@ void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
.addReg(SrcReg, KillSrc ? RegState::Kill : 0);
}
MachineInstr *
WebAssemblyInstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI,
unsigned OpIdx1,
unsigned OpIdx2) const {
MachineInstr *WebAssemblyInstrInfo::commuteInstructionImpl(
MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const {
// If the operands are stackified, we can't reorder them.
WebAssemblyFunctionInfo &MFI =
*MI.getParent()->getParent()->getInfo<WebAssemblyFunctionInfo>();
@ -165,12 +163,9 @@ unsigned WebAssemblyInstrInfo::removeBranch(MachineBasicBlock &MBB,
return Count;
}
unsigned WebAssemblyInstrInfo::insertBranch(MachineBasicBlock &MBB,
MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded) const {
unsigned WebAssemblyInstrInfo::insertBranch(
MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
assert(!BytesAdded && "code size not handled");
if (Cond.empty()) {

View File

@ -78,30 +78,102 @@ bool WebAssemblyLowerBrUnless::runOnMachineFunction(MachineFunction &MF) {
MachineInstr *Def = MRI.getVRegDef(Cond);
switch (Def->getOpcode()) {
using namespace WebAssembly;
case EQ_I32: Def->setDesc(TII.get(NE_I32)); Inverted = true; break;
case NE_I32: Def->setDesc(TII.get(EQ_I32)); Inverted = true; break;
case GT_S_I32: Def->setDesc(TII.get(LE_S_I32)); Inverted = true; break;
case GE_S_I32: Def->setDesc(TII.get(LT_S_I32)); Inverted = true; break;
case LT_S_I32: Def->setDesc(TII.get(GE_S_I32)); Inverted = true; break;
case LE_S_I32: Def->setDesc(TII.get(GT_S_I32)); Inverted = true; break;
case GT_U_I32: Def->setDesc(TII.get(LE_U_I32)); Inverted = true; break;
case GE_U_I32: Def->setDesc(TII.get(LT_U_I32)); Inverted = true; break;
case LT_U_I32: Def->setDesc(TII.get(GE_U_I32)); Inverted = true; break;
case LE_U_I32: Def->setDesc(TII.get(GT_U_I32)); Inverted = true; break;
case EQ_I64: Def->setDesc(TII.get(NE_I64)); Inverted = true; break;
case NE_I64: Def->setDesc(TII.get(EQ_I64)); Inverted = true; break;
case GT_S_I64: Def->setDesc(TII.get(LE_S_I64)); Inverted = true; break;
case GE_S_I64: Def->setDesc(TII.get(LT_S_I64)); Inverted = true; break;
case LT_S_I64: Def->setDesc(TII.get(GE_S_I64)); Inverted = true; break;
case LE_S_I64: Def->setDesc(TII.get(GT_S_I64)); Inverted = true; break;
case GT_U_I64: Def->setDesc(TII.get(LE_U_I64)); Inverted = true; break;
case GE_U_I64: Def->setDesc(TII.get(LT_U_I64)); Inverted = true; break;
case LT_U_I64: Def->setDesc(TII.get(GE_U_I64)); Inverted = true; break;
case LE_U_I64: Def->setDesc(TII.get(GT_U_I64)); Inverted = true; break;
case EQ_F32: Def->setDesc(TII.get(NE_F32)); Inverted = true; break;
case NE_F32: Def->setDesc(TII.get(EQ_F32)); Inverted = true; break;
case EQ_F64: Def->setDesc(TII.get(NE_F64)); Inverted = true; break;
case NE_F64: Def->setDesc(TII.get(EQ_F64)); Inverted = true; break;
case EQ_I32:
Def->setDesc(TII.get(NE_I32));
Inverted = true;
break;
case NE_I32:
Def->setDesc(TII.get(EQ_I32));
Inverted = true;
break;
case GT_S_I32:
Def->setDesc(TII.get(LE_S_I32));
Inverted = true;
break;
case GE_S_I32:
Def->setDesc(TII.get(LT_S_I32));
Inverted = true;
break;
case LT_S_I32:
Def->setDesc(TII.get(GE_S_I32));
Inverted = true;
break;
case LE_S_I32:
Def->setDesc(TII.get(GT_S_I32));
Inverted = true;
break;
case GT_U_I32:
Def->setDesc(TII.get(LE_U_I32));
Inverted = true;
break;
case GE_U_I32:
Def->setDesc(TII.get(LT_U_I32));
Inverted = true;
break;
case LT_U_I32:
Def->setDesc(TII.get(GE_U_I32));
Inverted = true;
break;
case LE_U_I32:
Def->setDesc(TII.get(GT_U_I32));
Inverted = true;
break;
case EQ_I64:
Def->setDesc(TII.get(NE_I64));
Inverted = true;
break;
case NE_I64:
Def->setDesc(TII.get(EQ_I64));
Inverted = true;
break;
case GT_S_I64:
Def->setDesc(TII.get(LE_S_I64));
Inverted = true;
break;
case GE_S_I64:
Def->setDesc(TII.get(LT_S_I64));
Inverted = true;
break;
case LT_S_I64:
Def->setDesc(TII.get(GE_S_I64));
Inverted = true;
break;
case LE_S_I64:
Def->setDesc(TII.get(GT_S_I64));
Inverted = true;
break;
case GT_U_I64:
Def->setDesc(TII.get(LE_U_I64));
Inverted = true;
break;
case GE_U_I64:
Def->setDesc(TII.get(LT_U_I64));
Inverted = true;
break;
case LT_U_I64:
Def->setDesc(TII.get(GE_U_I64));
Inverted = true;
break;
case LE_U_I64:
Def->setDesc(TII.get(GT_U_I64));
Inverted = true;
break;
case EQ_F32:
Def->setDesc(TII.get(NE_F32));
Inverted = true;
break;
case NE_F32:
Def->setDesc(TII.get(EQ_F32));
Inverted = true;
break;
case EQ_F64:
Def->setDesc(TII.get(NE_F64));
Inverted = true;
break;
case NE_F64:
Def->setDesc(TII.get(EQ_F64));
Inverted = true;
break;
case EQZ_I32: {
// Invert an eqz by replacing it with its operand.
Cond = Def->getOperand(1).getReg();
@ -109,7 +181,8 @@ bool WebAssemblyLowerBrUnless::runOnMachineFunction(MachineFunction &MF) {
Inverted = true;
break;
}
default: break;
default:
break;
}
}

View File

@ -18,15 +18,15 @@
//===----------------------------------------------------------------------===//
#include "WebAssembly.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include "llvm/Pass.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
using namespace llvm;
#define DEBUG_TYPE "wasm-lower-global-dtors"
@ -77,18 +77,20 @@ bool LowerGlobalDtors::runOnModule(Module &M) {
// Collect the contents of @llvm.global_dtors, collated by priority and
// associated symbol.
std::map<uint16_t, MapVector<Constant *, std::vector<Constant *> > > DtorFuncs;
std::map<uint16_t, MapVector<Constant *, std::vector<Constant *>>> DtorFuncs;
for (Value *O : InitList->operands()) {
ConstantStruct *CS = dyn_cast<ConstantStruct>(O);
if (!CS) continue; // Malformed.
if (!CS)
continue; // Malformed.
ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
if (!Priority) continue; // Malformed.
if (!Priority)
continue; // Malformed.
uint16_t PriorityValue = Priority->getLimitedValue(UINT16_MAX);
Constant *DtorFunc = CS->getOperand(1);
if (DtorFunc->isNullValue())
break; // Found a null terminator, skip the rest.
break; // Found a null terminator, skip the rest.
Constant *Associated = CS->getOperand(2);
Associated = cast<Constant>(Associated->stripPointerCastsNoFollowAliases());
@ -101,31 +103,23 @@ bool LowerGlobalDtors::runOnModule(Module &M) {
// extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);
LLVMContext &C = M.getContext();
PointerType *VoidStar = Type::getInt8PtrTy(C);
Type *AtExitFuncArgs[] = { VoidStar };
FunctionType *AtExitFuncTy = FunctionType::get(
Type::getVoidTy(C),
AtExitFuncArgs,
/*isVarArg=*/false);
Type *AtExitFuncArgs[] = {VoidStar};
FunctionType *AtExitFuncTy =
FunctionType::get(Type::getVoidTy(C), AtExitFuncArgs,
/*isVarArg=*/false);
Type *AtExitArgs[] = {
PointerType::get(AtExitFuncTy, 0),
VoidStar,
VoidStar
};
FunctionType *AtExitTy = FunctionType::get(
Type::getInt32Ty(C),
AtExitArgs,
/*isVarArg=*/false);
Type *AtExitArgs[] = {PointerType::get(AtExitFuncTy, 0), VoidStar, VoidStar};
FunctionType *AtExitTy = FunctionType::get(Type::getInt32Ty(C), AtExitArgs,
/*isVarArg=*/false);
Constant *AtExit = M.getOrInsertFunction("__cxa_atexit", AtExitTy);
// Declare __dso_local.
Constant *DsoHandle = M.getNamedValue("__dso_handle");
if (!DsoHandle) {
Type *DsoHandleTy = Type::getInt8Ty(C);
GlobalVariable *Handle =
new GlobalVariable(M, DsoHandleTy, /*isConstant=*/true,
GlobalVariable::ExternalWeakLinkage,
nullptr, "__dso_handle");
GlobalVariable *Handle = new GlobalVariable(
M, DsoHandleTy, /*isConstant=*/true,
GlobalVariable::ExternalWeakLinkage, nullptr, "__dso_handle");
Handle->setVisibility(GlobalVariable::HiddenVisibility);
DsoHandle = Handle;
}
@ -139,13 +133,13 @@ bool LowerGlobalDtors::runOnModule(Module &M) {
Constant *Associated = AssociatedAndMore.first;
Function *CallDtors = Function::Create(
AtExitFuncTy, Function::PrivateLinkage,
"call_dtors" +
(Priority != UINT16_MAX ?
(Twine(".") + Twine(Priority)) : Twine()) +
(!Associated->isNullValue() ?
(Twine(".") + Associated->getName()) : Twine()),
&M);
AtExitFuncTy, Function::PrivateLinkage,
"call_dtors" +
(Priority != UINT16_MAX ? (Twine(".") + Twine(Priority))
: Twine()) +
(!Associated->isNullValue() ? (Twine(".") + Associated->getName())
: Twine()),
&M);
BasicBlock *BB = BasicBlock::Create(C, "body", CallDtors);
for (auto Dtor : AssociatedAndMore.second)
@ -155,29 +149,29 @@ bool LowerGlobalDtors::runOnModule(Module &M) {
FunctionType *VoidVoid = FunctionType::get(Type::getVoidTy(C),
/*isVarArg=*/false);
Function *RegisterCallDtors = Function::Create(
VoidVoid, Function::PrivateLinkage,
"register_call_dtors" +
(Priority != UINT16_MAX ?
(Twine(".") + Twine(Priority)) : Twine()) +
(!Associated->isNullValue() ?
(Twine(".") + Associated->getName()) : Twine()),
&M);
VoidVoid, Function::PrivateLinkage,
"register_call_dtors" +
(Priority != UINT16_MAX ? (Twine(".") + Twine(Priority))
: Twine()) +
(!Associated->isNullValue() ? (Twine(".") + Associated->getName())
: Twine()),
&M);
BasicBlock *EntryBB = BasicBlock::Create(C, "entry", RegisterCallDtors);
BasicBlock *FailBB = BasicBlock::Create(C, "fail", RegisterCallDtors);
BasicBlock *RetBB = BasicBlock::Create(C, "return", RegisterCallDtors);
Value *Null = ConstantPointerNull::get(VoidStar);
Value *Args[] = { CallDtors, Null, DsoHandle };
Value *Args[] = {CallDtors, Null, DsoHandle};
Value *Res = CallInst::Create(AtExit, Args, "call", EntryBB);
Value *Cmp = new ICmpInst(*EntryBB, ICmpInst::ICMP_NE, Res,
Constant::getNullValue(Res->getType()));
BranchInst::Create(FailBB, RetBB, Cmp, EntryBB);
// If `__cxa_atexit` hits out-of-memory, trap, so that we don't misbehave.
// This should be very rare, because if the process is running out of memory
// before main has even started, something is wrong.
CallInst::Create(Intrinsic::getDeclaration(&M, Intrinsic::trap),
"", FailBB);
// This should be very rare, because if the process is running out of
// memory before main has even started, something is wrong.
CallInst::Create(Intrinsic::getDeclaration(&M, Intrinsic::trap), "",
FailBB);
new UnreachableInst(C, FailBB);
ReturnInst::Create(C, RetBB);

View File

@ -32,11 +32,11 @@ using namespace llvm;
// This disables the removal of registers when lowering into MC, as required
// by some current tests.
static cl::opt<bool> WasmKeepRegisters(
"wasm-keep-registers", cl::Hidden,
cl::desc("WebAssembly: output stack registers in"
" instruction output for test purposes only."),
cl::init(false));
static cl::opt<bool>
WasmKeepRegisters("wasm-keep-registers", cl::Hidden,
cl::desc("WebAssembly: output stack registers in"
" instruction output for test purposes only."),
cl::init(false));
static unsigned regInstructionToStackInstruction(unsigned OpCode);
static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI);
@ -54,10 +54,9 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
SmallVector<wasm::ValType, 4> Returns;
SmallVector<wasm::ValType, 4> Params;
wasm::ValType iPTR =
MF.getSubtarget<WebAssemblySubtarget>().hasAddr64() ?
wasm::ValType::I64 :
wasm::ValType::I32;
wasm::ValType iPTR = MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
? wasm::ValType::I64
: wasm::ValType::I32;
SmallVector<MVT, 4> ResultMVTs;
ComputeLegalValueVTs(CurrentFunc, TM, FuncTy->getReturnType(), ResultMVTs);
@ -122,9 +121,9 @@ MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(MCSymbol *Sym,
bool IsFunc,
bool IsGlob) const {
MCSymbolRefExpr::VariantKind VK =
IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION :
IsGlob ? MCSymbolRefExpr::VK_WebAssembly_GLOBAL
: MCSymbolRefExpr::VK_None;
IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION
: IsGlob ? MCSymbolRefExpr::VK_WebAssembly_GLOBAL
: MCSymbolRefExpr::VK_None;
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx);
@ -238,7 +237,8 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
// variable or a function.
assert((MO.getTargetFlags() & ~WebAssemblyII::MO_SYMBOL_MASK) == 0 &&
"WebAssembly uses only symbol flags on ExternalSymbols");
MCOp = LowerSymbolOperand(GetExternalSymbolSymbol(MO), /*Offset=*/0,
MCOp = LowerSymbolOperand(
GetExternalSymbolSymbol(MO), /*Offset=*/0,
(MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_FUNCTION) != 0,
(MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_GLOBAL) != 0);
break;
@ -295,7 +295,7 @@ static unsigned regInstructionToStackInstruction(unsigned OpCode) {
switch (OpCode) {
default:
llvm_unreachable(
"unknown WebAssembly instruction in WebAssemblyMCInstLower pass");
"unknown WebAssembly instruction in WebAssemblyMCInstLower pass");
#include "WebAssemblyGenStackifier.inc"
}
}

View File

@ -33,8 +33,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyMCInstLower {
MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
MCOperand LowerSymbolOperand(MCSymbol *Sym, int64_t Offset,
bool IsFunc, bool IsGlob) const;
MCOperand LowerSymbolOperand(MCSymbol *Sym, int64_t Offset, bool IsFunc,
bool IsGlob) const;
public:
WebAssemblyMCInstLower(MCContext &ctx, WebAssemblyAsmPrinter &printer)

View File

@ -50,7 +50,7 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
// overaligned values on the user stack.
unsigned BasePtrVreg = -1U;
public:
public:
explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {}
~WebAssemblyFunctionInfo() override;
@ -60,7 +60,10 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
void addResult(MVT VT) { Results.push_back(VT); }
const std::vector<MVT> &getResults() const { return Results; }
void clearParamsAndResults() { Params.clear(); Results.clear(); }
void clearParamsAndResults() {
Params.clear();
Results.clear();
}
void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); }
void setLocal(size_t i, MVT VT) { Locals[i] = VT; }
@ -115,8 +118,8 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
}
};
void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM,
Type *Ty, SmallVectorImpl<MVT> &ValueVTs);
void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,
SmallVectorImpl<MVT> &ValueVTs);
void ComputeSignatureVTs(const Function &F, const TargetMachine &TM,
SmallVectorImpl<MVT> &Params,

View File

@ -65,7 +65,8 @@ FunctionPass *llvm::createWebAssemblyOptimizeLiveIntervals() {
return new WebAssemblyOptimizeLiveIntervals();
}
bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(MachineFunction &MF) {
bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(
MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "********** Optimize LiveIntervals **********\n"
"********** Function: "
<< MF.getName() << '\n');
@ -76,11 +77,10 @@ bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(MachineFunction &MF)
// We don't preserve SSA form.
MRI.leaveSSA();
assert(MRI.tracksLiveness() &&
"OptimizeLiveIntervals expects liveness");
assert(MRI.tracksLiveness() && "OptimizeLiveIntervals expects liveness");
// Split multiple-VN LiveIntervals into multiple LiveIntervals.
SmallVector<LiveInterval*, 4> SplitLIs;
SmallVector<LiveInterval *, 4> SplitLIs;
for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) {
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
if (MRI.reg_nodbg_empty(Reg))
@ -94,7 +94,7 @@ bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(MachineFunction &MF)
// instructions to satisfy LiveIntervals' requirement that all uses be
// dominated by defs. Now that LiveIntervals has computed which of these
// defs are actually needed and which are dead, remove the dead ones.
for (auto MII = MF.begin()->begin(), MIE = MF.begin()->end(); MII != MIE; ) {
for (auto MII = MF.begin()->begin(), MIE = MF.begin()->end(); MII != MIE;) {
MachineInstr *MI = &*MII++;
if (MI->isImplicitDef() && MI->getOperand(0).isDead()) {
LiveInterval &LI = LIS.getInterval(MI->getOperand(0).getReg());

View File

@ -70,7 +70,8 @@ static bool HasArgumentDef(unsigned Reg, const MachineRegisterInfo &MRI) {
return false;
}
bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(MachineFunction &MF) {
bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(
MachineFunction &MF) {
LLVM_DEBUG({
dbgs() << "********** Prepare For LiveIntervals **********\n"
<< "********** Function: " << MF.getName() << '\n';
@ -112,7 +113,7 @@ bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(MachineFunction &M
// Move ARGUMENT_* instructions to the top of the entry block, so that their
// liveness reflects the fact that these really are live-in values.
for (auto MII = Entry.begin(), MIE = Entry.end(); MII != MIE; ) {
for (auto MII = Entry.begin(), MIE = Entry.end(); MII != MIE;) {
MachineInstr &MI = *MII++;
if (WebAssembly::isArgument(MI)) {
MI.removeFromParent();

View File

@ -100,8 +100,7 @@ static void ConvertImplicitDefToConstZero(MachineInstr *MI,
MachineFunction &MF) {
assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
const auto *RegClass =
MRI.getRegClass(MI->getOperand(0).getReg());
const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg());
if (RegClass == &WebAssembly::I32RegClass) {
MI->setDesc(TII->get(WebAssembly::CONST_I32));
MI->addOperand(MachineOperand::CreateImm(0));
@ -187,14 +186,22 @@ static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read,
}
} else if (MI.hasOrderedMemoryRef()) {
switch (MI.getOpcode()) {
case WebAssembly::DIV_S_I32: case WebAssembly::DIV_S_I64:
case WebAssembly::REM_S_I32: case WebAssembly::REM_S_I64:
case WebAssembly::DIV_U_I32: case WebAssembly::DIV_U_I64:
case WebAssembly::REM_U_I32: case WebAssembly::REM_U_I64:
case WebAssembly::I32_TRUNC_S_F32: case WebAssembly::I64_TRUNC_S_F32:
case WebAssembly::I32_TRUNC_S_F64: case WebAssembly::I64_TRUNC_S_F64:
case WebAssembly::I32_TRUNC_U_F32: case WebAssembly::I64_TRUNC_U_F32:
case WebAssembly::I32_TRUNC_U_F64: case WebAssembly::I64_TRUNC_U_F64:
case WebAssembly::DIV_S_I32:
case WebAssembly::DIV_S_I64:
case WebAssembly::REM_S_I32:
case WebAssembly::REM_S_I64:
case WebAssembly::DIV_U_I32:
case WebAssembly::DIV_U_I64:
case WebAssembly::REM_U_I32:
case WebAssembly::REM_U_I64:
case WebAssembly::I32_TRUNC_S_F32:
case WebAssembly::I64_TRUNC_S_F32:
case WebAssembly::I32_TRUNC_S_F64:
case WebAssembly::I64_TRUNC_S_F64:
case WebAssembly::I32_TRUNC_U_F32:
case WebAssembly::I64_TRUNC_U_F32:
case WebAssembly::I32_TRUNC_U_F64:
case WebAssembly::I64_TRUNC_U_F64:
// These instruction have hasUnmodeledSideEffects() returning true
// because they trap on overflow and invalid so they can't be arbitrarily
// moved, however hasOrderedMemoryRef() interprets this plus their lack
@ -214,14 +221,22 @@ static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read,
// Check for side effects.
if (MI.hasUnmodeledSideEffects()) {
switch (MI.getOpcode()) {
case WebAssembly::DIV_S_I32: case WebAssembly::DIV_S_I64:
case WebAssembly::REM_S_I32: case WebAssembly::REM_S_I64:
case WebAssembly::DIV_U_I32: case WebAssembly::DIV_U_I64:
case WebAssembly::REM_U_I32: case WebAssembly::REM_U_I64:
case WebAssembly::I32_TRUNC_S_F32: case WebAssembly::I64_TRUNC_S_F32:
case WebAssembly::I32_TRUNC_S_F64: case WebAssembly::I64_TRUNC_S_F64:
case WebAssembly::I32_TRUNC_U_F32: case WebAssembly::I64_TRUNC_U_F32:
case WebAssembly::I32_TRUNC_U_F64: case WebAssembly::I64_TRUNC_U_F64:
case WebAssembly::DIV_S_I32:
case WebAssembly::DIV_S_I64:
case WebAssembly::REM_S_I32:
case WebAssembly::REM_S_I64:
case WebAssembly::DIV_U_I32:
case WebAssembly::DIV_U_I64:
case WebAssembly::REM_U_I32:
case WebAssembly::REM_U_I64:
case WebAssembly::I32_TRUNC_S_F32:
case WebAssembly::I64_TRUNC_S_F32:
case WebAssembly::I32_TRUNC_S_F64:
case WebAssembly::I64_TRUNC_S_F64:
case WebAssembly::I32_TRUNC_U_F32:
case WebAssembly::I64_TRUNC_U_F32:
case WebAssembly::I32_TRUNC_U_F64:
case WebAssembly::I64_TRUNC_U_F64:
// These instructions have hasUnmodeledSideEffects() returning true
// because they trap on overflow and invalid so they can't be arbitrarily
// moved, however in the specific case of register stackifying, it is safe
@ -251,8 +266,7 @@ static bool ShouldRematerialize(const MachineInstr &Def, AliasAnalysis &AA,
// LiveIntervals to handle complex cases.
static MachineInstr *GetVRegDef(unsigned Reg, const MachineInstr *Insert,
const MachineRegisterInfo &MRI,
const LiveIntervals &LIS)
{
const LiveIntervals &LIS) {
// Most registers are in SSA form here so we try a quick MRI query first.
if (MachineInstr *Def = MRI.getUniqueVRegDef(Reg))
return Def;
@ -268,17 +282,16 @@ static MachineInstr *GetVRegDef(unsigned Reg, const MachineInstr *Insert,
// Test whether Reg, as defined at Def, has exactly one use. This is a
// generalization of MachineRegisterInfo::hasOneUse that uses LiveIntervals
// to handle complex cases.
static bool HasOneUse(unsigned Reg, MachineInstr *Def,
MachineRegisterInfo &MRI, MachineDominatorTree &MDT,
LiveIntervals &LIS) {
static bool HasOneUse(unsigned Reg, MachineInstr *Def, MachineRegisterInfo &MRI,
MachineDominatorTree &MDT, LiveIntervals &LIS) {
// Most registers are in SSA form here so we try a quick MRI query first.
if (MRI.hasOneUse(Reg))
return true;
bool HasOne = false;
const LiveInterval &LI = LIS.getInterval(Reg);
const VNInfo *DefVNI = LI.getVNInfoAt(
LIS.getInstructionIndex(*Def).getRegSlot());
const VNInfo *DefVNI =
LI.getVNInfoAt(LIS.getInstructionIndex(*Def).getRegSlot());
assert(DefVNI);
for (auto &I : MRI.use_nodbg_operands(Reg)) {
const auto &Result = LI.Query(LIS.getInstructionIndex(*I.getParent()));
@ -447,16 +460,15 @@ static unsigned GetTeeOpcode(const TargetRegisterClass *RC) {
// Shrink LI to its uses, cleaning up LI.
static void ShrinkToUses(LiveInterval &LI, LiveIntervals &LIS) {
if (LIS.shrinkToUses(&LI)) {
SmallVector<LiveInterval*, 4> SplitLIs;
SmallVector<LiveInterval *, 4> SplitLIs;
LIS.splitSeparateComponents(LI, SplitLIs);
}
}
/// A single-use def in the same block with no intervening memory or register
/// dependencies; move the def down and nest it with the current instruction.
static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand& Op,
MachineInstr *Def,
MachineBasicBlock &MBB,
static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
MachineInstr *Def, MachineBasicBlock &MBB,
MachineInstr *Insert, LiveIntervals &LIS,
WebAssemblyFunctionInfo &MFI,
MachineRegisterInfo &MRI) {

View File

@ -22,9 +22,9 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;

View File

@ -54,8 +54,8 @@ private:
char WebAssemblyReplacePhysRegs::ID = 0;
INITIALIZE_PASS(WebAssemblyReplacePhysRegs, DEBUG_TYPE,
"Replace physical registers with virtual registers",
false, false)
"Replace physical registers with virtual registers", false,
false)
FunctionPass *llvm::createWebAssemblyReplacePhysRegs() {
return new WebAssemblyReplacePhysRegs();
@ -86,7 +86,7 @@ bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) {
// Replace explicit uses of the physical register with a virtual register.
const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg);
unsigned VReg = WebAssembly::NoRegister;
for (auto I = MRI.reg_begin(PReg), E = MRI.reg_end(); I != E; ) {
for (auto I = MRI.reg_begin(PReg), E = MRI.reg_end(); I != E;) {
MachineOperand &MO = *I++;
if (!MO.isImplicit()) {
if (VReg == WebAssembly::NoRegister)

View File

@ -88,7 +88,6 @@ enum RuntimeLibcallSignature {
unsupported
};
struct RuntimeLibcallSignatureTable {
std::vector<RuntimeLibcallSignature> Table;
@ -486,8 +485,6 @@ struct StaticLibcallNameMap {
} // end anonymous namespace
void llvm::GetSignature(const WebAssemblySubtarget &Subtarget,
RTLIB::Libcall LC, SmallVectorImpl<wasm::ValType> &Rets,
SmallVectorImpl<wasm::ValType> &Params) {
@ -497,7 +494,7 @@ void llvm::GetSignature(const WebAssemblySubtarget &Subtarget,
wasm::ValType iPTR =
Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32;
auto& Table = RuntimeLibcallSignatures->Table;
auto &Table = RuntimeLibcallSignatures->Table;
switch (Table[LC]) {
case func:
break;
@ -837,7 +834,7 @@ static ManagedStatic<StaticLibcallNameMap> LibcallNameMap;
void llvm::GetSignature(const WebAssemblySubtarget &Subtarget, const char *Name,
SmallVectorImpl<wasm::ValType> &Rets,
SmallVectorImpl<wasm::ValType> &Params) {
auto& Map = LibcallNameMap->Map;
auto &Map = LibcallNameMap->Map;
auto val = Map.find(Name);
assert(val != Map.end() && "unexpected runtime library name");
return GetSignature(Subtarget, val->second, Rets, Params);

View File

@ -60,8 +60,7 @@ static void RewriteP2Align(MachineInstr &MI, unsigned OperandNo) {
assert(MI.hasOneMemOperand() &&
"Load and store instructions have exactly one mem operand");
assert((*MI.memoperands_begin())->getSize() ==
(UINT64_C(1)
<< WebAssembly::GetDefaultP2Align(MI.getOpcode())) &&
(UINT64_C(1) << WebAssembly::GetDefaultP2Align(MI.getOpcode())) &&
"Default p2align value should be natural");
assert(MI.getDesc().OpInfo[OperandNo].OperandType ==
WebAssembly::OPERAND_P2ALIGN &&
@ -69,8 +68,8 @@ static void RewriteP2Align(MachineInstr &MI, unsigned OperandNo) {
uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment());
// WebAssembly does not currently support supernatural alignment.
P2Align = std::min(
P2Align, uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode())));
P2Align = std::min(P2Align,
uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode())));
MI.getOperand(OperandNo).setImm(P2Align);
}

View File

@ -91,7 +91,8 @@ static bool ReplaceDominatedUses(MachineBasicBlock &MBB, MachineInstr &MI,
SmallVector<SlotIndex, 4> Indices;
for (auto I = MRI.use_nodbg_begin(FromReg), E = MRI.use_nodbg_end(); I != E;) {
for (auto I = MRI.use_nodbg_begin(FromReg), E = MRI.use_nodbg_end();
I != E;) {
MachineOperand &O = *I++;
MachineInstr *Where = O.getParent();
@ -132,9 +133,9 @@ static bool ReplaceDominatedUses(MachineBasicBlock &MBB, MachineInstr &MI,
// If we replaced all dominated uses, FromReg is now killed at MI.
if (!FromLI->liveAt(FromIdx.getDeadSlot()))
MI.addRegisterKilled(FromReg,
MBB.getParent()->getSubtarget<WebAssemblySubtarget>()
.getRegisterInfo());
MI.addRegisterKilled(FromReg, MBB.getParent()
->getSubtarget<WebAssemblySubtarget>()
.getRegisterInfo());
}
return Changed;
@ -142,8 +143,7 @@ static bool ReplaceDominatedUses(MachineBasicBlock &MBB, MachineInstr &MI,
static bool optimizeCall(MachineBasicBlock &MBB, MachineInstr &MI,
const MachineRegisterInfo &MRI,
MachineDominatorTree &MDT,
LiveIntervals &LIS,
MachineDominatorTree &MDT, LiveIntervals &LIS,
const WebAssemblyTargetLowering &TLI,
const TargetLibraryInfo &LibInfo) {
MachineOperand &Op1 = MI.getOperand(1);

View File

@ -150,7 +150,7 @@ class StripThreadLocal final : public ModulePass {
// pass just converts all GlobalVariables to NotThreadLocal
static char ID;
public:
public:
StripThreadLocal() : ModulePass(ID) {}
bool runOnModule(Module &M) override {
for (auto &GV : M.globals())

View File

@ -23,28 +23,22 @@ using namespace object;
namespace {
static const EnumEntry<unsigned> WasmSymbolTypes[] = {
#define ENUM_ENTRY(X) { #X, wasm::WASM_SYMBOL_TYPE_##X }
ENUM_ENTRY(FUNCTION),
ENUM_ENTRY(DATA),
ENUM_ENTRY(GLOBAL),
ENUM_ENTRY(SECTION),
#define ENUM_ENTRY(X) \
{ #X, wasm::WASM_SYMBOL_TYPE_##X }
ENUM_ENTRY(FUNCTION),
ENUM_ENTRY(DATA),
ENUM_ENTRY(GLOBAL),
ENUM_ENTRY(SECTION),
#undef ENUM_ENTRY
};
static const EnumEntry<uint32_t> WasmSectionTypes[] = {
#define ENUM_ENTRY(X) { #X, wasm::WASM_SEC_##X }
ENUM_ENTRY(CUSTOM),
ENUM_ENTRY(TYPE),
ENUM_ENTRY(IMPORT),
ENUM_ENTRY(FUNCTION),
ENUM_ENTRY(TABLE),
ENUM_ENTRY(MEMORY),
ENUM_ENTRY(GLOBAL),
ENUM_ENTRY(EXPORT),
ENUM_ENTRY(START),
ENUM_ENTRY(ELEM),
ENUM_ENTRY(CODE),
ENUM_ENTRY(DATA),
#define ENUM_ENTRY(X) \
{ #X, wasm::WASM_SEC_##X }
ENUM_ENTRY(CUSTOM), ENUM_ENTRY(TYPE), ENUM_ENTRY(IMPORT),
ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE), ENUM_ENTRY(MEMORY),
ENUM_ENTRY(GLOBAL), ENUM_ENTRY(EXPORT), ENUM_ENTRY(START),
ENUM_ENTRY(ELEM), ENUM_ENTRY(CODE), ENUM_ENTRY(DATA),
#undef ENUM_ENTRY
};
@ -108,7 +102,7 @@ void WasmDumper::printRelocation(const SectionRef &Section,
if (HasAddend)
W.printNumber("Addend", WasmReloc.Addend);
} else {
raw_ostream& OS = W.startLine();
raw_ostream &OS = W.startLine();
OS << W.hex(Reloc.getOffset()) << " " << RelocTypeName << " ";
if (!SymName.empty())
OS << SymName;
@ -169,7 +163,7 @@ void WasmDumper::printSections() {
const wasm::WasmLinkingData &LinkingData = Obj->linkingData();
if (!LinkingData.InitFunctions.empty()) {
ListScope Group(W, "InitFunctions");
for (const wasm::WasmInitFunc &F: LinkingData.InitFunctions)
for (const wasm::WasmInitFunc &F : LinkingData.InitFunctions)
W.startLine() << F.Symbol << " (priority=" << F.Priority << ")\n";
}
}
@ -177,7 +171,7 @@ void WasmDumper::printSections() {
case wasm::WASM_SEC_DATA: {
ListScope Group(W, "Segments");
for (const WasmSegment &Segment : Obj->dataSegments()) {
const wasm::WasmDataSegment& Seg = Segment.Data;
const wasm::WasmDataSegment &Seg = Segment.Data;
DictScope Group(W, "Segment");
if (!Seg.Name.empty())
W.printString("Name", Seg.Name);
@ -219,7 +213,7 @@ void WasmDumper::printSymbol(const SymbolRef &Sym) {
W.printHex("Flags", Symbol.Info.Flags);
}
}
} // namespace
namespace llvm {

View File

@ -49,11 +49,13 @@ static WasmYAML::Limits make_limits(const wasm::WasmLimits &Limits) {
return L;
}
std::unique_ptr<WasmYAML::CustomSection> WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
std::unique_ptr<WasmYAML::CustomSection>
WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
std::unique_ptr<WasmYAML::CustomSection> CustomSec;
if (WasmSec.Name == "name") {
std::unique_ptr<WasmYAML::NameSection> NameSec = make_unique<WasmYAML::NameSection>();
for (const llvm::wasm::WasmFunctionName &Func: Obj.debugNames()) {
std::unique_ptr<WasmYAML::NameSection> NameSec =
make_unique<WasmYAML::NameSection>();
for (const llvm::wasm::WasmFunctionName &Func : Obj.debugNames()) {
WasmYAML::NameEntry NameEntry;
NameEntry.Name = Func.Name;
NameEntry.Index = Func.Index;
@ -61,7 +63,8 @@ std::unique_ptr<WasmYAML::CustomSection> WasmDumper::dumpCustomSection(const Was
}
CustomSec = std::move(NameSec);
} else if (WasmSec.Name == "linking") {
std::unique_ptr<WasmYAML::LinkingSection> LinkingSec = make_unique<WasmYAML::LinkingSection>();
std::unique_ptr<WasmYAML::LinkingSection> LinkingSec =
make_unique<WasmYAML::LinkingSection>();
LinkingSec->Version = Obj.linkingData().Version;
ArrayRef<StringRef> Comdats = Obj.linkingData().Comdats;
@ -70,7 +73,7 @@ std::unique_ptr<WasmYAML::CustomSection> WasmDumper::dumpCustomSection(const Was
for (auto &Func : Obj.functions()) {
if (Func.Comdat != UINT32_MAX) {
LinkingSec->Comdats[Func.Comdat].Entries.emplace_back(
WasmYAML::ComdatEntry{wasm::WASM_COMDAT_FUNCTION, Func.Index});
WasmYAML::ComdatEntry{wasm::WASM_COMDAT_FUNCTION, Func.Index});
}
}
@ -290,7 +293,7 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
llvm_unreachable("Unknown section type");
break;
}
for (const wasm::WasmRelocation &Reloc: WasmSec.Relocations) {
for (const wasm::WasmRelocation &Reloc : WasmSec.Relocations) {
WasmYAML::Relocation R;
R.Type = Reloc.Type;
R.Index = Reloc.Index;

View File

@ -127,12 +127,11 @@ public:
OutString.clear();
}
raw_ostream& GetStream() {
return StringStream;
}
raw_ostream &GetStream() { return StringStream; }
};
int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section) {
int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::LinkingSection &Section) {
writeStringRef(Section.Name, OS);
encodeULEB128(Section.Version, OS);
@ -218,7 +217,8 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &S
return 0;
}
int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section) {
int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::NameSection &Section) {
writeStringRef(Section.Name, OS);
if (Section.FunctionNames.size()) {
writeUint8(OS, wasm::WASM_NAMES_FUNCTION);
@ -296,7 +296,7 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
writeLimits(Import.Memory, OS);
break;
case wasm::WASM_EXTERNAL_TABLE:
writeUint8(OS,Import.TableImport.ElemType);
writeUint8(OS, Import.TableImport.ElemType);
writeLimits(Import.TableImport.TableLimits, OS);
break;
default:
@ -428,47 +428,46 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
uint32_t SectionIndex) {
switch (Sec.Type) {
case wasm::WASM_SEC_CODE:
writeStringRef("reloc.CODE", OS);
break;
case wasm::WASM_SEC_DATA:
writeStringRef("reloc.DATA", OS);
break;
case wasm::WASM_SEC_CUSTOM: {
auto CustomSection = dyn_cast<WasmYAML::CustomSection>(&Sec);
if (!CustomSection->Name.startswith(".debug_")) {
llvm_unreachable("not yet implemented (only for debug sections)");
return 1;
}
writeStringRef(("reloc." + CustomSection->Name).str(), OS);
break;
}
default:
llvm_unreachable("not yet implemented");
case wasm::WASM_SEC_CODE:
writeStringRef("reloc.CODE", OS);
break;
case wasm::WASM_SEC_DATA:
writeStringRef("reloc.DATA", OS);
break;
case wasm::WASM_SEC_CUSTOM: {
auto CustomSection = dyn_cast<WasmYAML::CustomSection>(&Sec);
if (!CustomSection->Name.startswith(".debug_")) {
llvm_unreachable("not yet implemented (only for debug sections)");
return 1;
}
writeStringRef(("reloc." + CustomSection->Name).str(), OS);
break;
}
default:
llvm_unreachable("not yet implemented");
return 1;
}
encodeULEB128(SectionIndex, OS);
encodeULEB128(Sec.Relocations.size(), OS);
for (auto Reloc: Sec.Relocations) {
for (auto Reloc : Sec.Relocations) {
writeUint8(OS, Reloc.Type);
encodeULEB128(Reloc.Offset, OS);
encodeULEB128(Reloc.Index, OS);
switch (Reloc.Type) {
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
encodeULEB128(Reloc.Addend, OS);
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
encodeULEB128(Reloc.Addend, OS);
}
}
return 0;
}
int WasmWriter::writeWasm(raw_ostream &OS) {
// Write headers
OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic));