44 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
45 return std::mismatch(LIds.begin(), LIds.end(), RIds.begin(), RIds.end())
81 FilterOffsets.
reserve(FilterIds.size());
84 for (
unsigned FilterId : FilterIds) {
92 unsigned SizeActions = 0;
96 const std::vector<int> &TypeIds = LPI->
TypeIds;
97 unsigned NumShared = PrevLPI ?
sharedTypeIDs(LPI, PrevLPI) : 0;
98 unsigned SizeSiteActions = 0;
100 if (NumShared < TypeIds.size()) {
102 unsigned SizeActionEntry = 0;
106 unsigned SizePrevIds = PrevLPI->
TypeIds.size();
108 PrevAction = Actions.
size() - 1;
109 SizeActionEntry =
getSLEB128Size(Actions[PrevAction].NextAction) +
112 for (
unsigned j = NumShared; j != SizePrevIds; ++j) {
113 assert(PrevAction != (
unsigned)-1 &&
"PrevAction is invalid!");
114 SizeActionEntry -=
getSLEB128Size(Actions[PrevAction].ValueForTypeID);
115 SizeActionEntry += -Actions[PrevAction].NextAction;
116 PrevAction = Actions[PrevAction].Previous;
121 for (
unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) {
128 int NextAction = SizeActionEntry ? -(SizeActionEntry + SizeTypeID) : 0;
130 SizeSiteActions += SizeActionEntry;
132 ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
134 PrevAction = Actions.
size() - 1;
138 FirstAction = SizeActions + SizeSiteActions - SizeActionEntry + 1;
149 SizeActions += SizeSiteActions;
158 assert(
MI->isCall() &&
"This should be a call instruction!");
160 bool MarkedNoUnwind =
false;
161 bool SawFunc =
false;
164 if (!MO.isGlobal())
continue;
166 const Function *
F = dyn_cast<Function>(MO.getGlobal());
176 MarkedNoUnwind =
false;
180 MarkedNoUnwind =
F->doesNotThrow();
184 return MarkedNoUnwind;
193 for (
unsigned i = 0,
N = LandingPads.
size(); i !=
N; ++i) {
195 for (
unsigned j = 0, E = LandingPad->
BeginLabels.size(); j != E; ++j) {
203 assert(!PadMap.
count(BeginLabel) &&
"Duplicate landing pad labels!");
205 PadMap[BeginLabel] =
P;
243 bool SawPotentiallyThrowing =
false;
246 bool PreviousIsInvoke =
false;
259 PreviousIsInvoke =
false;
260 SawPotentiallyThrowing =
false;
265 CallSiteRanges.
back().IsLPRange =
true;
267 for (
const auto &
MI :
MBB) {
268 if (!
MI.isEHLabel()) {
275 MCSymbol *BeginLabel =
MI.getOperand(0).getMCSymbol();
276 if (BeginLabel == LastLabel)
277 SawPotentiallyThrowing =
false;
281 if (L == PadMap.
end())
288 "Inconsistent landing pad map!");
294 if (SawPotentiallyThrowing &&
297 CallSites.
push_back({LastLabel, BeginLabel,
nullptr, 0});
298 PreviousIsInvoke =
false;
301 LastLabel = LandingPad->
EndLabels[
P.RangeIndex];
302 assert(BeginLabel && LastLabel &&
"Invalid landing pad!");
306 PreviousIsInvoke =
false;
313 FirstActions[
P.PadIndex]
317 if (PreviousIsInvoke && !IsSJLJ) {
333 if (CallSites.
size() < SiteNo)
335 CallSites[SiteNo - 1] = Site;
337 PreviousIsInvoke =
true;
347 if (SawPotentiallyThrowing && !IsSJLJ) {
351 SawPotentiallyThrowing =
false;
353 CallSiteRanges.
back().CallSiteEndIdx = CallSites.
size();
382 const std::vector<const GlobalValue *> &TypeInfos = MF->
getTypeInfos();
383 const std::vector<unsigned> &FilterIds = MF->
getFilterIds();
384 const std::vector<LandingPadInfo> &PadInfos = MF->
getLandingPads();
389 LandingPads.
reserve(PadInfos.size());
395 if (LPI.LandingPadLabel && !LPI.LandingPadLabel->isDefined())
402 return L->TypeIds < R->TypeIds;
422 unsigned CallSiteEncoding =
425 bool HaveTTData = !TypeInfos.empty() || !FilterIds.empty();
430 unsigned TTypeEncoding;
480 CallSiteRanges.
size() > 1 ?
"action_table_base" :
"cst_end");
492 auto EmitTypeTableRefAndCallSiteTableEndRef = [&]() {
520 auto EmitTypeTableOffsetAndCallSiteTableOffset = [&]() {
522 "Targets supporting .uleb128 do not need to take this path.");
523 if (CallSiteRanges.
size() > 1)
525 "-fbasic-block-sections is not yet supported on "
526 "platforms that do not have general LEB128 directive support.");
536 assert(isUInt<32>(CallSiteTableSize) &&
"CallSiteTableSize overflows.");
541 const unsigned ByteSizeOfCallSiteOffset =
548 assert(isUInt<32>(ActionTableSize) &&
"ActionTableSize overflows.");
551 const unsigned TypeInfoSize =
554 const uint64_t LSDASizeBeforeAlign =
556 + ByteSizeOfCallSiteOffset
560 const uint64_t LSDASizeWithoutAlign = LSDASizeBeforeAlign + TypeInfoSize;
561 const unsigned ByteSizeOfLSDAWithoutAlign =
563 const uint64_t DisplacementBeforeAlign =
565 + ByteSizeOfLSDAWithoutAlign + LSDASizeBeforeAlign;
568 const unsigned NeedAlignVal = (4 - DisplacementBeforeAlign % 4) % 4;
569 uint64_t LSDASizeWithAlign = LSDASizeWithoutAlign + NeedAlignVal;
570 const unsigned ByteSizeOfLSDAWithAlign =
576 if (ByteSizeOfLSDAWithAlign > ByteSizeOfLSDAWithoutAlign)
577 LSDASizeWithAlign -= 1;
580 ByteSizeOfLSDAWithAlign);
588 if (IsSJLJ || IsWasm) {
593 EmitTypeTableRefAndCallSiteTableEndRef();
597 I = CallSites.
begin(), E = CallSites.
end();
I != E; ++
I, ++idx) {
641 assert(CallSiteRanges.
size() != 0 &&
"No call-site ranges!");
647 if (CSRange.IsLPRange) {
648 assert(LandingPadRange ==
nullptr &&
649 "All landing pads must be in a single callsite range.");
650 LandingPadRange = &CSRange;
669 if (CSRange.CallSiteBeginIdx != 0) {
680 if (CallSiteRanges.size() == 1 || LandingPadRange ==
nullptr) {
703 if (HasLEB128Directives)
704 EmitTypeTableRefAndCallSiteTableEndRef();
706 EmitTypeTableOffsetAndCallSiteTableOffset();
708 for (
size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
709 CallSiteIdx != CSRange.CallSiteEndIdx; ++CallSiteIdx) {
712 MCSymbol *EHFuncBeginSym = CSRange.FragmentBeginLabel;
713 MCSymbol *EHFuncEndSym = CSRange.FragmentEndLabel;
717 BeginLabel = EHFuncBeginSym;
720 EndLabel = EHFuncEndSym;
729 BeginLabel->
getName() +
" and " +
777 if (Action.ValueForTypeID > 0)
779 Twine(Action.ValueForTypeID));
780 else if (Action.ValueForTypeID < 0)
782 Twine(Action.ValueForTypeID));
790 if (Action.Previous ==
unsigned(-1)) {
794 Twine(Action.Previous + 1));
811 const std::vector<const GlobalValue *> &TypeInfos = MF->
getTypeInfos();
812 const std::vector<unsigned> &FilterIds = MF->
getFilterIds();
818 if (VerboseAsm && !TypeInfos.empty()) {
821 Entry = TypeInfos.size();
833 if (VerboseAsm && !FilterIds.empty()) {
838 for (std::vector<unsigned>::const_iterator
839 I = FilterIds.begin(), E = FilterIds.end();
I < E; ++
I) {
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains constants used for implementing Dwarf debug support.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
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)
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)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
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