MCFragment.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- MCFragment.h - Fragment type hierarchy -------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_MC_MCFRAGMENT_H
  14. #define LLVM_MC_MCFRAGMENT_H
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/ADT/SmallString.h"
  17. #include "llvm/ADT/SmallVector.h"
  18. #include "llvm/ADT/StringRef.h"
  19. #include "llvm/ADT/ilist_node.h"
  20. #include "llvm/MC/MCFixup.h"
  21. #include "llvm/MC/MCInst.h"
  22. #include "llvm/Support/Alignment.h"
  23. #include "llvm/Support/Casting.h"
  24. #include "llvm/Support/SMLoc.h"
  25. #include <cstdint>
  26. #include <utility>
  27. namespace llvm {
  28. class MCSection;
  29. class MCSubtargetInfo;
  30. class MCSymbol;
  31. class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
  32. friend class MCAsmLayout;
  33. public:
  34. enum FragmentType : uint8_t {
  35. FT_Align,
  36. FT_Data,
  37. FT_CompactEncodedInst,
  38. FT_Fill,
  39. FT_Nops,
  40. FT_Relaxable,
  41. FT_Org,
  42. FT_Dwarf,
  43. FT_DwarfFrame,
  44. FT_LEB,
  45. FT_BoundaryAlign,
  46. FT_SymbolId,
  47. FT_CVInlineLines,
  48. FT_CVDefRange,
  49. FT_PseudoProbe,
  50. FT_Dummy
  51. };
  52. private:
  53. /// The data for the section this fragment is in.
  54. MCSection *Parent;
  55. /// The atom this fragment is in, as represented by its defining symbol.
  56. const MCSymbol *Atom;
  57. /// The offset of this fragment in its section. This is ~0 until
  58. /// initialized.
  59. uint64_t Offset;
  60. /// The layout order of this fragment.
  61. unsigned LayoutOrder;
  62. /// The subsection this fragment belongs to. This is 0 if the fragment is not
  63. // in any subsection.
  64. unsigned SubsectionNumber = 0;
  65. FragmentType Kind;
  66. /// Whether fragment is being laid out.
  67. bool IsBeingLaidOut;
  68. protected:
  69. bool HasInstructions;
  70. MCFragment(FragmentType Kind, bool HasInstructions,
  71. MCSection *Parent = nullptr);
  72. public:
  73. MCFragment() = delete;
  74. MCFragment(const MCFragment &) = delete;
  75. MCFragment &operator=(const MCFragment &) = delete;
  76. /// Destroys the current fragment.
  77. ///
  78. /// This must be used instead of delete as MCFragment is non-virtual.
  79. /// This method will dispatch to the appropriate subclass.
  80. void destroy();
  81. FragmentType getKind() const { return Kind; }
  82. MCSection *getParent() const { return Parent; }
  83. void setParent(MCSection *Value) { Parent = Value; }
  84. const MCSymbol *getAtom() const { return Atom; }
  85. void setAtom(const MCSymbol *Value) { Atom = Value; }
  86. unsigned getLayoutOrder() const { return LayoutOrder; }
  87. void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
  88. /// Does this fragment have instructions emitted into it? By default
  89. /// this is false, but specific fragment types may set it to true.
  90. bool hasInstructions() const { return HasInstructions; }
  91. void dump() const;
  92. void setSubsectionNumber(unsigned Value) { SubsectionNumber = Value; }
  93. unsigned getSubsectionNumber() const { return SubsectionNumber; }
  94. };
  95. class MCDummyFragment : public MCFragment {
  96. public:
  97. explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
  98. static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
  99. };
  100. /// Interface implemented by fragments that contain encoded instructions and/or
  101. /// data.
  102. ///
  103. class MCEncodedFragment : public MCFragment {
  104. /// Should this fragment be aligned to the end of a bundle?
  105. bool AlignToBundleEnd = false;
  106. uint8_t BundlePadding = 0;
  107. protected:
  108. MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
  109. MCSection *Sec)
  110. : MCFragment(FType, HasInstructions, Sec) {}
  111. /// The MCSubtargetInfo in effect when the instruction was encoded.
  112. /// It must be non-null for instructions.
  113. const MCSubtargetInfo *STI = nullptr;
  114. public:
  115. static bool classof(const MCFragment *F) {
  116. MCFragment::FragmentType Kind = F->getKind();
  117. switch (Kind) {
  118. default:
  119. return false;
  120. case MCFragment::FT_Relaxable:
  121. case MCFragment::FT_CompactEncodedInst:
  122. case MCFragment::FT_Data:
  123. case MCFragment::FT_Dwarf:
  124. case MCFragment::FT_DwarfFrame:
  125. case MCFragment::FT_PseudoProbe:
  126. return true;
  127. }
  128. }
  129. /// Should this fragment be placed at the end of an aligned bundle?
  130. bool alignToBundleEnd() const { return AlignToBundleEnd; }
  131. void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
  132. /// Get the padding size that must be inserted before this fragment.
  133. /// Used for bundling. By default, no padding is inserted.
  134. /// Note that padding size is restricted to 8 bits. This is an optimization
  135. /// to reduce the amount of space used for each fragment. In practice, larger
  136. /// padding should never be required.
  137. uint8_t getBundlePadding() const { return BundlePadding; }
  138. /// Set the padding size for this fragment. By default it's a no-op,
  139. /// and only some fragments have a meaningful implementation.
  140. void setBundlePadding(uint8_t N) { BundlePadding = N; }
  141. /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
  142. /// Guaranteed to be non-null if hasInstructions() == true
  143. const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
  144. /// Record that the fragment contains instructions with the MCSubtargetInfo in
  145. /// effect when the instruction was encoded.
  146. void setHasInstructions(const MCSubtargetInfo &STI) {
  147. HasInstructions = true;
  148. this->STI = &STI;
  149. }
  150. };
  151. /// Interface implemented by fragments that contain encoded instructions and/or
  152. /// data.
  153. ///
  154. template<unsigned ContentsSize>
  155. class MCEncodedFragmentWithContents : public MCEncodedFragment {
  156. SmallVector<char, ContentsSize> Contents;
  157. protected:
  158. MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
  159. bool HasInstructions,
  160. MCSection *Sec)
  161. : MCEncodedFragment(FType, HasInstructions, Sec) {}
  162. public:
  163. SmallVectorImpl<char> &getContents() { return Contents; }
  164. const SmallVectorImpl<char> &getContents() const { return Contents; }
  165. };
  166. /// Interface implemented by fragments that contain encoded instructions and/or
  167. /// data and also have fixups registered.
  168. ///
  169. template<unsigned ContentsSize, unsigned FixupsSize>
  170. class MCEncodedFragmentWithFixups :
  171. public MCEncodedFragmentWithContents<ContentsSize> {
  172. /// The list of fixups in this fragment.
  173. SmallVector<MCFixup, FixupsSize> Fixups;
  174. protected:
  175. MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
  176. bool HasInstructions,
  177. MCSection *Sec)
  178. : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
  179. Sec) {}
  180. public:
  181. using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
  182. using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
  183. SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
  184. const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
  185. fixup_iterator fixup_begin() { return Fixups.begin(); }
  186. const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
  187. fixup_iterator fixup_end() { return Fixups.end(); }
  188. const_fixup_iterator fixup_end() const { return Fixups.end(); }
  189. static bool classof(const MCFragment *F) {
  190. MCFragment::FragmentType Kind = F->getKind();
  191. return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
  192. Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf ||
  193. Kind == MCFragment::FT_DwarfFrame;
  194. }
  195. };
  196. /// Fragment for data and encoded instructions.
  197. ///
  198. class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
  199. public:
  200. MCDataFragment(MCSection *Sec = nullptr)
  201. : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
  202. static bool classof(const MCFragment *F) {
  203. return F->getKind() == MCFragment::FT_Data;
  204. }
  205. };
  206. /// This is a compact (memory-size-wise) fragment for holding an encoded
  207. /// instruction (non-relaxable) that has no fixups registered. When applicable,
  208. /// it can be used instead of MCDataFragment and lead to lower memory
  209. /// consumption.
  210. ///
  211. class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
  212. public:
  213. MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
  214. : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
  215. }
  216. static bool classof(const MCFragment *F) {
  217. return F->getKind() == MCFragment::FT_CompactEncodedInst;
  218. }
  219. };
  220. /// A relaxable fragment holds on to its MCInst, since it may need to be
  221. /// relaxed during the assembler layout and relaxation stage.
  222. ///
  223. class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
  224. /// The instruction this is a fragment for.
  225. MCInst Inst;
  226. /// Can we auto pad the instruction?
  227. bool AllowAutoPadding = false;
  228. public:
  229. MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
  230. MCSection *Sec = nullptr)
  231. : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
  232. Inst(Inst) { this->STI = &STI; }
  233. const MCInst &getInst() const { return Inst; }
  234. void setInst(const MCInst &Value) { Inst = Value; }
  235. bool getAllowAutoPadding() const { return AllowAutoPadding; }
  236. void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }
  237. static bool classof(const MCFragment *F) {
  238. return F->getKind() == MCFragment::FT_Relaxable;
  239. }
  240. };
  241. class MCAlignFragment : public MCFragment {
  242. /// The alignment to ensure, in bytes.
  243. unsigned Alignment;
  244. /// Flag to indicate that (optimal) NOPs should be emitted instead
  245. /// of using the provided value. The exact interpretation of this flag is
  246. /// target dependent.
  247. bool EmitNops : 1;
  248. /// Value to use for filling padding bytes.
  249. int64_t Value;
  250. /// The size of the integer (in bytes) of \p Value.
  251. unsigned ValueSize;
  252. /// The maximum number of bytes to emit; if the alignment
  253. /// cannot be satisfied in this width then this fragment is ignored.
  254. unsigned MaxBytesToEmit;
  255. /// When emitting Nops some subtargets have specific nop encodings.
  256. const MCSubtargetInfo *STI;
  257. public:
  258. MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
  259. unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
  260. : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
  261. Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
  262. unsigned getAlignment() const { return Alignment; }
  263. int64_t getValue() const { return Value; }
  264. unsigned getValueSize() const { return ValueSize; }
  265. unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
  266. bool hasEmitNops() const { return EmitNops; }
  267. void setEmitNops(bool Value, const MCSubtargetInfo *STI) {
  268. EmitNops = Value;
  269. this->STI = STI;
  270. }
  271. const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
  272. static bool classof(const MCFragment *F) {
  273. return F->getKind() == MCFragment::FT_Align;
  274. }
  275. };
  276. class MCFillFragment : public MCFragment {
  277. uint8_t ValueSize;
  278. /// Value to use for filling bytes.
  279. uint64_t Value;
  280. /// The number of bytes to insert.
  281. const MCExpr &NumValues;
  282. /// Source location of the directive that this fragment was created for.
  283. SMLoc Loc;
  284. public:
  285. MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues,
  286. SMLoc Loc, MCSection *Sec = nullptr)
  287. : MCFragment(FT_Fill, false, Sec), ValueSize(VSize), Value(Value),
  288. NumValues(NumValues), Loc(Loc) {}
  289. uint64_t getValue() const { return Value; }
  290. uint8_t getValueSize() const { return ValueSize; }
  291. const MCExpr &getNumValues() const { return NumValues; }
  292. SMLoc getLoc() const { return Loc; }
  293. static bool classof(const MCFragment *F) {
  294. return F->getKind() == MCFragment::FT_Fill;
  295. }
  296. };
  297. class MCNopsFragment : public MCFragment {
  298. /// The number of bytes to insert.
  299. int64_t Size;
  300. /// Maximum number of bytes allowed in each NOP instruction.
  301. int64_t ControlledNopLength;
  302. /// Source location of the directive that this fragment was created for.
  303. SMLoc Loc;
  304. /// When emitting Nops some subtargets have specific nop encodings.
  305. const MCSubtargetInfo &STI;
  306. public:
  307. MCNopsFragment(int64_t NumBytes, int64_t ControlledNopLength, SMLoc L,
  308. const MCSubtargetInfo &STI, MCSection *Sec = nullptr)
  309. : MCFragment(FT_Nops, false, Sec), Size(NumBytes),
  310. ControlledNopLength(ControlledNopLength), Loc(L), STI(STI) {}
  311. int64_t getNumBytes() const { return Size; }
  312. int64_t getControlledNopLength() const { return ControlledNopLength; }
  313. SMLoc getLoc() const { return Loc; }
  314. const MCSubtargetInfo *getSubtargetInfo() const { return &STI; }
  315. static bool classof(const MCFragment *F) {
  316. return F->getKind() == MCFragment::FT_Nops;
  317. }
  318. };
  319. class MCOrgFragment : public MCFragment {
  320. /// Value to use for filling bytes.
  321. int8_t Value;
  322. /// The offset this fragment should start at.
  323. const MCExpr *Offset;
  324. /// Source location of the directive that this fragment was created for.
  325. SMLoc Loc;
  326. public:
  327. MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc,
  328. MCSection *Sec = nullptr)
  329. : MCFragment(FT_Org, false, Sec), Value(Value), Offset(&Offset),
  330. Loc(Loc) {}
  331. const MCExpr &getOffset() const { return *Offset; }
  332. uint8_t getValue() const { return Value; }
  333. SMLoc getLoc() const { return Loc; }
  334. static bool classof(const MCFragment *F) {
  335. return F->getKind() == MCFragment::FT_Org;
  336. }
  337. };
  338. class MCLEBFragment : public MCFragment {
  339. /// True if this is a sleb128, false if uleb128.
  340. bool IsSigned;
  341. /// The value this fragment should contain.
  342. const MCExpr *Value;
  343. SmallString<8> Contents;
  344. public:
  345. MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
  346. : MCFragment(FT_LEB, false, Sec), IsSigned(IsSigned_), Value(&Value_) {
  347. Contents.push_back(0);
  348. }
  349. const MCExpr &getValue() const { return *Value; }
  350. bool isSigned() const { return IsSigned; }
  351. SmallString<8> &getContents() { return Contents; }
  352. const SmallString<8> &getContents() const { return Contents; }
  353. /// @}
  354. static bool classof(const MCFragment *F) {
  355. return F->getKind() == MCFragment::FT_LEB;
  356. }
  357. };
  358. class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
  359. /// The value of the difference between the two line numbers
  360. /// between two .loc dwarf directives.
  361. int64_t LineDelta;
  362. /// The expression for the difference of the two symbols that
  363. /// make up the address delta between two .loc dwarf directives.
  364. const MCExpr *AddrDelta;
  365. public:
  366. MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
  367. MCSection *Sec = nullptr)
  368. : MCEncodedFragmentWithFixups<8, 1>(FT_Dwarf, false, Sec),
  369. LineDelta(LineDelta), AddrDelta(&AddrDelta) {}
  370. int64_t getLineDelta() const { return LineDelta; }
  371. const MCExpr &getAddrDelta() const { return *AddrDelta; }
  372. static bool classof(const MCFragment *F) {
  373. return F->getKind() == MCFragment::FT_Dwarf;
  374. }
  375. };
  376. class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups<8, 1> {
  377. /// The expression for the difference of the two symbols that
  378. /// make up the address delta between two .cfi_* dwarf directives.
  379. const MCExpr *AddrDelta;
  380. public:
  381. MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
  382. : MCEncodedFragmentWithFixups<8, 1>(FT_DwarfFrame, false, Sec),
  383. AddrDelta(&AddrDelta) {}
  384. const MCExpr &getAddrDelta() const { return *AddrDelta; }
  385. static bool classof(const MCFragment *F) {
  386. return F->getKind() == MCFragment::FT_DwarfFrame;
  387. }
  388. };
  389. /// Represents a symbol table index fragment.
  390. class MCSymbolIdFragment : public MCFragment {
  391. const MCSymbol *Sym;
  392. public:
  393. MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
  394. : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
  395. const MCSymbol *getSymbol() { return Sym; }
  396. const MCSymbol *getSymbol() const { return Sym; }
  397. static bool classof(const MCFragment *F) {
  398. return F->getKind() == MCFragment::FT_SymbolId;
  399. }
  400. };
  401. /// Fragment representing the binary annotations produced by the
  402. /// .cv_inline_linetable directive.
  403. class MCCVInlineLineTableFragment : public MCFragment {
  404. unsigned SiteFuncId;
  405. unsigned StartFileId;
  406. unsigned StartLineNum;
  407. const MCSymbol *FnStartSym;
  408. const MCSymbol *FnEndSym;
  409. SmallString<8> Contents;
  410. /// CodeViewContext has the real knowledge about this format, so let it access
  411. /// our members.
  412. friend class CodeViewContext;
  413. public:
  414. MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
  415. unsigned StartLineNum, const MCSymbol *FnStartSym,
  416. const MCSymbol *FnEndSym,
  417. MCSection *Sec = nullptr)
  418. : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
  419. StartFileId(StartFileId), StartLineNum(StartLineNum),
  420. FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
  421. const MCSymbol *getFnStartSym() const { return FnStartSym; }
  422. const MCSymbol *getFnEndSym() const { return FnEndSym; }
  423. SmallString<8> &getContents() { return Contents; }
  424. const SmallString<8> &getContents() const { return Contents; }
  425. static bool classof(const MCFragment *F) {
  426. return F->getKind() == MCFragment::FT_CVInlineLines;
  427. }
  428. };
  429. /// Fragment representing the .cv_def_range directive.
  430. class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
  431. SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges;
  432. SmallString<32> FixedSizePortion;
  433. /// CodeViewContext has the real knowledge about this format, so let it access
  434. /// our members.
  435. friend class CodeViewContext;
  436. public:
  437. MCCVDefRangeFragment(
  438. ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
  439. StringRef FixedSizePortion, MCSection *Sec = nullptr)
  440. : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),
  441. Ranges(Ranges.begin(), Ranges.end()),
  442. FixedSizePortion(FixedSizePortion) {}
  443. ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
  444. return Ranges;
  445. }
  446. StringRef getFixedSizePortion() const { return FixedSizePortion.str(); }
  447. static bool classof(const MCFragment *F) {
  448. return F->getKind() == MCFragment::FT_CVDefRange;
  449. }
  450. };
  451. /// Represents required padding such that a particular other set of fragments
  452. /// does not cross a particular power-of-two boundary. The other fragments must
  453. /// follow this one within the same section.
  454. class MCBoundaryAlignFragment : public MCFragment {
  455. /// The alignment requirement of the branch to be aligned.
  456. Align AlignBoundary;
  457. /// The last fragment in the set of fragments to be aligned.
  458. const MCFragment *LastFragment = nullptr;
  459. /// The size of the fragment. The size is lazily set during relaxation, and
  460. /// is not meaningful before that.
  461. uint64_t Size = 0;
  462. /// When emitting Nops some subtargets have specific nop encodings.
  463. const MCSubtargetInfo &STI;
  464. public:
  465. MCBoundaryAlignFragment(Align AlignBoundary, const MCSubtargetInfo &STI,
  466. MCSection *Sec = nullptr)
  467. : MCFragment(FT_BoundaryAlign, false, Sec), AlignBoundary(AlignBoundary),
  468. STI(STI) {}
  469. uint64_t getSize() const { return Size; }
  470. void setSize(uint64_t Value) { Size = Value; }
  471. Align getAlignment() const { return AlignBoundary; }
  472. void setAlignment(Align Value) { AlignBoundary = Value; }
  473. const MCFragment *getLastFragment() const { return LastFragment; }
  474. void setLastFragment(const MCFragment *F) {
  475. assert(!F || getParent() == F->getParent());
  476. LastFragment = F;
  477. }
  478. const MCSubtargetInfo *getSubtargetInfo() const { return &STI; }
  479. static bool classof(const MCFragment *F) {
  480. return F->getKind() == MCFragment::FT_BoundaryAlign;
  481. }
  482. };
  483. class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
  484. /// The expression for the difference of the two symbols that
  485. /// make up the address delta between two .pseudoprobe directives.
  486. const MCExpr *AddrDelta;
  487. public:
  488. MCPseudoProbeAddrFragment(const MCExpr *AddrDelta, MCSection *Sec = nullptr)
  489. : MCEncodedFragmentWithFixups<8, 1>(FT_PseudoProbe, false, Sec),
  490. AddrDelta(AddrDelta) {}
  491. const MCExpr &getAddrDelta() const { return *AddrDelta; }
  492. static bool classof(const MCFragment *F) {
  493. return F->getKind() == MCFragment::FT_PseudoProbe;
  494. }
  495. };
  496. } // end namespace llvm
  497. #endif // LLVM_MC_MCFRAGMENT_H
  498. #ifdef __GNUC__
  499. #pragma GCC diagnostic pop
  500. #endif