mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
690248bf52
If the landingpad of the invoke is using a personality function that catches asynch exceptions, then it can catch a trap. Also add some landingpads to invalid LLVM IR test cases that lack them. Over-the-shoulder reviewed by David Majnemer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228782 91177308-0d34-0410-b5e6-96231b3b80d8
103 lines
3.0 KiB
C++
103 lines
3.0 KiB
C++
//===-- WinEHPrepare - Prepare exception handling for code generation ---===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This pass lowers LLVM IR exception handling into something closer to what the
|
|
// backend wants. It snifs the personality function to see which kind of
|
|
// preparation is necessary. If the personality function uses the Itanium LSDA,
|
|
// this pass delegates to the DWARF EH preparation pass.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/Passes.h"
|
|
#include "llvm/Analysis/LibCallSemantics.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/Pass.h"
|
|
#include <memory>
|
|
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "winehprepare"
|
|
|
|
namespace {
|
|
class WinEHPrepare : public FunctionPass {
|
|
std::unique_ptr<FunctionPass> DwarfPrepare;
|
|
|
|
public:
|
|
static char ID; // Pass identification, replacement for typeid.
|
|
WinEHPrepare(const TargetMachine *TM = nullptr)
|
|
: FunctionPass(ID), DwarfPrepare(createDwarfEHPass(TM)) {}
|
|
|
|
bool runOnFunction(Function &Fn) override;
|
|
|
|
bool doFinalization(Module &M) override;
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
|
|
|
const char *getPassName() const override {
|
|
return "Windows exception handling preparation";
|
|
}
|
|
};
|
|
} // end anonymous namespace
|
|
|
|
char WinEHPrepare::ID = 0;
|
|
INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare",
|
|
"Prepare Windows exceptions", false, false)
|
|
|
|
FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
|
|
return new WinEHPrepare(TM);
|
|
}
|
|
|
|
static bool isMSVCPersonality(EHPersonality Pers) {
|
|
return Pers == EHPersonality::MSVC_Win64SEH ||
|
|
Pers == EHPersonality::MSVC_CXX;
|
|
}
|
|
|
|
bool WinEHPrepare::runOnFunction(Function &Fn) {
|
|
SmallVector<LandingPadInst *, 4> LPads;
|
|
SmallVector<ResumeInst *, 4> Resumes;
|
|
for (BasicBlock &BB : Fn) {
|
|
if (auto *LP = BB.getLandingPadInst())
|
|
LPads.push_back(LP);
|
|
if (auto *Resume = dyn_cast<ResumeInst>(BB.getTerminator()))
|
|
Resumes.push_back(Resume);
|
|
}
|
|
|
|
// No need to prepare functions that lack landing pads.
|
|
if (LPads.empty())
|
|
return false;
|
|
|
|
// Classify the personality to see what kind of preparation we need.
|
|
EHPersonality Pers = classifyEHPersonality(LPads.back()->getPersonalityFn());
|
|
|
|
// Delegate through to the DWARF pass if this is unrecognized.
|
|
if (!isMSVCPersonality(Pers))
|
|
return DwarfPrepare->runOnFunction(Fn);
|
|
|
|
// FIXME: Cleanups are unimplemented. Replace them with unreachable.
|
|
if (Resumes.empty())
|
|
return false;
|
|
|
|
for (ResumeInst *Resume : Resumes) {
|
|
IRBuilder<>(Resume).CreateUnreachable();
|
|
Resume->eraseFromParent();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool WinEHPrepare::doFinalization(Module &M) {
|
|
return DwarfPrepare->doFinalization(M);
|
|
}
|
|
|
|
void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
|
|
DwarfPrepare->getAnalysisUsage(AU);
|
|
}
|