WebAssemblyMachineFunctionInfo.cpp 6.5 KB

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