51#define DEBUG_TYPE "asm-printer"
64 if (
TRI->isTypeLegalForClass(*TRC,
T))
66 LLVM_DEBUG(
errs() <<
"Unknown type for register number: " << RegNo);
74 "Unlowered physical register encountered during assembly printing");
76 unsigned WAReg = MFI->
getWAReg(RegNo);
78 return '$' + utostr(WAReg);
103 if (
Name.front() ==
'"' &&
Name.back() ==
'"')
105 return Name.startswith(
"__invoke_");
134 std::string Ret =
"invoke_";
152 bool &InvokeDetected) {
156 InvokeDetected =
true;
159 "Emscripten EH/SjLj does not support multivalue returns: " +
160 std::string(
F->getName()) +
": " +
164 WasmSym = cast<MCSymbolWasm>(
214 if (WasmSym->getType())
223 if (
Name ==
"__stack_pointer" ||
Name ==
"__tls_base" ||
224 Name ==
"__memory_base" ||
Name ==
"__table_base" ||
225 Name ==
"__tls_size" ||
Name ==
"__tls_align") {
227 Name ==
"__stack_pointer" ||
Name ==
"__tls_base";
236 if (
Name.startswith(
"GCC_except_table")) {
243 if (
Name ==
"__cpp_exception" ||
Name ==
"__c_longjmp") {
251 WasmSym->setWeak(
true);
252 WasmSym->setExternal(
true);
266 auto Signature = std::make_unique<wasm::WasmSignature>(std::move(Returns),
268 WasmSym->setSignature(Signature.get());
275 std::optional<wasm::WasmSymbolType> WasmTy = Sym->
getType();
295 if (signaturesEmitted)
297 signaturesEmitted =
true;
306 if (WasmSym->isFunction()) {
317 auto Sym = cast<MCSymbolWasm>(It.getValue());
318 if (!Sym->isDefined())
323 for (
const auto &
F : M) {
339 bool InvokeDetected =
false;
342 Signature.get(), InvokeDetected);
348 if (InvokeDetected && !InvokeSymbols.
insert(Sym).second)
352 if (!Sym->getSignature()) {
353 Sym->setSignature(Signature.get());
362 if (
F.hasFnAttribute(
"wasm-import-module")) {
364 F.getFnAttribute(
"wasm-import-module").getValueAsString();
365 Sym->setImportModule(storeName(
Name));
368 if (
F.hasFnAttribute(
"wasm-import-name")) {
374 :
F.getFnAttribute(
"wasm-import-name").getValueAsString();
375 Sym->setImportName(storeName(
Name));
379 if (
F.hasFnAttribute(
"wasm-export-name")) {
380 auto *Sym = cast<MCSymbolWasm>(
getSymbol(&
F));
381 StringRef Name =
F.getFnAttribute(
"wasm-export-name").getValueAsString();
382 Sym->setExportName(storeName(
Name));
400 for (
const auto &
F : M) {
401 if (!
F.isIntrinsic() &&
F.hasAddressTaken()) {
409 for (
const auto &
G : M.globals()) {
410 if (!
G.hasInitializer() &&
G.hasExternalLinkage() &&
412 G.getValueType()->isSized()) {
413 uint16_t Size = M.getDataLayout().getTypeAllocSize(
G.getValueType());
419 if (
const NamedMDNode *Named = M.getNamedMetadata(
"wasm.custom_sections")) {
420 for (
const Metadata *MD : Named->operands()) {
421 const auto *Tuple = dyn_cast<MDTuple>(MD);
422 if (!Tuple || Tuple->getNumOperands() != 2)
424 const MDString *
Name = dyn_cast<MDString>(Tuple->getOperand(0));
425 const MDString *Contents = dyn_cast<MDString>(Tuple->getOperand(1));
426 if (!
Name || !Contents)
430 std::string
SectionName = (
".custom_section." +
Name->getString()).str();
447 for (
size_t I = 0,
E =
Debug->getNumOperands();
I <
E; ++
I) {
448 const auto *
CU = cast<DICompileUnit>(
Debug->getOperand(
I));
450 Language.consume_front(
"DW_LANG_");
451 if (SeenLanguages.
insert(Language).second)
457 if (
const NamedMDNode *Ident = M.getNamedMetadata(
"llvm.ident")) {
459 for (
size_t I = 0,
E = Ident->getNumOperands();
I <
E; ++
I) {
460 const auto *S = cast<MDString>(Ident->getOperand(
I)->getOperand(0));
461 std::pair<StringRef, StringRef>
Field = S->getString().split(
"version");
469 int FieldCount = int(!Languages.
empty()) + int(!Tools.
empty());
470 if (FieldCount != 0) {
476 for (
auto &Producers : {std::make_pair(
"language", &Languages),
477 std::make_pair(
"processed-by", &Tools)}) {
478 if (Producers.second->empty())
480 OutStreamer->emitULEB128IntValue(strlen(Producers.first));
482 OutStreamer->emitULEB128IntValue(Producers.second->size());
483 for (
auto &Producer : *Producers.second) {
484 OutStreamer->emitULEB128IntValue(Producer.first.size());
486 OutStreamer->emitULEB128IntValue(Producer.second.size());
495 struct FeatureEntry {
502 auto EmitFeature = [&](std::string Feature) {
503 std::string MDKey = (
StringRef(
"wasm-feature-") + Feature).str();
504 Metadata *Policy = M.getModuleFlag(MDKey);
505 if (Policy ==
nullptr)
510 Entry.Name = Feature;
512 if (
auto *MD = cast<ConstantAsMetadata>(Policy))
513 if (
auto *
I = cast<ConstantInt>(MD->getValue()))
514 Entry.Prefix =
I->getZExtValue();
529 EmitFeature(
"shared-mem");
534 if (M.getDataLayout().getPointerSize() == 8) {
540 if (EmittedFeatures.
size() == 0)
550 for (
auto &
F : EmittedFeatures) {
562 "WebAssembly disables constant pools");
577 WasmSym->setSignature(Signature.get());
584 if (
MDNode *
Idx =
F.getMetadata(
"wasm.index")) {
588 cast<ConstantAsMetadata>(
Idx->getOperand(0))->getValue()));
600 WebAssembly_MC::verifyInstructionPredicates(
MI->getOpcode(),
601 Subtarget->getFeatureBits());
603 switch (
MI->getOpcode()) {
604 case WebAssembly::ARGUMENT_i32:
605 case WebAssembly::ARGUMENT_i32_S:
606 case WebAssembly::ARGUMENT_i64:
607 case WebAssembly::ARGUMENT_i64_S:
608 case WebAssembly::ARGUMENT_f32:
609 case WebAssembly::ARGUMENT_f32_S:
610 case WebAssembly::ARGUMENT_f64:
611 case WebAssembly::ARGUMENT_f64_S:
612 case WebAssembly::ARGUMENT_v16i8:
613 case WebAssembly::ARGUMENT_v16i8_S:
614 case WebAssembly::ARGUMENT_v8i16:
615 case WebAssembly::ARGUMENT_v8i16_S:
616 case WebAssembly::ARGUMENT_v4i32:
617 case WebAssembly::ARGUMENT_v4i32_S:
618 case WebAssembly::ARGUMENT_v2i64:
619 case WebAssembly::ARGUMENT_v2i64_S:
620 case WebAssembly::ARGUMENT_v4f32:
621 case WebAssembly::ARGUMENT_v4f32_S:
622 case WebAssembly::ARGUMENT_v2f64:
623 case WebAssembly::ARGUMENT_v2f64_S:
627 case WebAssembly::FALLTHROUGH_RETURN: {
636 case WebAssembly::COMPILER_FENCE:
643 MCInstLowering.
lower(
MI, TmpInst);
652 const char *ExtraCode,
667 assert(
MI->getOpcode() == WebAssembly::INLINEASM);
690 const char *ExtraCode,
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
static std::string getEmscriptenInvokeSymbolName(wasm::WasmSignature *Sig)
static bool isEmscriptenInvokeName(StringRef Name)
static char getInvokeSig(wasm::ValType VT)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyAsmPrinter()
cl::opt< bool > WasmKeepRegisters
This file declares the class to lower WebAssembly MachineInstrs to their corresponding MCInst records...
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
This file contains the WebAssembly implementation of the WebAssemblyRegisterInfo class.
This file provides signature information for runtime libcalls.
This file registers the WebAssembly target.
This file declares the WebAssembly-specific subclass of TargetMachine.
This file declares WebAssembly-specific target streamer classes.
This file contains the declaration of the WebAssembly-specific type parsing utility functions.
This file contains the declaration of the WebAssembly-specific utility functions.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
MCSymbol * getSymbol(const GlobalValue *GV) const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
virtual void emitGlobalVariable(const GlobalVariable *GV)
Emit the specified global variable to the .s file.
TargetMachine & TM
Target machine description.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
virtual void emitFunctionBodyStart()
Targets can override this to emit stuff before the first basic block in the function.
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const
This emits linkage information about GVSym based on GV, if this is supported by the target.
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
MCSymbol * CurrentFnSym
The symbol for the current function.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
Return the MCSymbol for the specified ExternalSymbol.
bool isPositionIndependent() const
void emitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition=true) const
This emits visibility information about symbol, if this is supported by the target.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
virtual const MCExpr * lowerConstant(const Constant *CV)
Lower the specified LLVM Constant to an MCExpr.
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
bool isVerbose() const
Return true if assembly output should contain comments.
@ Debug
Emit .debug_frame.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
Implements a dense probed hash-table based set.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
VisibilityTypes getVisibility() const
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
Type * getValueType() const
bool hasInitializer() const
Definitions have initializers, declarations don't.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
MCSectionWasm * getWasmSection(const Twine &Section, SectionKind K, unsigned Flags=0)
const SymbolTable & getSymbols() const
getSymbols - Get a reference for the symbol table for clients that want to, for example,...
Instances of this class represent a single low-level machine instruction.
This represents a section on wasm.
std::optional< wasm::WasmSymbolType > getType() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Target specific streamer interface.
StringRef getString() const
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
const std::vector< MachineConstantPoolEntry > & getConstants() const
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
Representation of each machine instruction.
MachineModuleInfoWasm - This is a MachineModuleInfoImpl implementation for Wasm targets.
StringSet MachineSymbolsUsed
const Module * getModule() const
Ty & getObjFileInfo()
Keep track of various per-module pieces of information for backends that would like to do so.
MachineOperand class - Representation of each machine instruction operand.
MachineBasicBlock * getMBB() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
int64_t getOffset() const
Return the offset from the symbol in this operand.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
A Module instance is used to store all the information related to an LLVM module.
LLVMContext & getContext() const
Get the global data context.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Wrapper class representing virtual and physical registers.
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static SectionKind getMetadata()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
void emitJumpTableInfo() override
Print assembly representations of the jump tables used by the current function to the current output ...
void EmitProducerInfo(Module &M)
void emitGlobalVariable(const GlobalVariable *GV) override
Emit the specified global variable to the .s file.
void EmitTargetFeatures(Module &M)
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
const WebAssemblySubtarget & getSubtarget() const
WebAssemblyTargetStreamer * getTargetStreamer()
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
std::string regToString(const MachineOperand &MO)
void emitSymbolType(const MCSymbolWasm *Sym)
MCSymbol * getOrCreateWasmSymbol(StringRef Name)
void emitConstantPool() override
Print to the current output stream assembly representations of the constants in the constant pool MCP...
MVT getRegType(unsigned RegNo) const
void emitDecls(const Module &M)
void emitFunctionBodyStart() override
Targets can override this to emit stuff before the first basic block in the function.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
MCSymbolWasm * getMCSymbolForFunction(const Function *F, bool EnableEmEH, wasm::WasmSignature *Sig, bool &InvokeDetected)
void addSignature(std::unique_ptr< wasm::WasmSignature > &&Sig)
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
bool isVRegStackified(unsigned VReg) const
static const unsigned UnusedReg
unsigned getWAReg(unsigned VReg) const
const std::vector< MVT > & getLocals() const
This class is used to lower an MachineInstr into an MCInst.
void lower(const MachineInstr *MI, MCInst &OutMI) const
const WebAssemblyTargetLowering * getTargetLowering() const override
const WebAssemblyRegisterInfo * getRegisterInfo() const override
WebAssembly-specific streamer interface, to implement support WebAssembly-specific assembly directive...
virtual void emitFunctionType(const MCSymbolWasm *Sym)=0
.functype
virtual void emitLocal(ArrayRef< wasm::ValType > Types)=0
.local
virtual void emitTagType(const MCSymbolWasm *Sym)=0
.tagtype
virtual void emitExportName(const MCSymbolWasm *Sym, StringRef ExportName)=0
.export_name
virtual void emitGlobalType(const MCSymbolWasm *Sym)=0
.globaltype
virtual void emitImportModule(const MCSymbolWasm *Sym, StringRef ImportModule)=0
.import_module
virtual void emitTableType(const MCSymbolWasm *Sym)=0
.tabletype
virtual void emitImportName(const MCSymbolWasm *Sym, StringRef ImportName)=0
.import_name
virtual void emitIndIdx(const MCExpr *Value)=0
.indidx
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
StringRef LanguageString(unsigned Language)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MCSymbolWasm * getOrCreateFunctionTableSymbol(MCContext &Ctx, const WebAssemblySubtarget *Subtarget)
Returns the __indirect_function_table, for use in call_indirect and in function bitcasts.
cl::opt< bool > WasmEnableEmEH
cl::opt< bool > WasmEnableEmSjLj
std::string signatureToString(const wasm::WasmSignature *Sig)
void wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT, const ArrayRef< MVT > &VTs)
Sets a Wasm Symbol Type.
bool isWasmVarAddressSpace(unsigned AS)
@ WASM_FEATURE_PREFIX_USED
@ WASM_FEATURE_PREFIX_REQUIRED
@ WASM_FEATURE_PREFIX_DISALLOWED
@ WASM_SYMBOL_TYPE_GLOBAL
@ WASM_SYMBOL_TYPE_FUNCTION
This is an optimization pass for GlobalISel generic memory operations.
void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, const Function &ContextFunc, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
const SubtargetFeatureKV WebAssemblyFeatureKV[WebAssembly::NumSubtargetFeatures]
void valTypesFromMVTs(const ArrayRef< MVT > &In, SmallVectorImpl< wasm::ValType > &Out)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Target & getTheWebAssemblyTarget32()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
std::unique_ptr< wasm::WasmSignature > signatureFromMVTs(const SmallVectorImpl< MVT > &Results, const SmallVectorImpl< MVT > &Params)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Target & getTheWebAssemblyTarget64()
void getLibcallSignature(const WebAssemblySubtarget &Subtarget, RTLIB::Libcall LC, SmallVectorImpl< wasm::ValType > &Rets, SmallVectorImpl< wasm::ValType > &Params)
void computeLegalValueVTs(const WebAssemblyTargetLowering &TLI, LLVMContext &Ctx, const DataLayout &DL, Type *Ty, SmallVectorImpl< MVT > &ValueVTs)
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
Used to provide key value pairs for feature and CPU bit flags.
SmallVector< ValType, 1 > Returns
SmallVector< ValType, 4 > Params