LCOV - code coverage report
Current view: top level - lib/Target/WebAssembly - WebAssemblyEHRestoreStackPointer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 19 19 100.0 %
Date: 2018-10-20 13:21:21 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- WebAssemblyEHRestoreStackPointer.cpp - __stack_pointer restoration ===//
       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             : /// After the stack is unwound due to a thrown exception, the __stack_pointer
      12             : /// global can point to an invalid address. This inserts instructions that
      13             : /// restore __stack_pointer global.
      14             : ///
      15             : //===----------------------------------------------------------------------===//
      16             : 
      17             : #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
      18             : #include "WebAssembly.h"
      19             : #include "WebAssemblySubtarget.h"
      20             : #include "WebAssemblyUtilities.h"
      21             : #include "llvm/CodeGen/MachineFrameInfo.h"
      22             : #include "llvm/MC/MCAsmInfo.h"
      23             : using namespace llvm;
      24             : 
      25             : #define DEBUG_TYPE "wasm-eh-restore-stack-pointer"
      26             : 
      27             : namespace {
      28             : class WebAssemblyEHRestoreStackPointer final : public MachineFunctionPass {
      29             : public:
      30             :   static char ID; // Pass identification, replacement for typeid
      31         305 :   WebAssemblyEHRestoreStackPointer() : MachineFunctionPass(ID) {}
      32             : 
      33         305 :   StringRef getPassName() const override {
      34         305 :     return "WebAssembly Restore Stack Pointer for Exception Handling";
      35             :   }
      36             : 
      37         305 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
      38         305 :     AU.setPreservesCFG();
      39         305 :     MachineFunctionPass::getAnalysisUsage(AU);
      40         305 :   }
      41             : 
      42             :   bool runOnMachineFunction(MachineFunction &MF) override;
      43             : };
      44             : } // end anonymous namespace
      45             : 
      46             : char WebAssemblyEHRestoreStackPointer::ID = 0;
      47      199030 : INITIALIZE_PASS(WebAssemblyEHRestoreStackPointer, DEBUG_TYPE,
      48             :                 "Restore Stack Pointer for Exception Handling", true, false)
      49             : 
      50         305 : FunctionPass *llvm::createWebAssemblyEHRestoreStackPointer() {
      51         305 :   return new WebAssemblyEHRestoreStackPointer();
      52             : }
      53             : 
      54        2983 : bool WebAssemblyEHRestoreStackPointer::runOnMachineFunction(
      55             :     MachineFunction &MF) {
      56             :   const auto *FrameLowering = static_cast<const WebAssemblyFrameLowering *>(
      57        2983 :       MF.getSubtarget().getFrameLowering());
      58        2983 :   if (!FrameLowering->needsPrologForEH(MF))
      59             :     return false;
      60             :   bool Changed = false;
      61             : 
      62          67 :   for (auto &MBB : MF) {
      63          59 :     if (!MBB.isEHPad())
      64          41 :       continue;
      65             :     Changed = true;
      66             : 
      67             :     // Insert __stack_pointer restoring instructions at the beginning of each EH
      68             :     // pad, after the catch instruction. (Catch instructions may have been
      69             :     // reordered, and catch_all instructions have not been inserted yet, but
      70             :     // those cases are handled in LateEHPrepare).
      71             :     //
      72             :     // Here it is safe to assume that SP32 holds the latest value of
      73             :     // __stack_pointer, because the only exception for this case is when a
      74             :     // function uses the red zone, but that only happens with leaf functions,
      75             :     // and we don't restore __stack_pointer in leaf functions anyway.
      76          18 :     auto InsertPos = MBB.begin();
      77          18 :     if (WebAssembly::isCatch(*MBB.begin()))
      78             :       InsertPos++;
      79          18 :     FrameLowering->writeSPToGlobal(WebAssembly::SP32, MF, MBB, InsertPos,
      80             :                                    MBB.begin()->getDebugLoc());
      81             :   }
      82             :   return Changed;
      83             : }

Generated by: LCOV version 1.13