Path: blob/main/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.h
35266 views
//===-- WebAssemblyExceptionInfo.h - WebAssembly Exception Info -*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// \brief This file implements WebAssemblyException information analysis.10///11//===----------------------------------------------------------------------===//1213#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYEXCEPTIONINFO_H14#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYEXCEPTIONINFO_H1516#include "WebAssembly.h"17#include "llvm/ADT/SmallPtrSet.h"18#include "llvm/CodeGen/MachineFunctionPass.h"1920namespace llvm {2122class MachineDominatorTree;23class MachineDominanceFrontier;2425// WebAssembly instructions for exception handling are structured as follows:26// try27// instructions*28// catch ----|29// instructions* | -> A WebAssemblyException consists of this region30// end ----|31//32// A WebAssemblyException object contains BBs that belong to a 'catch' part of33// the try-catch-end structure to be created later. 'try' and 'end' markers34// are not present at this stage and will be generated in CFGStackify pass.35// Because CFGSort requires all the BBs within a catch part to be sorted36// together as it does for loops, this pass calculates the nesting structure of37// catch part of exceptions in a function.38//39// An exception catch part is defined as a BB with catch instruction and all40// other BBs dominated by this BB.41class WebAssemblyException {42MachineBasicBlock *EHPad = nullptr;4344WebAssemblyException *ParentException = nullptr;45std::vector<std::unique_ptr<WebAssemblyException>> SubExceptions;46std::vector<MachineBasicBlock *> Blocks;47SmallPtrSet<MachineBasicBlock *, 8> BlockSet;4849public:50WebAssemblyException(MachineBasicBlock *EHPad) : EHPad(EHPad) {}51WebAssemblyException(const WebAssemblyException &) = delete;52const WebAssemblyException &operator=(const WebAssemblyException &) = delete;5354MachineBasicBlock *getEHPad() const { return EHPad; }55MachineBasicBlock *getHeader() const { return EHPad; }56WebAssemblyException *getParentException() const { return ParentException; }57void setParentException(WebAssemblyException *WE) { ParentException = WE; }5859bool contains(const WebAssemblyException *WE) const {60if (WE == this)61return true;62if (!WE)63return false;64return contains(WE->getParentException());65}66bool contains(const MachineBasicBlock *MBB) const {67return BlockSet.count(MBB);68}6970void addToBlocksSet(MachineBasicBlock *MBB) { BlockSet.insert(MBB); }71void removeFromBlocksSet(MachineBasicBlock *MBB) { BlockSet.erase(MBB); }72void addToBlocksVector(MachineBasicBlock *MBB) { Blocks.push_back(MBB); }73void addBlock(MachineBasicBlock *MBB) {74Blocks.push_back(MBB);75BlockSet.insert(MBB);76}77ArrayRef<MachineBasicBlock *> getBlocks() const { return Blocks; }78using block_iterator = typename ArrayRef<MachineBasicBlock *>::const_iterator;79block_iterator block_begin() const { return getBlocks().begin(); }80block_iterator block_end() const { return getBlocks().end(); }81inline iterator_range<block_iterator> blocks() const {82return make_range(block_begin(), block_end());83}84unsigned getNumBlocks() const { return Blocks.size(); }85std::vector<MachineBasicBlock *> &getBlocksVector() { return Blocks; }86SmallPtrSetImpl<MachineBasicBlock *> &getBlocksSet() { return BlockSet; }8788const std::vector<std::unique_ptr<WebAssemblyException>> &89getSubExceptions() const {90return SubExceptions;91}92std::vector<std::unique_ptr<WebAssemblyException>> &getSubExceptions() {93return SubExceptions;94}95void addSubException(std::unique_ptr<WebAssemblyException> E) {96SubExceptions.push_back(std::move(E));97}98using iterator = typename decltype(SubExceptions)::const_iterator;99iterator begin() const { return SubExceptions.begin(); }100iterator end() const { return SubExceptions.end(); }101102void reserveBlocks(unsigned Size) { Blocks.reserve(Size); }103void reverseBlock(unsigned From = 0) {104std::reverse(Blocks.begin() + From, Blocks.end());105}106107// Return the nesting level. An outermost one has depth 1.108unsigned getExceptionDepth() const {109unsigned D = 1;110for (const WebAssemblyException *CurException = ParentException;111CurException; CurException = CurException->ParentException)112++D;113return D;114}115116void print(raw_ostream &OS, unsigned Depth = 0) const;117void dump() const;118};119120raw_ostream &operator<<(raw_ostream &OS, const WebAssemblyException &WE);121122class WebAssemblyExceptionInfo final : public MachineFunctionPass {123// Mapping of basic blocks to the innermost exception they occur in124DenseMap<const MachineBasicBlock *, WebAssemblyException *> BBMap;125std::vector<std::unique_ptr<WebAssemblyException>> TopLevelExceptions;126127void discoverAndMapException(WebAssemblyException *WE,128const MachineDominatorTree &MDT,129const MachineDominanceFrontier &MDF);130WebAssemblyException *getOutermostException(MachineBasicBlock *MBB) const;131132public:133static char ID;134WebAssemblyExceptionInfo() : MachineFunctionPass(ID) {135initializeWebAssemblyExceptionInfoPass(*PassRegistry::getPassRegistry());136}137~WebAssemblyExceptionInfo() override { releaseMemory(); }138WebAssemblyExceptionInfo(const WebAssemblyExceptionInfo &) = delete;139WebAssemblyExceptionInfo &140operator=(const WebAssemblyExceptionInfo &) = delete;141142bool runOnMachineFunction(MachineFunction &) override;143void releaseMemory() override;144void recalculate(MachineFunction &MF, MachineDominatorTree &MDT,145const MachineDominanceFrontier &MDF);146void getAnalysisUsage(AnalysisUsage &AU) const override;147148bool empty() const { return TopLevelExceptions.empty(); }149150// Return the innermost exception that MBB lives in. If the block is not in an151// exception, null is returned.152WebAssemblyException *getExceptionFor(const MachineBasicBlock *MBB) const {153return BBMap.lookup(MBB);154}155156void changeExceptionFor(const MachineBasicBlock *MBB,157WebAssemblyException *WE) {158if (!WE) {159BBMap.erase(MBB);160return;161}162BBMap[MBB] = WE;163}164165void addTopLevelException(std::unique_ptr<WebAssemblyException> WE) {166assert(!WE->getParentException() && "Not a top level exception!");167TopLevelExceptions.push_back(std::move(WE));168}169170void print(raw_ostream &OS, const Module *M = nullptr) const override;171};172173} // end namespace llvm174175#endif176177178