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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file implements WebAssembly-specific per-machine-function 11 /// information. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "WebAssemblyMachineFunctionInfo.h" 16 #include "Utils/WebAssemblyTypeUtilities.h" 17 #include "WebAssemblyISelLowering.h" 18 #include "WebAssemblySubtarget.h" 19 #include "llvm/CodeGen/Analysis.h" 20 #include "llvm/CodeGen/WasmEHFuncInfo.h" 21 #include "llvm/Target/TargetMachine.h" 22 using namespace llvm; 23 24 WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor. 25 26 void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo &MRI) { 27 assert(WARegs.empty()); 28 unsigned Reg = UnusedReg; 29 WARegs.resize(MRI.getNumVirtRegs(), Reg); 30 } 31 32 void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM, 33 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) { 34 const DataLayout &DL(F.getParent()->getDataLayout()); 35 const WebAssemblyTargetLowering &TLI = 36 *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering(); 37 SmallVector<EVT, 4> VTs; 38 ComputeValueVTs(TLI, DL, Ty, VTs); 39 40 for (EVT VT : VTs) { 41 unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT); 42 MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT); 43 for (unsigned I = 0; I != NumRegs; ++I) 44 ValueVTs.push_back(RegisterVT); 45 } 46 } 47 48 void llvm::computeSignatureVTs(const FunctionType *Ty, 49 const Function *TargetFunc, 50 const Function &ContextFunc, 51 const TargetMachine &TM, 52 SmallVectorImpl<MVT> &Params, 53 SmallVectorImpl<MVT> &Results) { 54 computeLegalValueVTs(ContextFunc, TM, Ty->getReturnType(), Results); 55 56 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()); 57 if (Results.size() > 1 && 58 !TM.getSubtarget<WebAssemblySubtarget>(ContextFunc).hasMultivalue()) { 59 // WebAssembly can't lower returns of multiple values without demoting to 60 // sret unless multivalue is enabled (see 61 // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return 62 // values with a poitner parameter. 63 Results.clear(); 64 Params.push_back(PtrVT); 65 } 66 67 for (auto *Param : Ty->params()) 68 computeLegalValueVTs(ContextFunc, TM, Param, Params); 69 if (Ty->isVarArg()) 70 Params.push_back(PtrVT); 71 72 // For swiftcc, emit additional swiftself and swifterror parameters 73 // if there aren't. These additional parameters are also passed for caller. 74 // They are necessary to match callee and caller signature for indirect 75 // call. 76 77 if (TargetFunc && TargetFunc->getCallingConv() == CallingConv::Swift) { 78 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()); 79 bool HasSwiftErrorArg = false; 80 bool HasSwiftSelfArg = false; 81 for (const auto &Arg : TargetFunc->args()) { 82 HasSwiftErrorArg |= Arg.hasAttribute(Attribute::SwiftError); 83 HasSwiftSelfArg |= Arg.hasAttribute(Attribute::SwiftSelf); 84 } 85 if (!HasSwiftErrorArg) 86 Params.push_back(PtrVT); 87 if (!HasSwiftSelfArg) 88 Params.push_back(PtrVT); 89 } 90 } 91 92 void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In, 93 SmallVectorImpl<wasm::ValType> &Out) { 94 for (MVT Ty : In) 95 Out.push_back(WebAssembly::toValType(Ty)); 96 } 97 98 std::unique_ptr<wasm::WasmSignature> 99 llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results, 100 const SmallVectorImpl<MVT> &Params) { 101 auto Sig = std::make_unique<wasm::WasmSignature>(); 102 valTypesFromMVTs(Results, Sig->Returns); 103 valTypesFromMVTs(Params, Sig->Params); 104 return Sig; 105 } 106 107 yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo( 108 const llvm::WebAssemblyFunctionInfo &MFI) 109 : CFGStackified(MFI.isCFGStackified()) { 110 auto *EHInfo = MFI.getWasmEHFuncInfo(); 111 const llvm::MachineFunction &MF = MFI.getMachineFunction(); 112 // MFI.getWasmEHFuncInfo() is non-null only for functions with the 113 // personality function. 114 if (EHInfo) { 115 // SrcToUnwindDest can contain stale mappings in case BBs are removed in 116 // optimizations, in case, for example, they are unreachable. We should not 117 // include their info. 118 SmallPtrSet<const MachineBasicBlock *, 16> MBBs; 119 for (const auto &MBB : MF) 120 MBBs.insert(&MBB); 121 for (auto KV : EHInfo->SrcToUnwindDest) { 122 auto *SrcBB = KV.first.get<MachineBasicBlock *>(); 123 auto *DestBB = KV.second.get<MachineBasicBlock *>(); 124 if (MBBs.count(SrcBB) && MBBs.count(DestBB)) 125 SrcToUnwindDest[SrcBB->getNumber()] = DestBB->getNumber(); 126 } 127 } 128 } 129 130 void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) { 131 MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this); 132 } 133 134 void WebAssemblyFunctionInfo::initializeBaseYamlFields( 135 const yaml::WebAssemblyFunctionInfo &YamlMFI) { 136 CFGStackified = YamlMFI.CFGStackified; 137 if (WasmEHInfo) { 138 for (auto KV : YamlMFI.SrcToUnwindDest) 139 WasmEHInfo->setUnwindDest(MF.getBlockNumbered(KV.first), 140 MF.getBlockNumbered(KV.second)); 141 } 142 } 143