55 return F.hasUWTable() && !
F.doesNotThrow();
63 BPFUnwindPrepare() : ModulePass(ID) {}
64 StringRef getPassName()
const override {
return "BPF Unwind Prepare"; }
66 static bool isRaise(
const CallBase &CB) {
71 static bool mayUnwind(
const Instruction &
I) {
77 bool runOnModule(
Module &M)
override {
84 LLVMContext &
C =
M.getContext();
88 if (CB && isRaise(*CB)) {
90 for (Use &Arg : CB->
args())
109 if (!
F.hasPersonalityFn())
111 M.getOrInsertFunction(
"__gcc_personality_v0",
112 FunctionType::get(Type::getInt32Ty(
C),
true))
116 LandingPadInst *LP =
B.CreateLandingPad(
120 for (CallInst *CI : Calls)
132 BPFUnwindLower() : MachineFunctionPass(ID) {}
133 StringRef getPassName()
const override {
return "BPF Unwind Lower"; }
136 StringRef UnwindResume;
138 bool leavesFrame(
const MachineInstr &
MI)
const {
139 const MachineOperand &MO =
MI.getOperand(0);
148 static void endBlockAfter(MachineInstr &
MI, MachineBasicBlock *Succ) {
159 static void eraseArg(MachineInstr &
Call) {
164 if (
I->getOpcode() == BPF::MOV_ri &&
I->getOperand(0).getReg() == BPF::R1)
165 I->eraseFromParent();
173 return "BPF needs uwtable on a function with a landing pad";
176 for (
int TId : LP.TypeIds) {
178 return "BPF does not support type-specific exception catches yet";
182 return "BPF does not support exception filters yet";
192 RTLIB::UNWIND_RESUME);
193 DenseMap<MCSymbol *, MachineBasicBlock *> Begin;
195 SmallVector<MachineInstr *, 8> Labels, Resumes;
196 SmallSetVector<MachineBasicBlock *, 8> Pads;
205 for (MCSymbol *Sym : LP.BeginLabels)
206 Begin[Sym] = LP.LandingPadBlock;
210 SmallPtrSet<MachineInstr *, 8> Invokes;
211 for (MachineBasicBlock &
MBB : MF) {
212 for (MachineInstr &Label :
MBB) {
213 if (!
Label.isEHLabel())
216 MachineBasicBlock *Pad =
222 Work{{&
MBB, std::next(
Label.getIterator())}};
223 SmallPtrSet<MachineBasicBlock *, 4> Seen;
224 while (!Work.
empty()) {
227 for (;
I != Cur->end() && !
I->isEHLabel(); ++
I)
228 if (
I->isCall() && Invokes.
insert(&*
I).second)
232 for (MachineBasicBlock *Succ : Cur->successors())
238 for (MachineBasicBlock &
MBB : MF)
239 for (MachineInstr &
MI :
MBB)
240 if (
MI.isCall() && !Invokes.
count(&
MI) && leavesFrame(
MI))
247 F.getContext().diagnose(DiagnosticInfoUnsupported(
248 F,
"BPF cannot unwind out of a function that is nounwind or has no "
252 for (MachineInstr *
MI : Labels)
253 MI->eraseFromParent();
255 for (
auto [
Call, Pad] : Sites) {
262 if (leavesFrame(*
Call)) {
263 endBlockAfter(*
Call, Pad);
267 }
else if (
II &&
II->doesNotReturn()) {
269 endBlockAfter(*
Call, Pad);
282 for (MachineBasicBlock *Pad : Pads) {
283 LivePhysRegs Live(
TRI);
284 Live.addLiveOuts(*Pad);
286 Live.stepBackward(
MI);
287 if (!Live.available(MF.getRegInfo(), BPF::R0))
298 Outs, *MF.getSubtarget().getTargetLowering(),
301 for (MachineInstr *
Call : Resumes) {
307 MachineInstrBuilder
Exit =
309 .
addReg(BPF::R0, RegState::Implicit);
310 if (Outs.
size() > 1) {
312 Exit.addReg(BPF::R2, RegState::Implicit);
314 endBlockAfter(*Exit,
nullptr);
318 for (MachineBasicBlock &
MBB : MF)
320 MF.clearLandingPads();
323 df_iterator_default_set<MachineBasicBlock *> Reachable;
333 for (MachineBasicBlock &
MBB : MF)
343char BPFUnwindPrepare::ID = 0;
344char BPFUnwindLower::ID = 0;
347 return new BPFUnwindPrepare();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static constexpr StringLiteral UnwindRaise
On other targets it is a function of the unwinder library, which is why nothing else in LLVM knows th...
static bool canUnwind(const Function &F)
Not being nounwind is the default in IR, so that alone is not enough: uwtable is how a frontend asks ...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
This file implements a set that has insertion order iteration characteristics.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
bool isInlineAsm() const
Check if this call is an inline asm statement.
Value * getCalledOperand() const
bool doesNotThrow() const
Determine if the call cannot unwind.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
FunctionPass class - This class is used to implement most global optimizations.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool hasUWTable() const
True if the ABI mandates (or the user requested) that this function be in a unwind table.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
void setCleanup(bool V)
Indicate that this landingpad instruction is a cleanup.
bool isEHPad() const
Returns true if the block is a landing pad.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
succ_iterator succ_begin()
LLVM_ABI void removeLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
LLVM_ABI MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstrBundleIterator< MachineInstr > iterator
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const std::vector< unsigned > & getFilterIds() const
Return a reference to the typeids encoding filters used in the current function.
const std::vector< const GlobalValue * > & getTypeInfos() const
Return a reference to the C++ typeinfo for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const GlobalValue * getGlobal() const
MachineBasicBlock * getMBB() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
bool insert(const value_type &X)
Insert a new element into the SetVector.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void push_back(const T &Elt)
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
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.
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
@ BasicBlock
Various leaf nodes.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< df_ext_iterator< T, SetTy > > depth_first_ext(const T &G, SetTy &S)
LLVM_ABI BasicBlock * changeToInvokeAndSplitBasicBlock(CallInst *CI, BasicBlock *UnwindEdge, DomTreeUpdater *DTU=nullptr)
Convert the CallInst to InvokeInst with the specified unwind edge basic block.
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto dyn_cast_or_null(const Y &Val)
auto reverse(ContainerTy &&C)
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
FunctionPass * createBPFUnwindLowerPass()
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp=true)
Decrement It, then continue decrementing it while it points to a debug instruction.
ModulePass * createBPFUnwindPreparePass()