Summary: It does not currently make sense to use WebAssembly features in some functions but not others, so this CL adds an IR pass that takes the union of all used feature sets and applies it to each function in the module. This allows us to prevent atomics from being lowered away if some function has opted in to using them. When atomics is not enabled anywhere, we detect whether there exists any atomic operations or thread local storage that would be stripped and disallow linking with objects that contain atomics if and only if atomics or tls are stripped. When atomics is enabled, mark it as used but do not require it of other objects in the link. These changes allow libraries that do not use atomics to be built once and linked into both single-threaded and multithreaded binaries. Reviewers: aheejin, sbc100, dschuff Subscribers: jgravelle-google, hiraditya, sunfish, jfb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59625 llvm-svn: 357226
82 lines
3.0 KiB
C++
82 lines
3.0 KiB
C++
// WebAssemblyAsmPrinter.h - WebAssembly implementation of AsmPrinter-*- C++ -*-
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYASMPRINTER_H
|
|
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYASMPRINTER_H
|
|
|
|
#include "WebAssemblyMachineFunctionInfo.h"
|
|
#include "WebAssemblySubtarget.h"
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
|
#include "llvm/MC/MCStreamer.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
namespace llvm {
|
|
class MCSymbol;
|
|
class WebAssemblyTargetStreamer;
|
|
class WebAssemblyMCInstLower;
|
|
|
|
class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter {
|
|
const WebAssemblySubtarget *Subtarget;
|
|
const MachineRegisterInfo *MRI;
|
|
WebAssemblyFunctionInfo *MFI;
|
|
// TODO: Do the uniquing of Signatures here instead of ObjectFileWriter?
|
|
std::vector<std::unique_ptr<wasm::WasmSignature>> Signatures;
|
|
|
|
public:
|
|
explicit WebAssemblyAsmPrinter(TargetMachine &TM,
|
|
std::unique_ptr<MCStreamer> Streamer)
|
|
: AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr), MRI(nullptr),
|
|
MFI(nullptr) {}
|
|
|
|
StringRef getPassName() const override {
|
|
return "WebAssembly Assembly Printer";
|
|
}
|
|
|
|
const WebAssemblySubtarget &getSubtarget() const { return *Subtarget; }
|
|
void addSignature(std::unique_ptr<wasm::WasmSignature> &&Sig) {
|
|
Signatures.push_back(std::move(Sig));
|
|
}
|
|
|
|
//===------------------------------------------------------------------===//
|
|
// MachineFunctionPass Implementation.
|
|
//===------------------------------------------------------------------===//
|
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override {
|
|
Subtarget = &MF.getSubtarget<WebAssemblySubtarget>();
|
|
MRI = &MF.getRegInfo();
|
|
MFI = MF.getInfo<WebAssemblyFunctionInfo>();
|
|
return AsmPrinter::runOnMachineFunction(MF);
|
|
}
|
|
|
|
//===------------------------------------------------------------------===//
|
|
// AsmPrinter Implementation.
|
|
//===------------------------------------------------------------------===//
|
|
|
|
void EmitEndOfAsmFile(Module &M) override;
|
|
void EmitProducerInfo(Module &M);
|
|
void EmitTargetFeatures(Module &M);
|
|
void EmitJumpTableInfo() override;
|
|
void EmitConstantPool() override;
|
|
void EmitFunctionBodyStart() override;
|
|
void EmitInstruction(const MachineInstr *MI) override;
|
|
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
|
unsigned AsmVariant, const char *ExtraCode,
|
|
raw_ostream &OS) override;
|
|
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
|
unsigned AsmVariant, const char *ExtraCode,
|
|
raw_ostream &OS) override;
|
|
|
|
MVT getRegType(unsigned RegNo) const;
|
|
std::string regToString(const MachineOperand &MO);
|
|
WebAssemblyTargetStreamer *getTargetStreamer();
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|