//=== WebAssemblyLateEHPrepare.cpp - WebAssembly Exception Preparation -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// \brief Does various transformations for exception handling. /// //===----------------------------------------------------------------------===// #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "WebAssembly.h" #include "WebAssemblySubtarget.h" #include "WebAssemblyUtilities.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/WasmEHFuncInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Target/TargetMachine.h" usingnamespacellvm; #define DEBUG_TYPE … namespace { class WebAssemblyLateEHPrepare final : public MachineFunctionPass { … }; } // end anonymous namespace char WebAssemblyLateEHPrepare::ID = …; INITIALIZE_PASS(…) FunctionPass *llvm::createWebAssemblyLateEHPrepare() { … } // Returns the nearest EH pad that dominates this instruction. This does not use // dominator analysis; it just does BFS on its predecessors until arriving at an // EH pad. This assumes valid EH scopes so the first EH pad it arrives in all // possible search paths should be the same. // Returns nullptr in case it does not find any EH pad in the search, or finds // multiple different EH pads. MachineBasicBlock * WebAssemblyLateEHPrepare::getMatchingEHPad(MachineInstr *MI) { … } // Erase the specified BBs if the BB does not have any remaining predecessors, // and also all its dead children. template <typename Container> static void eraseDeadBBsAndChildren(const Container &MBBs) { … } bool WebAssemblyLateEHPrepare::runOnMachineFunction(MachineFunction &MF) { … } // Remove unreachable EH pads and its children. If they remain, CFG // stackification can be tricky. bool WebAssemblyLateEHPrepare::removeUnreachableEHPads(MachineFunction &MF) { … } // Record which BB ends with catchret instruction, because this will be replaced // with 'br's later. This set of catchret BBs is necessary in 'getMatchingEHPad' // function. void WebAssemblyLateEHPrepare::recordCatchRetBBs(MachineFunction &MF) { … } // Hoist catch instructions to the beginning of their matching EH pad BBs in // case, // (1) catch instruction is not the first instruction in EH pad. // ehpad: // some_other_instruction // ... // %exn = catch 0 // (2) catch instruction is in a non-EH pad BB. For example, // ehpad: // br bb0 // bb0: // %exn = catch 0 bool WebAssemblyLateEHPrepare::hoistCatches(MachineFunction &MF) { … } // Add catch_all to beginning of cleanup pads. bool WebAssemblyLateEHPrepare::addCatchAlls(MachineFunction &MF) { … } // Replace pseudo-instructions catchret and cleanupret with br and rethrow // respectively. bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) { … } // Add CATCH_REF and CATCH_ALL_REF pseudo instructions to EH pads, and convert // RETHROWs to THROW_REFs. bool WebAssemblyLateEHPrepare::addCatchRefsAndThrowRefs(MachineFunction &MF) { … } // Remove unnecessary unreachables after a throw/rethrow/throw_ref. bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables( MachineFunction &MF) { … } // After the stack is unwound due to a thrown exception, the __stack_pointer // global can point to an invalid address. This inserts instructions that // restore __stack_pointer global. bool WebAssemblyLateEHPrepare::restoreStackPointer(MachineFunction &MF) { … }