Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

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