diff options
| author | Thomas Lively <tlively@google.com> | 2019-10-15 18:28:22 +0000 |
|---|---|---|
| committer | Thomas Lively <tlively@google.com> | 2019-10-15 18:28:22 +0000 |
| commit | 2cb27072cefb11d5018735a3b70a903dc1d319ac (patch) | |
| tree | b007b3e4e319c5caf584201dceb06b0852aee65b /llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp | |
| parent | 0650355c09ab8e6605ae37b818270a7a7c8ce2c7 (diff) | |
| download | bcm5719-llvm-2cb27072cefb11d5018735a3b70a903dc1d319ac.tar.gz bcm5719-llvm-2cb27072cefb11d5018735a3b70a903dc1d319ac.zip | |
[WebAssembly] Allow multivalue types in block signature operands
Summary:
Renames `ExprType` to the more apt `BlockType` and adds a variant for
multivalue blocks. Currently non-void blocks are only generated at the
end of functions where the block return type needs to agree with the
function return type, and that remains true for multivalue
blocks. That invariant means that the actual signature does not need
to be stored in the block signature `MachineOperand` because it can be
inferred by `WebAssemblyMCInstLower` from the return type of the
parent function. `WebAssemblyMCInstLower` continues to lower block
signature operands to immediates when possible but lowers multivalue
signatures to function type symbols. The AsmParser and Disassembler
are updated to handle multivalue block types as well.
Reviewers: aheejin, dschuff, aardappel
Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D68889
llvm-svn: 374933
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp')
| -rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index 647e987309f..59c10243c54 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -163,6 +163,21 @@ MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO, return MCOperand::createExpr(Expr); } +MCOperand WebAssemblyMCInstLower::lowerTypeIndexOperand( + SmallVector<wasm::ValType, 1> &&Returns, + SmallVector<wasm::ValType, 4> &&Params) const { + auto Signature = std::make_unique<wasm::WasmSignature>(std::move(Returns), + std::move(Params)); + MCSymbol *Sym = Printer.createTempSymbol("typeindex"); + auto *WasmSym = cast<MCSymbolWasm>(Sym); + WasmSym->setSignature(Signature.get()); + Printer.addSignature(std::move(Signature)); + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); + const MCExpr *Expr = + MCSymbolRefExpr::create(WasmSym, MCSymbolRefExpr::VK_WASM_TYPEINDEX, Ctx); + return MCOperand::createExpr(Expr); +} + // Return the WebAssembly type associated with the given register class. static wasm::ValType getType(const TargetRegisterClass *RC) { if (RC == &WebAssembly::I32RegClass) @@ -178,6 +193,16 @@ static wasm::ValType getType(const TargetRegisterClass *RC) { llvm_unreachable("Unexpected register class"); } +static void getFunctionReturns(const MachineInstr *MI, + SmallVectorImpl<wasm::ValType> &Returns) { + const Function &F = MI->getMF()->getFunction(); + const TargetMachine &TM = MI->getMF()->getTarget(); + Type *RetTy = F.getReturnType(); + SmallVector<MVT, 4> CallerRetTys; + computeLegalValueVTs(F, TM, RetTy, CallerRetTys); + valTypesFromMVTs(CallerRetTys, Returns); +} + void WebAssemblyMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { OutMI.setOpcode(MI->getOpcode()); @@ -208,8 +233,6 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI, if (I < Desc.NumOperands) { const MCOperandInfo &Info = Desc.OpInfo[I]; if (Info.OperandType == WebAssembly::OPERAND_TYPEINDEX) { - MCSymbol *Sym = Printer.createTempSymbol("typeindex"); - SmallVector<wasm::ValType, 4> Returns; SmallVector<wasm::ValType, 4> Params; @@ -228,26 +251,21 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI, // return_call_indirect instructions have the return type of the // caller - if (MI->getOpcode() == WebAssembly::RET_CALL_INDIRECT) { - const Function &F = MI->getMF()->getFunction(); - const TargetMachine &TM = MI->getMF()->getTarget(); - Type *RetTy = F.getReturnType(); - SmallVector<MVT, 4> CallerRetTys; - computeLegalValueVTs(F, TM, RetTy, CallerRetTys); - valTypesFromMVTs(CallerRetTys, Returns); - } + if (MI->getOpcode() == WebAssembly::RET_CALL_INDIRECT) + getFunctionReturns(MI, Returns); - auto *WasmSym = cast<MCSymbolWasm>(Sym); - auto Signature = std::make_unique<wasm::WasmSignature>(std::move(Returns), - std::move(Params)); - WasmSym->setSignature(Signature.get()); - Printer.addSignature(std::move(Signature)); - WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); - - const MCExpr *Expr = MCSymbolRefExpr::create( - WasmSym, MCSymbolRefExpr::VK_WASM_TYPEINDEX, Ctx); - MCOp = MCOperand::createExpr(Expr); + MCOp = lowerTypeIndexOperand(std::move(Returns), std::move(Params)); break; + } else if (Info.OperandType == WebAssembly::OPERAND_SIGNATURE) { + auto BT = static_cast<WebAssembly::BlockType>(MO.getImm()); + assert(BT != WebAssembly::BlockType::Invalid); + if (BT == WebAssembly::BlockType::Multivalue) { + SmallVector<wasm::ValType, 1> Returns; + getFunctionReturns(MI, Returns); + MCOp = lowerTypeIndexOperand(std::move(Returns), + SmallVector<wasm::ValType, 4>()); + break; + } } } MCOp = MCOperand::createImm(MO.getImm()); |

