mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
9b48b7e7be
When Emscripten EH mixes with Emscripten SjLj, we are not currently handling some of them correctly. There are three cases: 1. The current function calls `setjmp` and there is an `invoke` to a function that can either throw or longjmp. In this case, we have to check both for exception and longjmp. We are currently handling this case correctly:0c0eb76782/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp (L1058-L1090)
When inserting routines for functions that can longjmp, which we do only for setjmp-calling functions, we check if the function was previously an `invoke` and handle it correctly. 2. The current function does NOT call `setjmp` and there is an `invoke` to a function that can either throw or longjmp. Because there is no `setjmp` call, we haven't been doing any check for functions that can longjmp. But in that case, for `invoke`, we only check for an exception and if it is not an exception we reset `__THREW__` to 0, which can silently swallow the longjmp:0c0eb76782/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp (L70-L80)
This CL fixes this. 3. The current function calls `setjmp` and there is no `invoke`. Because it is not an `invoke`, we haven't been doing any check for functions that can throw, and only insert longjmp-checking routines for functions that can longjmp. But in that case, if a longjmpable function throws, we only check for a longjmp so if it is not a longjmp we reset `__THREW__` to 0, which can silently swallow the exception:0c0eb76782/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp (L156-L169)
This CL fixes this. To do that, this moves around some code, so we register necessary functions for both EH and SjLj and precompute some data (the set of functions that contains `setjmp`) before doing actual EH or SjLj transformation. This CL makes 2nd and 3rd tests in https://github.com/emscripten-core/emscripten/pull/14732 work. Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D106525
109 lines
4.5 KiB
C++
109 lines
4.5 KiB
C++
//===-- WebAssembly.h - Top-level interface for WebAssembly ----*- C++ -*-===//
|
|
//
|
|
// 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
|
|
/// This file contains the entry points for global functions defined in
|
|
/// the LLVM WebAssembly back-end.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLY_H
|
|
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLY_H
|
|
|
|
#include "llvm/PassRegistry.h"
|
|
#include "llvm/Support/CodeGen.h"
|
|
|
|
namespace llvm {
|
|
|
|
class WebAssemblyTargetMachine;
|
|
class ModulePass;
|
|
class FunctionPass;
|
|
|
|
// LLVM IR passes.
|
|
ModulePass *createWebAssemblyLowerEmscriptenEHSjLj(bool EnableEH,
|
|
bool EnableSjLj);
|
|
ModulePass *createWebAssemblyLowerGlobalDtors();
|
|
ModulePass *createWebAssemblyAddMissingPrototypes();
|
|
ModulePass *createWebAssemblyFixFunctionBitcasts();
|
|
FunctionPass *createWebAssemblyOptimizeReturned();
|
|
|
|
// ISel and immediate followup passes.
|
|
FunctionPass *createWebAssemblyISelDag(WebAssemblyTargetMachine &TM,
|
|
CodeGenOpt::Level OptLevel);
|
|
FunctionPass *createWebAssemblyArgumentMove();
|
|
FunctionPass *createWebAssemblySetP2AlignOperands();
|
|
|
|
// Late passes.
|
|
FunctionPass *createWebAssemblyReplacePhysRegs();
|
|
FunctionPass *createWebAssemblyNullifyDebugValueLists();
|
|
FunctionPass *createWebAssemblyPrepareForLiveIntervals();
|
|
FunctionPass *createWebAssemblyOptimizeLiveIntervals();
|
|
FunctionPass *createWebAssemblyMemIntrinsicResults();
|
|
FunctionPass *createWebAssemblyRegStackify();
|
|
FunctionPass *createWebAssemblyRegColoring();
|
|
FunctionPass *createWebAssemblyFixBrTableDefaults();
|
|
FunctionPass *createWebAssemblyFixIrreducibleControlFlow();
|
|
FunctionPass *createWebAssemblyLateEHPrepare();
|
|
FunctionPass *createWebAssemblyCFGSort();
|
|
FunctionPass *createWebAssemblyCFGStackify();
|
|
FunctionPass *createWebAssemblyExplicitLocals();
|
|
FunctionPass *createWebAssemblyLowerBrUnless();
|
|
FunctionPass *createWebAssemblyRegNumbering();
|
|
FunctionPass *createWebAssemblyDebugFixup();
|
|
FunctionPass *createWebAssemblyPeephole();
|
|
FunctionPass *createWebAssemblyMCLowerPrePass();
|
|
|
|
// PassRegistry initialization declarations.
|
|
void initializeWebAssemblyAddMissingPrototypesPass(PassRegistry &);
|
|
void initializeWebAssemblyLowerEmscriptenEHSjLjPass(PassRegistry &);
|
|
void initializeLowerGlobalDtorsPass(PassRegistry &);
|
|
void initializeFixFunctionBitcastsPass(PassRegistry &);
|
|
void initializeOptimizeReturnedPass(PassRegistry &);
|
|
void initializeWebAssemblyArgumentMovePass(PassRegistry &);
|
|
void initializeWebAssemblySetP2AlignOperandsPass(PassRegistry &);
|
|
void initializeWebAssemblyReplacePhysRegsPass(PassRegistry &);
|
|
void initializeWebAssemblyNullifyDebugValueListsPass(PassRegistry &);
|
|
void initializeWebAssemblyPrepareForLiveIntervalsPass(PassRegistry &);
|
|
void initializeWebAssemblyOptimizeLiveIntervalsPass(PassRegistry &);
|
|
void initializeWebAssemblyMemIntrinsicResultsPass(PassRegistry &);
|
|
void initializeWebAssemblyRegStackifyPass(PassRegistry &);
|
|
void initializeWebAssemblyRegColoringPass(PassRegistry &);
|
|
void initializeWebAssemblyFixBrTableDefaultsPass(PassRegistry &);
|
|
void initializeWebAssemblyFixIrreducibleControlFlowPass(PassRegistry &);
|
|
void initializeWebAssemblyLateEHPreparePass(PassRegistry &);
|
|
void initializeWebAssemblyExceptionInfoPass(PassRegistry &);
|
|
void initializeWebAssemblyCFGSortPass(PassRegistry &);
|
|
void initializeWebAssemblyCFGStackifyPass(PassRegistry &);
|
|
void initializeWebAssemblyExplicitLocalsPass(PassRegistry &);
|
|
void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &);
|
|
void initializeWebAssemblyRegNumberingPass(PassRegistry &);
|
|
void initializeWebAssemblyDebugFixupPass(PassRegistry &);
|
|
void initializeWebAssemblyPeepholePass(PassRegistry &);
|
|
void initializeWebAssemblyMCLowerPrePassPass(PassRegistry &);
|
|
|
|
namespace WebAssembly {
|
|
enum TargetIndex {
|
|
// Followed by a local index (ULEB).
|
|
TI_LOCAL,
|
|
// Followed by an absolute global index (ULEB). DEPRECATED.
|
|
TI_GLOBAL_FIXED,
|
|
// Followed by the index from the bottom of the Wasm stack.
|
|
TI_OPERAND_STACK,
|
|
// Followed by a compilation unit relative global index (uint32_t)
|
|
// that will have an associated relocation.
|
|
TI_GLOBAL_RELOC,
|
|
// Like TI_LOCAL, but indicates an indirect value (e.g. byval arg
|
|
// passed by pointer).
|
|
TI_LOCAL_INDIRECT
|
|
};
|
|
} // end namespace WebAssembly
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|