43 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
44 return std::mismatch(LIds.begin(), LIds.end(), RIds.begin(), RIds.end())
80 FilterOffsets.
reserve(FilterIds.size());
83 for (
unsigned FilterId : FilterIds) {
91 unsigned SizeActions = 0;
95 const std::vector<int> &TypeIds = LPI->
TypeIds;
96 unsigned NumShared = PrevLPI ?
sharedTypeIDs(LPI, PrevLPI) : 0;
97 unsigned SizeSiteActions = 0;
99 if (NumShared < TypeIds.size()) {
101 unsigned SizeActionEntry = 0;
105 unsigned SizePrevIds = PrevLPI->
TypeIds.size();
107 PrevAction = Actions.
size() - 1;
108 SizeActionEntry =
getSLEB128Size(Actions[PrevAction].NextAction) +
111 for (
unsigned j = NumShared; j != SizePrevIds; ++j) {
112 assert(PrevAction != (
unsigned)-1 &&
"PrevAction is invalid!");
113 SizeActionEntry -=
getSLEB128Size(Actions[PrevAction].ValueForTypeID);
114 SizeActionEntry += -Actions[PrevAction].NextAction;
115 PrevAction = Actions[PrevAction].Previous;
120 for (
unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) {
127 int NextAction = SizeActionEntry ? -(SizeActionEntry + SizeTypeID) : 0;
129 SizeSiteActions += SizeActionEntry;
131 ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
133 PrevAction = Actions.
size() - 1;
137 FirstAction = SizeActions + SizeSiteActions - SizeActionEntry + 1;
148 SizeActions += SizeSiteActions;
157 assert(
MI->isCall() &&
"This should be a call instruction!");
159 bool MarkedNoUnwind =
false;
160 bool SawFunc =
false;
163 if (!MO.isGlobal())
continue;
165 const Function *
F = dyn_cast<Function>(MO.getGlobal());
175 MarkedNoUnwind =
false;
179 MarkedNoUnwind =
F->doesNotThrow();
183 return MarkedNoUnwind;
192 for (
unsigned i = 0,
N = LandingPads.
size(); i !=
N; ++i) {
194 for (
unsigned j = 0, E = LandingPad->
BeginLabels.size(); j != E; ++j) {
202 assert(!PadMap.
count(BeginLabel) &&
"Duplicate landing pad labels!");
204 PadMap[BeginLabel] =
P;
242 bool SawPotentiallyThrowing =
false;
245 bool PreviousIsInvoke =
false;
258 PreviousIsInvoke =
false;
259 SawPotentiallyThrowing =
false;
264 CallSiteRanges.
back().IsLPRange =
true;
266 for (
const auto &
MI :
MBB) {
267 if (!
MI.isEHLabel()) {
274 MCSymbol *BeginLabel =
MI.getOperand(0).getMCSymbol();
275 if (BeginLabel == LastLabel)
276 SawPotentiallyThrowing =
false;
280 if (L == PadMap.
end())
287 "Inconsistent landing pad map!");
293 if (SawPotentiallyThrowing &&
296 CallSites.
push_back({LastLabel, BeginLabel,
nullptr, 0});
297 PreviousIsInvoke =
false;
300 LastLabel = LandingPad->
EndLabels[
P.RangeIndex];
301 assert(BeginLabel && LastLabel &&
"Invalid landing pad!");
305 PreviousIsInvoke =
false;
312 FirstActions[
P.PadIndex]
316 if (PreviousIsInvoke && !IsSJLJ) {
332 if (CallSites.
size() < SiteNo)
334 CallSites[SiteNo - 1] = Site;
336 PreviousIsInvoke =
true;
346 if (SawPotentiallyThrowing && !IsSJLJ) {
350 SawPotentiallyThrowing =
false;
352 CallSiteRanges.
back().CallSiteEndIdx = CallSites.
size();
381 const std::vector<const GlobalValue *> &TypeInfos = MF->
getTypeInfos();
382 const std::vector<unsigned> &FilterIds = MF->
getFilterIds();
383 const std::vector<LandingPadInfo> &PadInfos = MF->
getLandingPads();
388 LandingPads.
reserve(PadInfos.size());
394 if (LPI.LandingPadLabel && !LPI.LandingPadLabel->isDefined())
401 return L->TypeIds < R->TypeIds;
421 unsigned CallSiteEncoding =
424 bool HaveTTData = !TypeInfos.empty() || !FilterIds.empty();
429 unsigned TTypeEncoding;
479 CallSiteRanges.
size() > 1 ?
"action_table_base" :
"cst_end");
491 auto EmitTypeTableRefAndCallSiteTableEndRef = [&]() {
519 auto EmitTypeTableOffsetAndCallSiteTableOffset = [&]() {
521 "Targets supporting .uleb128 do not need to take this path.");
522 if (CallSiteRanges.
size() > 1)
524 "-fbasic-block-sections is not yet supported on "
525 "platforms that do not have general LEB128 directive support.");
535 assert(isUInt<32>(CallSiteTableSize) &&
"CallSiteTableSize overflows.");
540 const unsigned ByteSizeOfCallSiteOffset =
547 assert(isUInt<32>(ActionTableSize) &&
"ActionTableSize overflows.");
550 const unsigned TypeInfoSize =
553 const uint64_t LSDASizeBeforeAlign =
555 + ByteSizeOfCallSiteOffset
559 const uint64_t LSDASizeWithoutAlign = LSDASizeBeforeAlign + TypeInfoSize;
560 const unsigned ByteSizeOfLSDAWithoutAlign =
562 const uint64_t DisplacementBeforeAlign =
564 + ByteSizeOfLSDAWithoutAlign + LSDASizeBeforeAlign;
567 const unsigned NeedAlignVal = (4 - DisplacementBeforeAlign % 4) % 4;
568 uint64_t LSDASizeWithAlign = LSDASizeWithoutAlign + NeedAlignVal;
569 const unsigned ByteSizeOfLSDAWithAlign =
575 if (ByteSizeOfLSDAWithAlign > ByteSizeOfLSDAWithoutAlign)
576 LSDASizeWithAlign -= 1;
579 ByteSizeOfLSDAWithAlign);
587 if (IsSJLJ || IsWasm) {
592 EmitTypeTableRefAndCallSiteTableEndRef();
596 I = CallSites.
begin(), E = CallSites.
end();
I != E; ++
I, ++idx) {
640 assert(CallSiteRanges.
size() != 0 &&
"No call-site ranges!");
646 if (CSRange.IsLPRange) {
647 assert(LandingPadRange ==
nullptr &&
648 "All landing pads must be in a single callsite range.");
649 LandingPadRange = &CSRange;
668 if (CSRange.CallSiteBeginIdx != 0) {
679 if (CallSiteRanges.size() == 1 || LandingPadRange ==
nullptr) {
702 if (HasLEB128Directives)
703 EmitTypeTableRefAndCallSiteTableEndRef();
705 EmitTypeTableOffsetAndCallSiteTableOffset();
707 for (
size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
708 CallSiteIdx != CSRange.CallSiteEndIdx; ++CallSiteIdx) {
711 MCSymbol *EHFuncBeginSym = CSRange.FragmentBeginLabel;
712 MCSymbol *EHFuncEndSym = CSRange.FragmentEndLabel;
716 BeginLabel = EHFuncBeginSym;
719 EndLabel = EHFuncEndSym;
728 BeginLabel->
getName() +
" and " +
776 if (Action.ValueForTypeID > 0)
778 Twine(Action.ValueForTypeID));
779 else if (Action.ValueForTypeID < 0)
781 Twine(Action.ValueForTypeID));
789 if (Action.Previous ==
unsigned(-1)) {
793 Twine(Action.Previous + 1));
810 const std::vector<const GlobalValue *> &TypeInfos = MF->
getTypeInfos();
811 const std::vector<unsigned> &FilterIds = MF->
getFilterIds();
817 if (VerboseAsm && !TypeInfos.empty()) {
820 Entry = TypeInfos.size();
832 if (VerboseAsm && !FilterIds.empty()) {
837 for (std::vector<unsigned>::const_iterator
838 I = FilterIds.begin(), E = FilterIds.end();
I < E; ++
I) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains constants used for implementing Dwarf debug support.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file defines the SmallVector class.
This class is intended to be used as a driving class for all asm writers.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
MapVector< MBBSectionID, MBBSectionRange > MBBSectionRanges
unsigned GetSizeOfEncodedValue(unsigned Encoding) const
Return the size of the encoding in bytes.
TargetMachine & TM
Target machine description.
MCSymbol * getFunctionBegin() const
MCSymbol * getMBBExceptionSym(const MachineBasicBlock &MBB)
virtual void emitTTypeReference(const GlobalValue *GV, unsigned Encoding)
Emit reference to a ttype global with a specified encoding.
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
void emitEncodingByte(unsigned Val, const char *Desc=nullptr) const
Emit a .byte 42 directive that corresponds to an encoding.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
MCSymbol * CurrentFnSym
The symbol for the current function.
void emitSLEB128(int64_t Value, const char *Desc=nullptr) const
Emit the specified signed leb128 value.
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSymbol * createTempSymbol(const Twine &Name) const
bool isPositionIndependent() const
void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Encoding) const
Emit reference to a call site with a specified encoding.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
void emitCallSiteValue(uint64_t Value, unsigned Encoding) const
Emit an integer value corresponding to the call site encoding.
void emitLabelDifferenceAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) const
Emit something like ".uleb128 Hi-Lo".
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
virtual void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel)
void computeActionsTable(const SmallVectorImpl< const LandingPadInfo * > &LandingPads, SmallVectorImpl< ActionEntry > &Actions, SmallVectorImpl< unsigned > &FirstActions)
Compute the actions table and gather the first action index for each landing pad site.
void computePadMap(const SmallVectorImpl< const LandingPadInfo * > &LandingPads, RangeMapType &PadMap)
AsmPrinter * Asm
Target of directive emission.
MCSymbol * emitExceptionTable()
Emit landing pads and actions.
virtual void computeCallSiteTable(SmallVectorImpl< CallSiteEntry > &CallSites, SmallVectorImpl< CallSiteRange > &CallSiteRanges, const SmallVectorImpl< const LandingPadInfo * > &LandingPads, const SmallVectorImpl< unsigned > &FirstActions)
Compute the call-site table and the call-site ranges.
static bool isFilterEHSelector(int Selector)
static unsigned sharedTypeIDs(const LandingPadInfo *L, const LandingPadInfo *R)
How many leading type ids two landing pads have in common.
static bool callToNoUnwindFunction(const MachineInstr *MI)
Return ‘true’ if this is a call to a function marked ‘nounwind’.
EHStreamer(AsmPrinter *A)
bool hasLEB128Directives() const
bool usesCFIForEH() const
Returns true if the exception handling method for the platform uses call frame information to unwind.
ExceptionHandling getExceptionHandlingType() const
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
StringRef getName() const
getName - Get the symbol name.
bool isEHPad() const
Returns true if the block is a landing pad.
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
bool isBeginSection() const
Returns true if this block begins any section.
bool isEndSection() const
Returns true if this block ends any section.
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 MachineBasicBlock & back() const
unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) const
Get the call site number for a begin label.
const MachineBasicBlock & front() const
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
typename SuperClass::const_iterator const_iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned getCallSiteEncoding() const
unsigned getTTypeEncoding() const
virtual MCSection * getSectionForLSDA(const Function &, const MCSymbol &, const TargetMachine &) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
TypeID
Definitions of all of the base types for the Type system.
This is an optimization pass for GlobalISel generic memory operations.
@ SjLj
setjmp/longjmp based exceptions
@ AIX
AIX Exception Handling.
@ Wasm
WebAssembly Exception Handling.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
LLVM_ABI unsigned getSLEB128Size(int64_t Value)
Utility function to get the size of the SLEB128-encoded value.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Structure describing an entry in the actions table.
Structure describing an entry in the call-site table.
const LandingPadInfo * LPad
Structure describing a contiguous range of call-sites which reside in the same procedure fragment.
MCSymbol * FragmentBeginLabel
Structure holding a try-range and the associated landing pad.
This structure is used to retain landing pad info for the current function.
SmallVector< MCSymbol *, 1 > EndLabels
MCSymbol * LandingPadLabel
SmallVector< MCSymbol *, 1 > BeginLabels
std::vector< int > TypeIds