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) {
162 return "BPF needs uwtable on a function with a landing pad";
165 for (
int TId : LP.TypeIds) {
167 return "BPF does not support type-specific exception catches yet";
171 return "BPF does not support exception filters yet";
181 RTLIB::UNWIND_RESUME);
182 DenseMap<MCSymbol *, MachineBasicBlock *> Begin;
184 SmallVector<MachineInstr *, 8> Labels, Resumes;
185 SmallSetVector<MachineBasicBlock *, 8> Pads;
194 for (MCSymbol *Sym : LP.BeginLabels)
195 Begin[Sym] = LP.LandingPadBlock;
197 for (MachineBasicBlock &
MBB : MF) {
198 MachineBasicBlock *Pad =
nullptr;
199 for (MachineInstr &
MI :
MBB) {
200 if (
MI.isEHLabel()) {
201 Pad = Begin.
lookup(
MI.getOperand(0).getMCSymbol());
203 }
else if (
MI.isCall() && Pad) {
205 }
else if (
MI.isCall() && leavesFrame(
MI)) {
215 F.getContext().diagnose(DiagnosticInfoUnsupported(
216 F,
"BPF cannot unwind out of a function that is nounwind or has no "
220 for (MachineInstr *
MI : Labels)
223 for (
auto [
Call, Pad] : Sites) {
230 if (leavesFrame(*
Call)) {
231 endBlockAfter(*
Call, Pad);
234 }
else if (
II &&
II->doesNotReturn()) {
236 endBlockAfter(*
Call, Pad);
249 for (MachineBasicBlock *Pad : Pads) {
250 LivePhysRegs Live(
TRI);
251 Live.addLiveOuts(*Pad);
253 Live.stepBackward(
MI);
254 if (!Live.available(MF.getRegInfo(), BPF::R0))
265 Outs, *MF.getSubtarget().getTargetLowering(),
268 for (MachineInstr *
Call : Resumes) {
273 MachineInstrBuilder
Exit =
275 .
addReg(BPF::R0, RegState::Implicit);
276 if (Outs.
size() > 1) {
278 Exit.addReg(BPF::R2, RegState::Implicit);
280 endBlockAfter(*Exit,
nullptr);
284 for (MachineBasicBlock &
MBB : MF)
286 MF.clearLandingPads();
289 df_iterator_default_set<MachineBasicBlock *> Reachable;
299 for (MachineBasicBlock &
MBB : MF)
309char BPFUnwindPrepare::ID = 0;
310char BPFUnwindLower::ID = 0;
313 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.
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.
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.
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.
ModulePass * createBPFUnwindPreparePass()