Skip to content

[CodeGen] Port SjLjEHPrepare to new pass manager #75023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "llvm/CodeGen/ReplaceWithVeclib.h"
#include "llvm/CodeGen/SafeStack.h"
#include "llvm/CodeGen/SelectOptimize.h"
#include "llvm/CodeGen/SjLjEHPrepare.h"
#include "llvm/CodeGen/UnreachableBlockElim.h"
#include "llvm/CodeGen/WasmEHPrepare.h"
#include "llvm/CodeGen/WinEHPrepare.h"
Expand Down Expand Up @@ -679,7 +680,7 @@ void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(
// removed from the parent invoke(s). This could happen when a landing
// pad is shared by multiple invokes and is also a target of a normal
// edge from elsewhere.
addPass(SjLjEHPreparePass());
addPass(SjLjEHPreparePass(&TM));
[[fallthrough]];
case ExceptionHandling::DwarfCFI:
case ExceptionHandling::ARM:
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/MachinePassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ FUNCTION_PASS("replace-with-veclib", ReplaceWithVeclib, ())
FUNCTION_PASS("safe-stack", SafeStackPass, (TM))
FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass, ())
FUNCTION_PASS("select-optimize", SelectOptimizePass, (TM))
FUNCTION_PASS("sjlj-eh-prepare", SjLjEHPreparePass, (TM))
FUNCTION_PASS("tlshoist", TLSVariableHoistPass, ())
FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass, ())
FUNCTION_PASS("verify", VerifierPass, ())
Expand Down Expand Up @@ -130,7 +131,6 @@ DUMMY_FUNCTION_PASS("expandmemcmp", ExpandMemCmpPass, ())
DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())
DUMMY_FUNCTION_PASS("indirectbr-expand", IndirectBrExpandPass, ())
DUMMY_FUNCTION_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())
DUMMY_FUNCTION_PASS("sjljehprepare", SjLjEHPreparePass, ())
DUMMY_FUNCTION_PASS("stack-protector", StackProtectorPass, ())
#undef DUMMY_FUNCTION_PASS

Expand Down
28 changes: 28 additions & 0 deletions llvm/include/llvm/CodeGen/SjLjEHPrepare.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===-- llvm/CodeGen/SjLjEHPrepare.h -------------------------- -*- 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_SJLJEHPREPARE_H
#define LLVM_CODEGEN_SJLJEHPREPARE_H

#include "llvm/IR/PassManager.h"

namespace llvm {

class TargetMachine;

class SjLjEHPreparePass : public PassInfoMixin<SjLjEHPreparePass> {
const TargetMachine *TM;

public:
explicit SjLjEHPreparePass(const TargetMachine *TM) : TM(TM) {}
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
};

} // namespace llvm

#endif // LLVM_CODEGEN_SJLJEHPREPARE_H
67 changes: 43 additions & 24 deletions llvm/lib/CodeGen/SjLjEHPrepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/SjLjEHPrepare.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
Expand All @@ -31,13 +32,13 @@
#include "llvm/Transforms/Utils/Local.h"
using namespace llvm;

#define DEBUG_TYPE "sjljehprepare"
#define DEBUG_TYPE "sjlj-eh-prepare"

STATISTIC(NumInvokes, "Number of invokes replaced");
STATISTIC(NumSpilled, "Number of registers live across unwind edges");

