Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Unified Diff: lib/Transforms/NaCl/LowerEmExceptionsPass.cpp

Issue 1692803002: Remove Emscripten support (Closed) Base URL: https://chromium.googlesource.com/a/native_client/pnacl-llvm.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/Transforms/NaCl/LowerEmAsyncify.cpp ('k') | lib/Transforms/NaCl/LowerEmSetjmp.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
diff --git a/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp b/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
deleted file mode 100644
index 676a0a68050e648f3e6f53bf4b1f93b3948a3322..0000000000000000000000000000000000000000
--- a/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-//===- LowerEmExceptions - Lower exceptions for Emscripten/JS -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is based off the 'cheap' version of LowerInvoke. It does two things:
-//
-// 1) Lower
-// invoke() to l1 unwind l2
-// into
-// preinvoke(); // (will clear __THREW__)
-// call();
-// threw = postinvoke(); (check __THREW__)
-// br threw, l1, l2
-//
-// We do this to avoid introducing a new LLVM IR type, or to try to reuse
-// invoke-landingpad for our special purposes (as they are checked very
-// carefully by llvm)
-//
-// 2) Lower landingpads to a call to emscripten_landingpad
-//
-// 3) Lower resume to emscripten_resume which receives non-aggregate inputs
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/NaCl.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <vector>
-#include <set>
-
-#ifdef NDEBUG
-#undef assert
-#define assert(x) { if (!(x)) report_fatal_error(#x); }
-#endif
-
-using namespace llvm;
-
-static cl::list<std::string>
-Whitelist("emscripten-cxx-exceptions-whitelist",
- cl::desc("Enables C++ exceptions in emscripten (see emscripten EXCEPTION_CATCHING_WHITELIST option)"),
- cl::CommaSeparated);
-
-namespace {
- class LowerEmExceptions : public ModulePass {
- Function *GetHigh, *PreInvoke, *PostInvoke, *LandingPad, *Resume;
- Module *TheModule;
-
- public:
- static char ID; // Pass identification, replacement for typeid
- explicit LowerEmExceptions() : ModulePass(ID), GetHigh(NULL), PreInvoke(NULL), PostInvoke(NULL), LandingPad(NULL), Resume(NULL), TheModule(NULL) {
- initializeLowerEmExceptionsPass(*PassRegistry::getPassRegistry());
- }
- bool runOnModule(Module &M);
- };
-}
-
-char LowerEmExceptions::ID = 0;
-INITIALIZE_PASS(LowerEmExceptions, "loweremexceptions",
- "Lower invoke and unwind for js/emscripten",
- false, false)
-
-bool canThrow(Value *V) {
- if (Function *F = dyn_cast<Function>(V)) {
- // intrinsics and some emscripten builtins cannot throw
- if (F->isIntrinsic()) return false;
- StringRef Name = F->getName();
- if (Name.startswith("emscripten_asm_")) return false;
- if (Name == "setjmp" || Name == "longjmp") return false; // leave setjmp and longjmp (mostly) alone, we process them properly later
- return true;
- }
- return true; // not a function, so an indirect call - can throw, we can't tell
-}
-
-bool LowerEmExceptions::runOnModule(Module &M) {
- TheModule = &M;
-
- // Add functions
-
- Type *i32 = Type::getInt32Ty(M.getContext());
- Type *i8 = Type::getInt8Ty(M.getContext());
- Type *i1 = Type::getInt1Ty(M.getContext());
- Type *i8P = i8->getPointerTo();
- Type *Void = Type::getVoidTy(M.getContext());
-
- if (!(GetHigh = TheModule->getFunction("getHigh32"))) {
- FunctionType *GetHighFunc = FunctionType::get(i32, false);
- GetHigh = Function::Create(GetHighFunc, GlobalValue::ExternalLinkage,
- "getHigh32", TheModule);
- }
-
- if (!(PreInvoke = TheModule->getFunction("emscripten_preinvoke"))) {
- FunctionType *VoidFunc = FunctionType::get(Void, false);
- PreInvoke = Function::Create(VoidFunc, GlobalValue::ExternalLinkage, "emscripten_preinvoke", TheModule);
- }
-
- if (!(PostInvoke = TheModule->getFunction("emscripten_postinvoke"))) {
- FunctionType *IntFunc = FunctionType::get(i32, false);
- PostInvoke = Function::Create(IntFunc, GlobalValue::ExternalLinkage, "emscripten_postinvoke", TheModule);
- }
-
- FunctionType *LandingPadFunc = FunctionType::get(i8P, true);
- LandingPad = Function::Create(LandingPadFunc, GlobalValue::ExternalLinkage, "emscripten_landingpad", TheModule);
-
- FunctionType *ResumeFunc = FunctionType::get(Void, true);
- Resume = Function::Create(ResumeFunc, GlobalValue::ExternalLinkage, "emscripten_resume", TheModule);
-
- // Process
-
- std::set<std::string> WhitelistSet(Whitelist.begin(), Whitelist.end());
-
- bool Changed = false;
-
- for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) {
- Function *F = Iter++;
-
- std::vector<Instruction*> ToErase;
- std::set<LandingPadInst*> LandingPads;
-
- bool AllowExceptionsInFunc = WhitelistSet.empty() || (WhitelistSet.count("_" + F->getName().str()) != 0);
-
- for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
- // check terminator for invokes
- if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
- LandingPads.insert(II->getLandingPadInst());
-
- bool NeedInvoke = AllowExceptionsInFunc && canThrow(II->getCalledValue());
-
- if (NeedInvoke) {
- // If we are calling a function that is noreturn, we must remove that attribute. The code we
- // insert here does expect it to return, after we catch the exception.
- if (II->doesNotReturn()) {
- if (Function *F = dyn_cast<Function>(II->getCalledValue())) {
- F->removeFnAttr(Attribute::NoReturn);
- }
- II->setAttributes(II->getAttributes().removeAttribute(TheModule->getContext(), AttributeSet::FunctionIndex, Attribute::NoReturn));
- assert(!II->doesNotReturn());
- }
-
- // Insert a normal call instruction folded in between pre- and post-invoke
- CallInst::Create(PreInvoke, "", II);
-
- SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
- CallInst *NewCall = CallInst::Create(II->getCalledValue(),
- CallArgs, "", II);
- NewCall->takeName(II);
- NewCall->setCallingConv(II->getCallingConv());
- NewCall->setAttributes(II->getAttributes());
- NewCall->setDebugLoc(II->getDebugLoc());
- II->replaceAllUsesWith(NewCall);
- ToErase.push_back(II);
-
- CallInst *Post = CallInst::Create(PostInvoke, "", II);
- Instruction *Post1 = new TruncInst(Post, i1, "", II);
-
- // Insert a branch based on the postInvoke
- BranchInst::Create(II->getUnwindDest(), II->getNormalDest(), Post1, II);
- } else {
- // This can't throw, and we don't need this invoke, just replace it with a call+branch
- SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
- CallInst *NewCall = CallInst::Create(II->getCalledValue(),
- CallArgs, "", II);
- NewCall->takeName(II);
- NewCall->setCallingConv(II->getCallingConv());
- NewCall->setAttributes(II->getAttributes());
- NewCall->setDebugLoc(II->getDebugLoc());
- II->replaceAllUsesWith(NewCall);
- ToErase.push_back(II);
-
- BranchInst::Create(II->getNormalDest(), II);
-
- // Remove any PHI node entries from the exception destination.
- II->getUnwindDest()->removePredecessor(BB);
- }
-
- Changed = true;
- }
- // scan the body of the basic block for resumes
- for (BasicBlock::iterator Iter = BB->begin(), E = BB->end();
- Iter != E; ) {
- Instruction *I = Iter++;
- if (ResumeInst *R = dyn_cast<ResumeInst>(I)) {
- // split the input into legal values
- Value *Input = R->getValue();
- ExtractValueInst *Low = ExtractValueInst::Create(Input, 0, "", R);
- ExtractValueInst *High = ExtractValueInst::Create(Input, 1, "", R);
-
- // create a resume call
- SmallVector<Value*,2> CallArgs;
- CallArgs.push_back(Low);
- CallArgs.push_back(High);
- CallInst::Create(Resume, CallArgs, "", R);
-
- new UnreachableInst(TheModule->getContext(), R); // add a terminator to the block
-
- ToErase.push_back(R);
- }
- }
- }
-
- // Look for orphan landingpads, can occur in blocks with no predecesors
- for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
- Instruction *I = BB->getFirstNonPHI();
- if (LandingPadInst *LP = dyn_cast<LandingPadInst>(I)) {
- LandingPads.insert(LP);
- }
- }
-
- // Handle all the landingpad for this function together, as multiple invokes may share a single lp
- for (std::set<LandingPadInst*>::iterator I = LandingPads.begin(); I != LandingPads.end(); I++) {
- // Replace the landingpad with a landingpad call to get the low part, and a getHigh for the high
- LandingPadInst *LP = *I;
- unsigned Num = LP->getNumClauses();
- SmallVector<Value*,16> NewLPArgs;
- NewLPArgs.push_back(LP->getPersonalityFn());
- for (unsigned i = 0; i < Num; i++) {
- Value *Arg = LP->getClause(i);
- // As a temporary workaround for the lack of aggregate varargs support
- // in the varargs lowering code, break out filter operands into their
- // component elements.
- if (LP->isFilter(i)) {
- ArrayType *ATy = cast<ArrayType>(Arg->getType());
- for (unsigned elem = 0, elemEnd = ATy->getNumElements(); elem != elemEnd; ++elem) {
- Instruction *EE = ExtractValueInst::Create(Arg, makeArrayRef(elem), "", LP);
- NewLPArgs.push_back(EE);
- }
- } else {
- NewLPArgs.push_back(Arg);
- }
- }
- NewLPArgs.push_back(LP->isCleanup() ? ConstantInt::getTrue(i1) : ConstantInt::getFalse(i1));
- CallInst *NewLP = CallInst::Create(LandingPad, NewLPArgs, "", LP);
-
- Instruction *High = CallInst::Create(GetHigh, "", LP);
-
- // New recreate an aggregate for them, which will be all simplified later (simplification cannot handle landingpad, hence all this)
- InsertValueInst *IVA = InsertValueInst::Create(UndefValue::get(LP->getType()), NewLP, 0, "", LP);
- InsertValueInst *IVB = InsertValueInst::Create(IVA, High, 1, "", LP);
-
- LP->replaceAllUsesWith(IVB);
- ToErase.push_back(LP);
- }
-
- // erase everything we no longer need in this function
- for (unsigned i = 0; i < ToErase.size(); i++) ToErase[i]->eraseFromParent();
- }
-
- return Changed;
-}
-
-ModulePass *llvm::createLowerEmExceptionsPass() {
- return new LowerEmExceptions();
-}
-
« no previous file with comments | « lib/Transforms/NaCl/LowerEmAsyncify.cpp ('k') | lib/Transforms/NaCl/LowerEmSetjmp.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698