172 lines · cpp
1//=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file implements WebAssembly-specific per-machine-function11/// information.12///13//===----------------------------------------------------------------------===//14 15#include "WebAssemblyMachineFunctionInfo.h"16#include "Utils/WebAssemblyTypeUtilities.h"17#include "WebAssemblyISelLowering.h"18#include "WebAssemblySubtarget.h"19#include "WebAssemblyUtilities.h"20#include "llvm/CodeGen/Analysis.h"21#include "llvm/CodeGen/WasmEHFuncInfo.h"22#include "llvm/Target/TargetMachine.h"23using namespace llvm;24 25WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor.26 27MachineFunctionInfo *WebAssemblyFunctionInfo::clone(28 BumpPtrAllocator &Allocator, MachineFunction &DestMF,29 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)30 const {31 // TODO: Implement cloning for WasmEHFuncInfo. This will have invalid block32 // references.33 return DestMF.cloneInfo<WebAssemblyFunctionInfo>(*this);34}35 36void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo &MRI) {37 assert(WARegs.empty());38 unsigned Reg = WebAssembly::UnusedReg;39 WARegs.resize(MRI.getNumVirtRegs(), Reg);40}41 42void llvm::computeLegalValueVTs(const WebAssemblyTargetLowering &TLI,43 LLVMContext &Ctx, const DataLayout &DL,44 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {45 SmallVector<EVT, 4> VTs;46 ComputeValueVTs(TLI, DL, Ty, VTs);47 48 for (EVT VT : VTs) {49 unsigned NumRegs = TLI.getNumRegisters(Ctx, VT);50 MVT RegisterVT = TLI.getRegisterType(Ctx, VT);51 for (unsigned I = 0; I != NumRegs; ++I)52 ValueVTs.push_back(RegisterVT);53 }54}55 56void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,57 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {58 const DataLayout &DL(F.getDataLayout());59 const WebAssemblyTargetLowering &TLI =60 *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();61 computeLegalValueVTs(TLI, F.getContext(), DL, Ty, ValueVTs);62}63 64void llvm::computeSignatureVTs(const FunctionType *Ty,65 const Function *TargetFunc,66 const Function &ContextFunc,67 const TargetMachine &TM,68 SmallVectorImpl<MVT> &Params,69 SmallVectorImpl<MVT> &Results) {70 computeLegalValueVTs(ContextFunc, TM, Ty->getReturnType(), Results);71 72 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());73 if (!WebAssembly::canLowerReturn(74 Results.size(),75 &TM.getSubtarget<WebAssemblySubtarget>(ContextFunc))) {76 // WebAssembly can't lower returns of multiple values without demoting to77 // sret unless multivalue is enabled (see78 // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return79 // values with a poitner parameter.80 Results.clear();81 Params.push_back(PtrVT);82 }83 84 for (auto *Param : Ty->params())85 computeLegalValueVTs(ContextFunc, TM, Param, Params);86 if (Ty->isVarArg())87 Params.push_back(PtrVT);88 89 // For swiftcc, emit additional swiftself and swifterror parameters90 // if there aren't. These additional parameters are also passed for caller.91 // They are necessary to match callee and caller signature for indirect92 // call.93 94 if (TargetFunc && TargetFunc->getCallingConv() == CallingConv::Swift) {95 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());96 bool HasSwiftErrorArg = false;97 bool HasSwiftSelfArg = false;98 for (const auto &Arg : TargetFunc->args()) {99 HasSwiftErrorArg |= Arg.hasAttribute(Attribute::SwiftError);100 HasSwiftSelfArg |= Arg.hasAttribute(Attribute::SwiftSelf);101 }102 if (!HasSwiftErrorArg)103 Params.push_back(PtrVT);104 if (!HasSwiftSelfArg)105 Params.push_back(PtrVT);106 }107}108 109void llvm::valTypesFromMVTs(ArrayRef<MVT> In,110 SmallVectorImpl<wasm::ValType> &Out) {111 for (MVT Ty : In)112 Out.push_back(WebAssembly::toValType(Ty));113}114 115wasm::WasmSignature *116llvm::signatureFromMVTs(MCContext &Ctx, const SmallVectorImpl<MVT> &Results,117 const SmallVectorImpl<MVT> &Params) {118 auto Sig = Ctx.createWasmSignature();119 valTypesFromMVTs(Results, Sig->Returns);120 valTypesFromMVTs(Params, Sig->Params);121 return Sig;122}123 124yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(125 const llvm::MachineFunction &MF, const llvm::WebAssemblyFunctionInfo &MFI)126 : CFGStackified(MFI.isCFGStackified()) {127 for (auto VT : MFI.getParams())128 Params.push_back(EVT(VT).getEVTString());129 for (auto VT : MFI.getResults())130 Results.push_back(EVT(VT).getEVTString());131 132 // MFI.getWasmEHFuncInfo() is non-null only for functions with the133 // personality function.134 135 if (auto *EHInfo = MF.getWasmEHFuncInfo()) {136 // SrcToUnwindDest can contain stale mappings in case BBs are removed in137 // optimizations, in case, for example, they are unreachable. We should not138 // include their info.139 SmallPtrSet<const MachineBasicBlock *, 16> MBBs;140 for (const auto &MBB : MF)141 MBBs.insert(&MBB);142 for (auto KV : EHInfo->SrcToUnwindDest) {143 auto *SrcBB = cast<MachineBasicBlock *>(KV.first);144 auto *DestBB = cast<MachineBasicBlock *>(KV.second);145 if (MBBs.count(SrcBB) && MBBs.count(DestBB))146 SrcToUnwindDest[SrcBB->getNumber()] = DestBB->getNumber();147 }148 }149}150 151void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {152 MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);153}154 155void WebAssemblyFunctionInfo::initializeBaseYamlFields(156 MachineFunction &MF, const yaml::WebAssemblyFunctionInfo &YamlMFI) {157 CFGStackified = YamlMFI.CFGStackified;158 for (auto VT : YamlMFI.Params)159 addParam(WebAssembly::parseMVT(VT.Value));160 for (auto VT : YamlMFI.Results)161 addResult(WebAssembly::parseMVT(VT.Value));162 163 // FIXME: WasmEHInfo is defined in the MachineFunction, but serialized164 // here. Either WasmEHInfo should be moved out of MachineFunction, or the165 // serialization handling should be moved to MachineFunction.166 if (WasmEHFuncInfo *WasmEHInfo = MF.getWasmEHFuncInfo()) {167 for (auto KV : YamlMFI.SrcToUnwindDest)168 WasmEHInfo->setUnwindDest(MF.getBlockNumbered(KV.first),169 MF.getBlockNumbered(KV.second));170 }171}172