xref: /freebsd/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp (revision 8bcb0991864975618c09697b1aca10683346d9f0)
10b57cec5SDimitry Andric //=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This file implements WebAssembly-specific per-machine-function
110b57cec5SDimitry Andric /// information.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "WebAssemblyMachineFunctionInfo.h"
160b57cec5SDimitry Andric #include "WebAssemblyISelLowering.h"
170b57cec5SDimitry Andric #include "WebAssemblySubtarget.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/Analysis.h"
190b57cec5SDimitry Andric using namespace llvm;
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor.
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric void WebAssemblyFunctionInfo::initWARegs() {
240b57cec5SDimitry Andric   assert(WARegs.empty());
250b57cec5SDimitry Andric   unsigned Reg = UnusedReg;
260b57cec5SDimitry Andric   WARegs.resize(MF.getRegInfo().getNumVirtRegs(), Reg);
270b57cec5SDimitry Andric }
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,
300b57cec5SDimitry Andric                                 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
310b57cec5SDimitry Andric   const DataLayout &DL(F.getParent()->getDataLayout());
320b57cec5SDimitry Andric   const WebAssemblyTargetLowering &TLI =
330b57cec5SDimitry Andric       *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
340b57cec5SDimitry Andric   SmallVector<EVT, 4> VTs;
350b57cec5SDimitry Andric   ComputeValueVTs(TLI, DL, Ty, VTs);
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   for (EVT VT : VTs) {
380b57cec5SDimitry Andric     unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
390b57cec5SDimitry Andric     MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
400b57cec5SDimitry Andric     for (unsigned I = 0; I != NumRegs; ++I)
410b57cec5SDimitry Andric       ValueVTs.push_back(RegisterVT);
420b57cec5SDimitry Andric   }
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric void llvm::computeSignatureVTs(const FunctionType *Ty, const Function &F,
460b57cec5SDimitry Andric                                const TargetMachine &TM,
470b57cec5SDimitry Andric                                SmallVectorImpl<MVT> &Params,
480b57cec5SDimitry Andric                                SmallVectorImpl<MVT> &Results) {
490b57cec5SDimitry Andric   computeLegalValueVTs(F, TM, Ty->getReturnType(), Results);
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
52*8bcb0991SDimitry Andric   if (Results.size() > 1 &&
53*8bcb0991SDimitry Andric       !TM.getSubtarget<WebAssemblySubtarget>(F).hasMultivalue()) {
54*8bcb0991SDimitry Andric     // WebAssembly can't lower returns of multiple values without demoting to
55*8bcb0991SDimitry Andric     // sret unless multivalue is enabled (see
56*8bcb0991SDimitry Andric     // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return
57*8bcb0991SDimitry Andric     // values with a poitner parameter.
580b57cec5SDimitry Andric     Results.clear();
590b57cec5SDimitry Andric     Params.push_back(PtrVT);
600b57cec5SDimitry Andric   }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   for (auto *Param : Ty->params())
630b57cec5SDimitry Andric     computeLegalValueVTs(F, TM, Param, Params);
640b57cec5SDimitry Andric   if (Ty->isVarArg())
650b57cec5SDimitry Andric     Params.push_back(PtrVT);
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In,
690b57cec5SDimitry Andric                             SmallVectorImpl<wasm::ValType> &Out) {
700b57cec5SDimitry Andric   for (MVT Ty : In)
710b57cec5SDimitry Andric     Out.push_back(WebAssembly::toValType(Ty));
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric std::unique_ptr<wasm::WasmSignature>
750b57cec5SDimitry Andric llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
760b57cec5SDimitry Andric                         const SmallVectorImpl<MVT> &Params) {
77*8bcb0991SDimitry Andric   auto Sig = std::make_unique<wasm::WasmSignature>();
780b57cec5SDimitry Andric   valTypesFromMVTs(Results, Sig->Returns);
790b57cec5SDimitry Andric   valTypesFromMVTs(Params, Sig->Params);
800b57cec5SDimitry Andric   return Sig;
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
840b57cec5SDimitry Andric     const llvm::WebAssemblyFunctionInfo &MFI)
850b57cec5SDimitry Andric     : CFGStackified(MFI.isCFGStackified()) {}
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
880b57cec5SDimitry Andric   MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric void WebAssemblyFunctionInfo::initializeBaseYamlFields(
920b57cec5SDimitry Andric     const yaml::WebAssemblyFunctionInfo &YamlMFI) {
930b57cec5SDimitry Andric   CFGStackified = YamlMFI.CFGStackified;
940b57cec5SDimitry Andric }
95