namespace {
class SjLjEHPrepare : public FunctionPass {
class SjLjEHPrepareImpl {
IntegerType *DataTy = nullptr;
Type *doubleUnderDataTy = nullptr;
Type *doubleUnderJBufTy = nullptr;
Expand All @@ -55,16 +56,9 @@ class SjLjEHPrepare : public FunctionPass {
const TargetMachine *TM = nullptr;

public:
static char ID; // Pass identification, replacement for typeid
explicit SjLjEHPrepare(const TargetMachine *TM = nullptr)
: FunctionPass(ID), TM(TM) {}
bool doInitialization(Module &M) override;
bool runOnFunction(Function &F) override;

void getAnalysisUsage(AnalysisUsage &AU) const override {}
StringRef getPassName() const override {
return "SJLJ Exception Handling preparation";
}
explicit SjLjEHPrepareImpl(const TargetMachine *TM = nullptr) : TM(TM) {}
bool doInitialization(Module &M);
bool runOnFunction(Function &F);

private:
bool setupEntryBlockAndCallSites(Function &F);
Expand All @@ -74,8 +68,32 @@ class SjLjEHPrepare : public FunctionPass {
void lowerAcrossUnwindEdges(Function &F, ArrayRef<InvokeInst *> Invokes);
void insertCallSiteStore(Instruction *I, int Number);
};

class SjLjEHPrepare : public FunctionPass {
SjLjEHPrepareImpl Impl;

public:
static char ID; // Pass identification, replacement for typeid
explicit SjLjEHPrepare(const TargetMachine *TM = nullptr)
: FunctionPass(ID), Impl(TM) {}
bool doInitialization(Module &M) override { return Impl.doInitialization(M); }
bool runOnFunction(Function &F) override { return Impl.runOnFunction(F); };

StringRef getPassName() const override {
return "SJLJ Exception Handling preparation";
}
};

} // end anonymous namespace

PreservedAnalyses SjLjEHPreparePass::run(Function &F,
FunctionAnalysisManager &FAM) {
SjLjEHPrepareImpl Impl(TM);
Impl.doInitialization(*F.getParent());
bool Changed = Impl.runOnFunction(F);
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}

char SjLjEHPrepare::ID = 0;
INITIALIZE_PASS(SjLjEHPrepare, DEBUG_TYPE, "Prepare SjLj exceptions",
false, false)
Expand All @@ -87,7 +105,7 @@ FunctionPass *llvm::createSjLjEHPreparePass(const TargetMachine *TM) {

// doInitialization - Set up decalarations and types needed to process
// exceptions.
bool SjLjEHPrepare::doInitialization(Module &M) {
bool SjLjEHPrepareImpl::doInitialization(Module &M) {
// Build the function context structure.
// builtin_setjmp uses a five word jbuf
Type *VoidPtrTy = PointerType::getUnqual(M.getContext());
Expand All @@ -104,12 +122,12 @@ bool SjLjEHPrepare::doInitialization(Module &M) {
doubleUnderJBufTy // __jbuf
);

return true;
return false;
}

/// insertCallSiteStore - Insert a store of the call-site value to the
/// function context
void SjLjEHPrepare::insertCallSiteStore(Instruction *I, int Number) {
void SjLjEHPrepareImpl::insertCallSiteStore(Instruction *I, int Number) {
IRBuilder<> Builder(I);

// Get a reference to the call_site field.
Expand Down Expand Up @@ -140,8 +158,8 @@ static void MarkBlocksLiveIn(BasicBlock *BB,

/// substituteLPadValues - Substitute the values returned by the landingpad
/// instruction with those returned by the personality function.
void SjLjEHPrepare::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal,
Value *SelVal) {
void SjLjEHPrepareImpl::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal,
Value *SelVal) {
SmallVector<Value *, 8> UseWorkList(LPI->users());
while (!UseWorkList.empty()) {
Value *Val = UseWorkList.pop_back_val();
Expand Down Expand Up @@ -175,8 +193,9 @@ void SjLjEHPrepare::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal,

/// setupFunctionContext - Allocate the function context on the stack and fill
/// it with all of the data that we know at this point.
Value *SjLjEHPrepare::setupFunctionContext(Function &F,
ArrayRef<LandingPadInst *> LPads) {
Value *
SjLjEHPrepareImpl::setupFunctionContext(Function &F,
ArrayRef<LandingPadInst *> LPads) {
BasicBlock *EntryBB = &F.front();

// Create an alloca for the incoming jump buffer ptr and the new jump buffer
Expand Down Expand Up @@ -233,7 +252,7 @@ Value *SjLjEHPrepare::setupFunctionContext(Function &F,
/// specially, we lower each arg to a copy instruction in the entry block. This
/// ensures that the argument value itself cannot be live out of the entry
/// block.
void SjLjEHPrepare::lowerIncomingArguments(Function &F) {
void SjLjEHPrepareImpl::lowerIncomingArguments(Function &F) {
BasicBlock::iterator AfterAllocaInsPt = F.begin()->begin();
while (isa<AllocaInst>(AfterAllocaInsPt) &&
cast<AllocaInst>(AfterAllocaInsPt)->isStaticAlloca())
Expand Down Expand Up @@ -264,8 +283,8 @@ void SjLjEHPrepare::lowerIncomingArguments(Function &F) {

/// lowerAcrossUnwindEdges - Find all variables which are alive across an unwind
/// edge and spill them.
void SjLjEHPrepare::lowerAcrossUnwindEdges(Function &F,
ArrayRef<InvokeInst *> Invokes) {
void SjLjEHPrepareImpl::lowerAcrossUnwindEdges(Function &F,
ArrayRef<InvokeInst *> Invokes) {
// Finally, scan the code looking for instructions with bad live ranges.
for (BasicBlock &BB : F) {
for (Instruction &Inst : BB) {
Expand Down Expand Up @@ -358,7 +377,7 @@ void SjLjEHPrepare::lowerAcrossUnwindEdges(Function &F,
/// setupEntryBlockAndCallSites - Setup the entry block by creating and filling
/// the function context and marking the call sites with the appropriate
/// values. These values are used by the DWARF EH emitter.
bool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) {
bool SjLjEHPrepareImpl::setupEntryBlockAndCallSites(Function &F) {
SmallVector<ReturnInst *, 16> Returns;
SmallVector<InvokeInst *, 16> Invokes;
SmallSetVector<LandingPadInst *, 16> LPads;
Expand Down Expand Up @@ -479,7 +498,7 @@ bool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) {
return true;
}

bool SjLjEHPrepare::runOnFunction(Function &F) {
bool SjLjEHPrepareImpl::runOnFunction(Function &F) {
Module &M = *F.getParent();
RegisterFn = M.getOrInsertFunction(
"_Unwind_SjLj_Register", Type::getVoidTy(M.getContext()),
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
#include "llvm/CodeGen/JMCInstrumenter.h"
#include "llvm/CodeGen/SafeStack.h"
#include "llvm/CodeGen/SelectOptimize.h"
#include "llvm/CodeGen/SjLjEHPrepare.h"
#include "llvm/CodeGen/TypePromotion.h"
#include "llvm/CodeGen/WasmEHPrepare.h"
#include "llvm/CodeGen/WinEHPrepare.h"
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ FUNCTION_PASS("select-optimize", SelectOptimizePass(TM))
FUNCTION_PASS("separate-const-offset-from-gep",
SeparateConstOffsetFromGEPPass())
FUNCTION_PASS("sink", SinkingPass())
FUNCTION_PASS("sjlj-eh-prepare", SjLjEHPreparePass(TM))
FUNCTION_PASS("slp-vectorizer", SLPVectorizerPass())
FUNCTION_PASS("slsr", StraightLineStrengthReducePass())
FUNCTION_PASS("strip-gc-relocates", StripGCRelocates())
Expand Down
3 changes: 2 additions & 1 deletion llvm/test/CodeGen/ARM/sjljeh-swifterror.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt -sjljehprepare -verify < %s -S | FileCheck %s
; RUN: opt -sjlj-eh-prepare < %s -S | FileCheck %s
; RUN: opt -passes=sjlj-eh-prepare < %s -S | FileCheck %s
target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
target triple = "armv7s-apple-ios7.0"

Expand Down
3 changes: 1 addition & 2 deletions llvm/tools/opt/opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,7 @@ static bool shouldPinPassToLegacyPM(StringRef Pass) {
"nvptx-", "mips-", "lanai-", "hexagon-", "bpf-", "avr-",
"thumb2-", "arm-", "si-", "gcn-", "amdgpu-", "aarch64-",
"amdgcn-", "polly-", "riscv-", "dxil-"};
// TODO: remove "ehprepare"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lost the todo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the last pass ends with ehprepare. After #75024, ehprepare is no longer needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean the todo would now move to remove "-eh-prepare"?

Copy link
Contributor Author

@paperchalice paperchalice Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but there are already some TODOs covered this:

// TODO: remove shouldForceLegacyPM().

// For use in NPM transition. Currently this contains most codegen-specific
// passes. Remove passes from here when porting to the NPM.
// TODO: use a codegen version of PassRegistry.def/PassBuilder::is*Pass() once
// it exists.
static bool shouldPinPassToLegacyPM(StringRef Pass) {

std::vector<StringRef> PassNameContain = {"-eh-prepare", "ehprepare"};
std::vector<StringRef> PassNameContain = {"-eh-prepare"};
std::vector<StringRef> PassNameExact = {
"safe-stack",
"cost-model",
Expand Down