LCOV - code coverage report
Current view: top level - lib/Target/WebAssembly - WebAssemblyExceptionInfo.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 22 30 73.3 %
Date: 2018-10-20 13:21:21 Functions: 6 11 54.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- WebAssemblyExceptionInfo.h - WebAssembly Exception Info -*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : ///
      10             : /// \file
      11             : /// \brief This file implements WebAssemblyException information analysis.
      12             : ///
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYEXCEPTIONINFO_H
      16             : #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYEXCEPTIONINFO_H
      17             : 
      18             : #include "WebAssembly.h"
      19             : #include "llvm/ADT/SetVector.h"
      20             : #include "llvm/CodeGen/MachineFunctionPass.h"
      21             : 
      22             : namespace llvm {
      23             : 
      24             : class MachineDominatorTree;
      25             : class MachineDominanceFrontier;
      26             : 
      27             : // WebAssembly instructions for exception handling are structured as follows:
      28             : //   try
      29             : //     instructions*
      30             : //   catch             ----|
      31             : //     instructions*       | -> A WebAssemblyException consists of this region
      32             : //   end               ----|
      33             : //
      34             : // A WebAssemblyException object contains BBs that belong to a 'catch' part of
      35             : // the try-catch-end structure to be created later. 'try' and 'end' markers
      36             : // are not present at this stage and will be generated in CFGStackify pass.
      37             : // Because CFGSort requires all the BBs within a catch part to be sorted
      38             : // together as it does for loops, this pass calculates the nesting structure of
      39             : // catch part of exceptions in a function.
      40             : //
      41             : // An exception catch part is defined as a BB with catch instruction and all
      42             : // other BBs dominated by this BB.
      43             : class WebAssemblyException {
      44             :   MachineBasicBlock *EHPad = nullptr;
      45             : 
      46             :   WebAssemblyException *ParentException = nullptr;
      47             :   std::vector<WebAssemblyException *> SubExceptions;
      48             :   std::vector<MachineBasicBlock *> Blocks;
      49             :   SmallPtrSet<const MachineBasicBlock *, 8> BlockSet;
      50             : 
      51             : public:
      52          34 :   WebAssemblyException(MachineBasicBlock *EHPad) : EHPad(EHPad) {}
      53          34 :   ~WebAssemblyException() { DeleteContainerPointers(SubExceptions); }
      54             :   WebAssemblyException(const WebAssemblyException &) = delete;
      55             :   const WebAssemblyException &operator=(const WebAssemblyException &) = delete;
      56             : 
      57           0 :   MachineBasicBlock *getEHPad() const { return EHPad; }
      58           0 :   MachineBasicBlock *getHeader() const { return EHPad; }
      59           0 :   WebAssemblyException *getParentException() const { return ParentException; }
      60          16 :   void setParentException(WebAssemblyException *WE) { ParentException = WE; }
      61             : 
      62             :   bool contains(const WebAssemblyException *WE) const {
      63             :     if (WE == this)
      64             :       return true;
      65             :     if (!WE)
      66             :       return false;
      67             :     return contains(WE->getParentException());
      68             :   }
      69             :   bool contains(const MachineBasicBlock *MBB) const {
      70          66 :     return BlockSet.count(MBB);
      71             :   }
      72             : 
      73         120 :   void addBlock(MachineBasicBlock *MBB) {
      74         120 :     Blocks.push_back(MBB);
      75         120 :     BlockSet.insert(MBB);
      76         120 :   }
      77             :   ArrayRef<MachineBasicBlock *> getBlocks() const { return Blocks; }
      78             :   using block_iterator = typename ArrayRef<MachineBasicBlock *>::const_iterator;
      79             :   block_iterator block_begin() const { return getBlocks().begin(); }
      80             :   block_iterator block_end() const { return getBlocks().end(); }
      81             :   inline iterator_range<block_iterator> blocks() const {
      82             :     return make_range(block_begin(), block_end());
      83             :   }
      84           6 :   unsigned getNumBlocks() const { return Blocks.size(); }
      85             :   std::vector<MachineBasicBlock *> &getBlocksVector() { return Blocks; }
      86             : 
      87             :   const std::vector<WebAssemblyException *> &getSubExceptions() const {
      88             :     return SubExceptions;
      89             :   }
      90             :   std::vector<WebAssemblyException *> &getSubExceptions() {
      91          47 :     return SubExceptions;
      92             :   }
      93             :   void addSubException(WebAssemblyException *E) { SubExceptions.push_back(E); }
      94             :   using iterator = typename std::vector<WebAssemblyException *>::const_iterator;
      95             :   iterator begin() const { return SubExceptions.begin(); }
      96             :   iterator end() const { return SubExceptions.end(); }
      97             : 
      98          31 :   void reserveBlocks(unsigned Size) { Blocks.reserve(Size); }
      99             :   void reverseBlock(unsigned From = 0) {
     100             :     std::reverse(Blocks.begin() + From, Blocks.end());
     101             :   }
     102             : 
     103             :   // Return the nesting level. An outermost one has depth 1.
     104           0 :   unsigned getExceptionDepth() const {
     105             :     unsigned D = 1;
     106           0 :     for (const WebAssemblyException *CurException = ParentException;
     107          22 :          CurException; CurException = CurException->ParentException)
     108          11 :       ++D;
     109           0 :     return D;
     110             :   }
     111             : 
     112             :   void print(raw_ostream &OS, unsigned Depth = 0) const;
     113             :   void dump() const;
     114             : };
     115             : 
     116             : raw_ostream &operator<<(raw_ostream &OS, const WebAssemblyException &WE);
     117             : 
     118             : class WebAssemblyExceptionInfo final : public MachineFunctionPass {
     119             :   // Mapping of basic blocks to the innermost exception they occur in
     120             :   DenseMap<const MachineBasicBlock *, WebAssemblyException *> BBMap;
     121             :   std::vector<WebAssemblyException *> TopLevelExceptions;
     122             : 
     123             :   void discoverAndMapException(WebAssemblyException *WE,
     124             :                                const MachineDominatorTree &MDT,
     125             :                                const MachineDominanceFrontier &MDF);
     126             :   WebAssemblyException *getOutermostException(MachineBasicBlock *MBB) const;
     127             : 
     128             : public:
     129             :   static char ID;
     130         309 :   WebAssemblyExceptionInfo() : MachineFunctionPass(ID) {
     131         309 :     initializeWebAssemblyExceptionInfoPass(*PassRegistry::getPassRegistry());
     132         309 :   }
     133         909 :   ~WebAssemblyExceptionInfo() override { releaseMemory(); }
     134             :   WebAssemblyExceptionInfo(const WebAssemblyExceptionInfo &) = delete;
     135             :   WebAssemblyExceptionInfo &
     136             :   operator=(const WebAssemblyExceptionInfo &) = delete;
     137             : 
     138             :   bool runOnMachineFunction(MachineFunction &) override;
     139             :   void releaseMemory() override;
     140             :   void recalculate(MachineDominatorTree &MDT,
     141             :                    const MachineDominanceFrontier &MDF);
     142             :   void getAnalysisUsage(AnalysisUsage &AU) const override;
     143             : 
     144             :   bool empty() const { return TopLevelExceptions.empty(); }
     145             : 
     146             :   // Return the innermost exception that MBB lives in. If the block is not in an
     147             :   // exception, null is returned.
     148             :   WebAssemblyException *getExceptionFor(const MachineBasicBlock *MBB) const {
     149       14577 :     return BBMap.lookup(MBB);
     150             :   }
     151             : 
     152          80 :   void changeExceptionFor(MachineBasicBlock *MBB, WebAssemblyException *WE) {
     153          80 :     if (!WE) {
     154           0 :       BBMap.erase(MBB);
     155           0 :       return;
     156             :     }
     157          80 :     BBMap[MBB] = WE;
     158             :   }
     159             : 
     160             :   void addTopLevelException(WebAssemblyException *WE) {
     161             :     assert(!WE->getParentException() && "Not a top level exception!");
     162          18 :     TopLevelExceptions.push_back(WE);
     163             :   }
     164             : 
     165             :   void print(raw_ostream &OS, const Module *M = nullptr) const override;
     166             : };
     167             : 
     168             : } // end namespace llvm
     169             : 
     170             : #endif

Generated by: LCOV version 1.13