LLVM  8.0.1
WebAssemblyEHRestoreStackPointer.cpp
Go to the documentation of this file.
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 
18 #include "WebAssembly.h"
19 #include "WebAssemblySubtarget.h"
20 #include "WebAssemblyUtilities.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  WebAssemblyEHRestoreStackPointer() : MachineFunctionPass(ID) {}
32 
33  StringRef getPassName() const override {
34  return "WebAssembly Restore Stack Pointer for Exception Handling";
35  }
36 
37  void getAnalysisUsage(AnalysisUsage &AU) const override {
38  AU.setPreservesCFG();
40  }
41 
42  bool runOnMachineFunction(MachineFunction &MF) override;
43 };
44 } // end anonymous namespace
45 
47 INITIALIZE_PASS(WebAssemblyEHRestoreStackPointer, DEBUG_TYPE,
48  "Restore Stack Pointer for Exception Handling", true, false)
49 
51  return new WebAssemblyEHRestoreStackPointer();
52 }
53 
54 bool WebAssemblyEHRestoreStackPointer::runOnMachineFunction(
55  MachineFunction &MF) {
56  LLVM_DEBUG(dbgs() << "********** EH Restore Stack Pointer **********\n"
57  "********** Function: "
58  << MF.getName() << '\n');
59 
60  const auto *FrameLowering = static_cast<const WebAssemblyFrameLowering *>(
62  if (!FrameLowering->needsPrologForEH(MF))
63  return false;
64  bool Changed = false;
65 
66  for (auto &MBB : MF) {
67  if (!MBB.isEHPad())
68  continue;
69  Changed = true;
70 
71  // Insert __stack_pointer restoring instructions at the beginning of each EH
72  // pad, after the catch instruction. (Catch instructions may have been
73  // reordered, and catch_all instructions have not been inserted yet, but
74  // those cases are handled in LateEHPrepare).
75  //
76  // Here it is safe to assume that SP32 holds the latest value of
77  // __stack_pointer, because the only exception for this case is when a
78  // function uses the red zone, but that only happens with leaf functions,
79  // and we don't restore __stack_pointer in leaf functions anyway.
80  auto InsertPos = MBB.begin();
81  if (WebAssembly::isCatch(*MBB.begin()))
82  InsertPos++;
83  FrameLowering->writeSPToGlobal(WebAssembly::SP32, MF, MBB, InsertPos,
84  MBB.begin()->getDebugLoc());
85  }
86  return Changed;
87 }
This class represents lattice values for constants.
Definition: AllocatorList.h:24
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
FunctionPass * createWebAssemblyEHRestoreStackPointer()
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
This file contains the declaration of the WebAssembly-specific utility functions. ...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
This file provides WebAssembly-specific target descriptions.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
This file declares the WebAssembly-specific subclass of TargetSubtarget.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:286
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
virtual const TargetFrameLowering * getFrameLowering() const
bool isCatch(const MachineInstr &MI)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
#define LLVM_DEBUG(X)
Definition: Debug.h:123
INITIALIZE_PASS(WebAssemblyEHRestoreStackPointer, DEBUG_TYPE, "Restore Stack Pointer for Exception Handling", true, false) FunctionPass *llvm