86#include "llvm/IR/IntrinsicsWebAssembly.h" 
   93#define DEBUG_TYPE "wasm-eh-prepare" 
   96class WasmEHPrepareImpl {
 
   97  friend class WasmEHPrepare;
 
   99  Type *LPadContextTy = 
nullptr; 
 
  103  Value *LPadIndexField = 
nullptr; 
 
  104  Value *LSDAField = 
nullptr;      
 
  105  Value *SelectorField = 
nullptr;  
 
  118  void prepareEHPad(
BasicBlock *BB, 
bool NeedPersonality, 
unsigned Index = 0);
 
  121  WasmEHPrepareImpl() = 
default;
 
  122  WasmEHPrepareImpl(
Type *LPadContextTy_) : LPadContextTy(LPadContextTy_) {}
 
  133  bool doInitialization(
Module &M) 
override;
 
  137    return "WebAssembly Exception handling preparation";
 
  145  auto &Context = 
F.getContext();
 
  148  auto *LPadContextTy =
 
  150  WasmEHPrepareImpl 
P(LPadContextTy);
 
 
  155char WasmEHPrepare::ID = 0;
 
  157                      "Prepare WebAssembly exceptions", 
false, 
false)
 
  163bool WasmEHPrepare::doInitialization(
Module &M) {
 
  174template <
typename Container>
 
  177  while (!WL.
empty()) {
 
 
  186bool WasmEHPrepareImpl::runOnFunction(
Function &
F) {
 
  193bool WasmEHPrepareImpl::prepareThrows(
Function &
F) {
 
  205    if (!ThrowI || ThrowI->getFunction() != &
F)
 
  208    auto *BB = ThrowI->getParent();
 
  211    IRB.SetInsertPoint(BB);
 
  212    IRB.CreateUnreachable();
 
  219bool WasmEHPrepareImpl::prepareEHPads(
Function &
F) {
 
  237  if (!
F.hasPersonalityFn() ||
 
  240                       "' does not have a correct Wasm personality function " 
  241                       "'__gxx_wasm_personality_v0'");
 
  243  assert(
F.hasPersonalityFn() && 
"Personality function not found");
 
  250  LPadContextGV = 
M.getOrInsertGlobal(
"__wasm_lpad_context", LPadContextTy);
 
  253  LPadIndexField = LPadContextGV;
 
  254  LSDAField = IRB.CreateConstInBoundsGEP2_32(LPadContextTy, LPadContextGV, 0, 1,
 
  256  SelectorField = IRB.CreateConstInBoundsGEP2_32(LPadContextTy, LPadContextGV,
 
  257                                                 0, 2, 
"selector_gep");
 
  277  CallPersonalityF = 
M.getOrInsertFunction(
"_Unwind_CallPersonality",
 
  278                                           IRB.getInt32Ty(), IRB.getPtrTy());
 
  280    F->setDoesNotThrow();
 
  283  for (
auto *BB : CatchPads) {
 
  287    if (CPI->arg_size() == 1 &&
 
  289      prepareEHPad(BB, 
false);
 
  291      prepareEHPad(BB, 
true, Index++);
 
  295  for (
auto *BB : CleanupPads)
 
  296    prepareEHPad(BB, 
false);
 
  303void WasmEHPrepareImpl::prepareEHPad(
BasicBlock *BB, 
bool NeedPersonality,
 
  310  Instruction *GetExnCI = 
nullptr, *GetSelectorCI = 
nullptr;
 
  311  for (
auto &U : FPI->uses()) {
 
  313      if (CI->getCalledOperand() == GetExnF)
 
  315      if (CI->getCalledOperand() == GetSelectorF)
 
  324           "wasm.get.ehselector() cannot exist w/o wasm.get.exception()");
 
  339  if (!NeedPersonality) {
 
  341      assert(GetSelectorCI->use_empty() &&
 
  342             "wasm.get.ehselector() still has uses!");
 
  343      GetSelectorCI->eraseFromParent();
 
  352  IRB.CreateCall(LPadIndexF, {FPI, IRB.getInt32(Index)});
 
  355  IRB.CreateStore(IRB.getInt32(Index), LPadIndexField);
 
  362  IRB.CreateStore(IRB.CreateCall(LSDAF), LSDAField);
 
  365  CallInst *PersCI = IRB.CreateCall(CallPersonalityF, CatchCI,
 
  371      IRB.CreateLoad(IRB.getInt32Ty(), SelectorField, 
"selector");
 
  375  assert(GetSelectorCI && 
"wasm.get.ehselector() call does not exist");
 
  376  GetSelectorCI->replaceAllUsesWith(Selector);
 
  377  GetSelectorCI->eraseFromParent();
 
  385  for (
const auto &BB : *
F) {
 
  391      const auto *UnwindBB = CatchPad->getCatchSwitch()->getUnwindDest();
 
  394      const Instruction *UnwindPad = &*UnwindBB->getFirstNonPHIIt();
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static bool runOnFunction(Function &F, bool PostInlining)
 
Module.h This file contains the declarations for the Module class.
 
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
 
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
 
static void eraseDeadBBsAndChildren(const Container &BBs)
 
LLVM Basic Block Representation.
 
iterator begin()
Instruction iterator methods.
 
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
 
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
 
InstListType::iterator iterator
Instruction iterators...
 
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
 
bool isEHPad() const
Return true if this basic block is an exception handling block.
 
This class represents a function call, abstracting a target machine's calling convention.
 
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
 
FunctionPass class - This class is used to implement most global optimizations.
 
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
 
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
 
A Module instance is used to store all the information related to an LLVM module.
 
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
 
A set of analyses that are preserved following a run of a transformation pass.
 
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
 
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
 
void push_back(const T &Elt)
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
StringRef - Represent a constant reference to a string, i.e.
 
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
 
The instances of the Type class are immutable: once they are created, they are never changed.
 
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
 
LLVM Value Representation.
 
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
 
iterator_range< user_iterator > users()
 
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
 
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
 
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
 
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
 
This is an optimization pass for GlobalISel generic memory operations.
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
auto successors(const MachineBasicBlock *BB)
 
LLVM_ABI FunctionPass * createWasmEHPass()
createWasmEHPass - This pass adapts exception handling code to use WebAssembly's exception handling s...
 
LLVM_ABI void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified block, which must have no predecessors.
 
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
 
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
 
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
 
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
 
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
 
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
 
OperandBundleDefT< Value * > OperandBundleDef
 
void calculateWasmEHInfo(const Function *F, WasmEHFuncInfo &EHInfo)
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
bool pred_empty(const BasicBlock *BB)
 
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
 
void setUnwindDest(const BasicBlock *BB, const BasicBlock *Dest)