Go to the documentation of this file.
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) {
86 FilterOffsets.push_back(
Offset);
90 FirstActions.
reserve(LandingPads.size());
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;
104 unsigned PrevAction = (unsigned)-1;
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) {
124 assert(-1 -
TypeID < (
int)FilterOffsets.size() &&
"Unknown filter id!");
129 int NextAction = SizeActionEntry ? -(SizeActionEntry + SizeTypeID) : 0;
131 SizeSiteActions += SizeActionEntry;
133 ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
134 Actions.push_back(Action);
135 PrevAction = Actions.size() - 1;
139 FirstAction = SizeActions + SizeSiteActions - SizeActionEntry + 1;
147 FirstActions.push_back(FirstAction);
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) {
204 assert(!PadMap.
count(BeginLabel) &&
"Duplicate landing pad labels!");
206 PadMap[BeginLabel] =
P;
244 bool SawPotentiallyThrowing =
false;
247 bool PreviousIsInvoke =
false;
256 CallSiteRanges.push_back(
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) {
329 CallSites.push_back(Site);
334 if (CallSites.size() < SiteNo)
336 CallSites[SiteNo - 1] = Site;
338 PreviousIsInvoke =
true;
348 if (SawPotentiallyThrowing && !IsSJLJ) {
349 CallSiteEntry Site = {LastLabel, CallSiteRanges.back().FragmentEndLabel,
351 CallSites.push_back(Site);
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())
398 LandingPads.push_back(&LPI);
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) {
616 Twine((
S.Action - 1) / 2 + 1));
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 " +
743 S.LPad->LandingPadLabel->getName());
757 Twine((
S.Action - 1) / 2 + 1));
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) {
bool isPositionIndependent() const
void emitLabelDifferenceAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) const
Emit something like ".uleb128 Hi-Lo".
This is an optimization pass for GlobalISel generic memory operations.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
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.
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
@ SjLj
setjmp/longjmp based exceptions
MCSymbol * createTempSymbol(const Twine &Name) const
Context object for machine code objects.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
const MCAsmInfo * MAI
Target Asm Printer information.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MCSymbol * LandingPadLabel
void emitSLEB128(int64_t Value, const char *Desc=nullptr) const
Emit the specified signed leb128 value.
bool hasLEB128Directives() const
const MachineBasicBlock & back() const
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
bool usesCFIForEH() const
Returns true if the exception handling method for the platform uses call frame information to unwind.
void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Encoding) const
Emit reference to a call site with a specified encoding.
const LandingPadInfo * LPad
virtual void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel)
@ AIX
AIX Exception Handling.
bool isBeginSection() const
Returns true if this block begins any section.
const MachineBasicBlock & front() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
unsigned getTTypeEncoding() const
SmallVector< MCSymbol *, 1 > EndLabels
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const std::vector< unsigned > & getFilterIds() const
Return a reference to the typeids encoding filters used in the current function.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
MCSymbol * emitExceptionTable()
Emit landing pads and actions.
std::vector< int > TypeIds
MachineOperand class - Representation of each machine instruction operand.
MCSymbol * CurrentFnSym
The symbol for the current function.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ Wasm
WebAssembly Exception Handling.
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.
StringRef getName() const
getName - Get the symbol name.
static bool isFilterEHSelector(int Selector)
MCSymbol * getFunctionBegin() const
virtual MCSection * getSectionForLSDA(const Function &, const MCSymbol &, const TargetMachine &) const
unsigned getSectionIDNum() const
Returns the unique section ID number of this basic block.
void sort(IteratorTy Start, IteratorTy End)
unsigned getCallSiteEncoding() const
static unsigned sharedTypeIDs(const LandingPadInfo *L, const LandingPadInfo *R)
How many leading type ids two landing pads have in common.
EHStreamer(AsmPrinter *A)
SmallVector< MCSymbol *, 1 > BeginLabels
Representation of each machine instruction.
unsigned GetSizeOfEncodedValue(unsigned Encoding) const
Return the size of the encoding in bytes.
Structure describing a contiguous range of call-sites which reside in the same procedure fragment.
iterator find(const_arg_type_t< KeyT > Val)
typename SuperClass::const_iterator const_iterator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
MCSymbol * getMBBExceptionSym(const MachineBasicBlock &MBB)
MachineFunction * MF
The current machine function.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
static bool callToNoUnwindFunction(const MachineInstr *MI)
Return ‘true’ if this is a call to a function marked ‘nounwind’.
MCContext & OutContext
This is the context for the output file that we are streaming.
Structure describing an entry in the actions table.
Structure describing an entry in the call-site table.
AsmPrinter * Asm
Target of directive emission.
bool isEHPad() const
Returns true if the block is a landing pad.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
unsigned getSLEB128Size(int64_t Value)
Utility function to get the size of the SLEB128-encoded value.
void computePadMap(const SmallVectorImpl< const LandingPadInfo * > &LandingPads, RangeMapType &PadMap)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Function & getFunction()
Return the LLVM function that this machine code represents.
bool isEndSection() const
Returns true if this block ends any section.
This class is intended to be used as a driving class for all asm writers.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
ExceptionHandling getExceptionHandlingType() const
virtual void emitTTypeReference(const GlobalValue *GV, unsigned Encoding)
Emit reference to a ttype global with a specified encoding.
MapVector< unsigned, MBBSectionRange > MBBSectionRanges
TargetMachine & TM
Target machine description.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
auto reverse(ContainerTy &&C)
unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) const
Get the call site number for a begin label.
This structure is used to retain landing pad info for the current function.
const std::vector< const GlobalValue * > & getTypeInfos() const
Return a reference to the C++ typeinfo for the current function.
void emitCallSiteValue(uint64_t Value, unsigned Encoding) const
Emit an integer value corresponding to the call site encoding.
TypeID
Definitions of all of the base types for the Type system.
Structure holding a try-range and the associated landing pad.
void reserve(size_type N)
unsigned getFunctionNumber() const
Return a unique ID for the current function.
void emitEncodingByte(unsigned Val, const char *Desc=nullptr) const
Emit a .byte 42 directive that corresponds to an encoding.
MCSymbol * FragmentBeginLabel