110e730a2SDan Gohman //=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=//
210e730a2SDan Gohman //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
610e730a2SDan Gohman //
710e730a2SDan Gohman //===----------------------------------------------------------------------===//
810e730a2SDan Gohman ///
910e730a2SDan Gohman /// \file
105f8f34e4SAdrian Prantl /// This file implements WebAssembly-specific per-machine-function
1110e730a2SDan Gohman /// information.
1210e730a2SDan Gohman ///
1310e730a2SDan Gohman //===----------------------------------------------------------------------===//
1410e730a2SDan Gohman 
1510e730a2SDan Gohman #include "WebAssemblyMachineFunctionInfo.h"
162726b88cSDan Gohman #include "WebAssemblyISelLowering.h"
172726b88cSDan Gohman #include "WebAssemblySubtarget.h"
182726b88cSDan Gohman #include "llvm/CodeGen/Analysis.h"
1910e730a2SDan Gohman using namespace llvm;
2010e730a2SDan Gohman 
2118c56a07SHeejin Ahn WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor.
22058fce54SDan Gohman 
23058fce54SDan Gohman void WebAssemblyFunctionInfo::initWARegs() {
24058fce54SDan Gohman   assert(WARegs.empty());
25058fce54SDan Gohman   unsigned Reg = UnusedReg;
26058fce54SDan Gohman   WARegs.resize(MF.getRegInfo().getNumVirtRegs(), Reg);
27058fce54SDan Gohman }
282726b88cSDan Gohman 
2918c56a07SHeejin Ahn void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,
302726b88cSDan Gohman                                 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
312726b88cSDan Gohman   const DataLayout &DL(F.getParent()->getDataLayout());
322726b88cSDan Gohman   const WebAssemblyTargetLowering &TLI =
332726b88cSDan Gohman       *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
342726b88cSDan Gohman   SmallVector<EVT, 4> VTs;
352726b88cSDan Gohman   ComputeValueVTs(TLI, DL, Ty, VTs);
362726b88cSDan Gohman 
372726b88cSDan Gohman   for (EVT VT : VTs) {
382726b88cSDan Gohman     unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
392726b88cSDan Gohman     MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
4018c56a07SHeejin Ahn     for (unsigned I = 0; I != NumRegs; ++I)
412726b88cSDan Gohman       ValueVTs.push_back(RegisterVT);
422726b88cSDan Gohman   }
432726b88cSDan Gohman }
442726b88cSDan Gohman 
4518c56a07SHeejin Ahn void llvm::computeSignatureVTs(const FunctionType *Ty, const Function &F,
4677a7a380SDerek Schuff                                const TargetMachine &TM,
472726b88cSDan Gohman                                SmallVectorImpl<MVT> &Params,
482726b88cSDan Gohman                                SmallVectorImpl<MVT> &Results) {
4918c56a07SHeejin Ahn   computeLegalValueVTs(F, TM, Ty->getReturnType(), Results);
502726b88cSDan Gohman 
5177a7a380SDerek Schuff   MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
522726b88cSDan Gohman   if (Results.size() > 1) {
532726b88cSDan Gohman     // WebAssembly currently can't lower returns of multiple values without
542726b88cSDan Gohman     // demoting to sret (see WebAssemblyTargetLowering::CanLowerReturn). So
552726b88cSDan Gohman     // replace multiple return values with a pointer parameter.
562726b88cSDan Gohman     Results.clear();
5777a7a380SDerek Schuff     Params.push_back(PtrVT);
582726b88cSDan Gohman   }
592726b88cSDan Gohman 
6077a7a380SDerek Schuff   for (auto *Param : Ty->params())
6118c56a07SHeejin Ahn     computeLegalValueVTs(F, TM, Param, Params);
6277a7a380SDerek Schuff   if (Ty->isVarArg())
6377a7a380SDerek Schuff     Params.push_back(PtrVT);
6477a7a380SDerek Schuff }
6577a7a380SDerek Schuff 
6618c56a07SHeejin Ahn void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In,
6749482f82SWouter van Oortmerssen                             SmallVectorImpl<wasm::ValType> &Out) {
6849482f82SWouter van Oortmerssen   for (MVT Ty : In)
6949482f82SWouter van Oortmerssen     Out.push_back(WebAssembly::toValType(Ty));
7049482f82SWouter van Oortmerssen }
7149482f82SWouter van Oortmerssen 
7277a7a380SDerek Schuff std::unique_ptr<wasm::WasmSignature>
7318c56a07SHeejin Ahn llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
7477a7a380SDerek Schuff                         const SmallVectorImpl<MVT> &Params) {
7577a7a380SDerek Schuff   auto Sig = make_unique<wasm::WasmSignature>();
7618c56a07SHeejin Ahn   valTypesFromMVTs(Results, Sig->Returns);
7718c56a07SHeejin Ahn   valTypesFromMVTs(Params, Sig->Params);
7877a7a380SDerek Schuff   return Sig;
792726b88cSDan Gohman }
8052221d56SHeejin Ahn 
8152221d56SHeejin Ahn yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
82*1aaa481fSHeejin Ahn     const llvm::WebAssemblyFunctionInfo &MFI)
83*1aaa481fSHeejin Ahn     : CFGStackified(MFI.isCFGStackified()) {}
8452221d56SHeejin Ahn 
8552221d56SHeejin Ahn void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
8652221d56SHeejin Ahn   MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);
8752221d56SHeejin Ahn }
8852221d56SHeejin Ahn 
8952221d56SHeejin Ahn void WebAssemblyFunctionInfo::initializeBaseYamlFields(
90*1aaa481fSHeejin Ahn     const yaml::WebAssemblyFunctionInfo &YamlMFI) {
91*1aaa481fSHeejin Ahn   CFGStackified = YamlMFI.CFGStackified;
92*1aaa481fSHeejin Ahn }
93