45 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
46 return std::mismatch(LIds.begin(), LIds.end(), RIds.begin(), RIds.end())
82 FilterOffsets.
reserve(FilterIds.size());
85 for (
unsigned FilterId : FilterIds) {
93 unsigned SizeActions = 0;
97 const std::vector<int> &TypeIds = LPI->
TypeIds;
98 unsigned NumShared = PrevLPI ?
sharedTypeIDs(LPI, PrevLPI) : 0;
99 unsigned SizeSiteActions = 0;
101 if (NumShared < TypeIds.size()) {
103 unsigned SizeActionEntry = 0;
107 unsigned SizePrevIds = PrevLPI->
TypeIds.size();
109 PrevAction = Actions.
size() - 1;
110 SizeActionEntry =
getSLEB128Size(Actions[PrevAction].NextAction) +
113 for (
unsigned j = NumShared; j != SizePrevIds; ++j) {
114 assert(PrevAction != (
unsigned)-1 &&
"PrevAction is invalid!");
115 SizeActionEntry -=
getSLEB128Size(Actions[PrevAction].ValueForTypeID);
116 SizeActionEntry += -Actions[PrevAction].NextAction;
117 PrevAction = Actions[PrevAction].Previous;
122 for (
unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) {
129 int NextAction = SizeActionEntry ? -(SizeActionEntry + SizeTypeID) : 0;
131 SizeSiteActions += SizeActionEntry;
133 ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
135 PrevAction = Actions.
size() - 1;
139 FirstAction = SizeActions + SizeSiteActions - SizeActionEntry + 1;
150 SizeActions += SizeSiteActions;
159 assert(
MI->isCall() &&
"This should be a call instruction!");
161 bool MarkedNoUnwind =
false;
162 bool SawFunc =
false;
165 if (!MO.isGlobal())
continue;
167 const Function *
F = dyn_cast<Function>(MO.getGlobal());
177 MarkedNoUnwind =
false;
181 MarkedNoUnwind =
F->doesNotThrow();
185 return MarkedNoUnwind;
194 for (
unsigned i = 0,
N = LandingPads.
size(); i !=
N; ++i) {
196 for (
unsigned j = 0,
E = LandingPad->
BeginLabels.size(); j !=
E; ++j) {
204 assert(!PadMap.
count(BeginLabel) &&
"Duplicate landing pad labels!");
206 PadMap[BeginLabel] =
P;
244 bool SawPotentiallyThrowing =
false;
247 bool PreviousIsInvoke =
false;
260 PreviousIsInvoke =
false;
261 SawPotentiallyThrowing =
false;
266 CallSiteRanges.
back().IsLPRange =
true;
268 for (
const auto &
MI :
MBB) {
269 if (!
MI.isEHLabel()) {
276 MCSymbol *BeginLabel =
MI.getOperand(0).getMCSymbol();
277 if (BeginLabel == LastLabel)
278 SawPotentiallyThrowing =
false;
282 if (L == PadMap.
end())
289 "Inconsistent landing pad map!");
295 if (SawPotentiallyThrowing &&
298 CallSites.
push_back({LastLabel, BeginLabel,
nullptr, 0});
299 PreviousIsInvoke =
false;
302 LastLabel = LandingPad->
EndLabels[
P.RangeIndex];
303 assert(BeginLabel && LastLabel &&
"Invalid landing pad!");
307 PreviousIsInvoke =
false;
314 FirstActions[
P.PadIndex]
318 if (PreviousIsInvoke && !IsSJLJ) {
334 if (CallSites.
size() < SiteNo)
336 CallSites[SiteNo - 1] = Site;
338 PreviousIsInvoke =
true;
348 if (SawPotentiallyThrowing && !IsSJLJ) {
352 SawPotentiallyThrowing =
false;
354 CallSiteRanges.
back().CallSiteEndIdx = CallSites.
size();
383 const std::vector<const GlobalValue *> &TypeInfos = MF->
getTypeInfos();
384 const std::vector<unsigned> &FilterIds = MF->
getFilterIds();
385 const std::vector<LandingPadInfo> &PadInfos = MF->
getLandingPads();
390 LandingPads.
reserve(PadInfos.size());
396 if (LPI.LandingPadLabel && !LPI.LandingPadLabel->isDefined())
403 return L->TypeIds < R->TypeIds;
423 unsigned CallSiteEncoding =
426 bool HaveTTData = !TypeInfos.empty() || !FilterIds.empty();
431 unsigned TTypeEncoding;
481 CallSiteRanges.
size() > 1 ?
"action_table_base" :
"cst_end");
493 auto EmitTypeTableRefAndCallSiteTableEndRef = [&]() {
521 auto EmitTypeTableOffsetAndCallSiteTableOffset = [&]() {
523 "Targets supporting .uleb128 do not need to take this path.");
524 if (CallSiteRanges.
size() > 1)
526 "-fbasic-block-sections is not yet supported on "
527 "platforms that do not have general LEB128 directive support.");
537 assert(isUInt<32>(CallSiteTableSize) &&
"CallSiteTableSize overflows.");
542 const unsigned ByteSizeOfCallSiteOffset =
549 assert(isUInt<32>(ActionTableSize) &&
"ActionTableSize overflows.");
552 const unsigned TypeInfoSize =
555 const uint64_t LSDASizeBeforeAlign =
557 + ByteSizeOfCallSiteOffset
561 const uint64_t LSDASizeWithoutAlign = LSDASizeBeforeAlign + TypeInfoSize;
562 const unsigned ByteSizeOfLSDAWithoutAlign =
564 const uint64_t DisplacementBeforeAlign =
566 + ByteSizeOfLSDAWithoutAlign + LSDASizeBeforeAlign;
569 const unsigned NeedAlignVal = (4 - DisplacementBeforeAlign % 4) % 4;
570 uint64_t LSDASizeWithAlign = LSDASizeWithoutAlign + NeedAlignVal;
571 const unsigned ByteSizeOfLSDAWithAlign =
577 if (ByteSizeOfLSDAWithAlign > ByteSizeOfLSDAWithoutAlign)
578 LSDASizeWithAlign -= 1;
581 ByteSizeOfLSDAWithAlign);
589 if (IsSJLJ || IsWasm) {
594 EmitTypeTableRefAndCallSiteTableEndRef();
598 I = CallSites.
begin(),
E = CallSites.
end();
I !=
E; ++
I, ++idx) {
642 assert(CallSiteRanges.
size() != 0 &&
"No call-site ranges!");
648 if (CSRange.IsLPRange) {
649 assert(LandingPadRange ==
nullptr &&
650 "All landing pads must be in a single callsite range.");
651 LandingPadRange = &CSRange;
670 if (CSRange.CallSiteBeginIdx != 0) {
681 if (CallSiteRanges.size() == 1 || LandingPadRange ==
nullptr) {
704 if (HasLEB128Directives)
705 EmitTypeTableRefAndCallSiteTableEndRef();
707 EmitTypeTableOffsetAndCallSiteTableOffset();
709 for (
size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
710 CallSiteIdx != CSRange.CallSiteEndIdx; ++CallSiteIdx) {
713 MCSymbol *EHFuncBeginSym = CSRange.FragmentBeginLabel;
714 MCSymbol *EHFuncEndSym = CSRange.FragmentEndLabel;
718 BeginLabel = EHFuncBeginSym;
721 EndLabel = EHFuncEndSym;
730 BeginLabel->
getName() +
" and " +
778 if (Action.ValueForTypeID > 0)
780 Twine(Action.ValueForTypeID));
781 else if (Action.ValueForTypeID < 0)
783 Twine(Action.ValueForTypeID));
791 if (Action.Previous ==
unsigned(-1)) {
795 Twine(Action.Previous + 1));
812 const std::vector<const GlobalValue *> &TypeInfos = MF->
getTypeInfos();
813 const std::vector<unsigned> &FilterIds = MF->
getFilterIds();
819 if (VerboseAsm && !TypeInfos.empty()) {
822 Entry = TypeInfos.size();
834 if (VerboseAsm && !FilterIds.empty()) {
839 for (std::vector<unsigned>::const_iterator
840 I = FilterIds.begin(),
E = FilterIds.end();
I <
E; ++
I) {
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
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.
MapVector< unsigned, MBBSectionRange > MBBSectionRanges
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 * 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.
unsigned getSectionIDNum() const
Returns the unique section ID number 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 provides a very simple, boring adaptor for a begin and end iterator into a range type.
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