Line data Source code
1 : //===- MCSection.h - Machine Code Sections ----------------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file declares the MCSection class.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_MC_MCSECTION_H
15 : #define LLVM_MC_MCSECTION_H
16 :
17 : #include "llvm/ADT/SmallVector.h"
18 : #include "llvm/ADT/ilist.h"
19 : #include "llvm/MC/MCFragment.h"
20 : #include "llvm/MC/SectionKind.h"
21 : #include <cassert>
22 : #include <utility>
23 :
24 : namespace llvm {
25 :
26 : class MCAsmInfo;
27 : class MCContext;
28 : class MCExpr;
29 : class MCSymbol;
30 : class raw_ostream;
31 : class Triple;
32 :
33 : template <> struct ilist_alloc_traits<MCFragment> {
34 : static void deleteNode(MCFragment *V);
35 : };
36 :
37 : /// Instances of this class represent a uniqued identifier for a section in the
38 : /// current translation unit. The MCContext class uniques and creates these.
39 2947670 : class MCSection {
40 : public:
41 : enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm };
42 :
43 : /// Express the state of bundle locked groups while emitting code.
44 : enum BundleLockStateType {
45 : NotBundleLocked,
46 : BundleLocked,
47 : BundleLockedAlignToEnd
48 : };
49 :
50 : using FragmentListType = iplist<MCFragment>;
51 :
52 : using const_iterator = FragmentListType::const_iterator;
53 : using iterator = FragmentListType::iterator;
54 :
55 : using const_reverse_iterator = FragmentListType::const_reverse_iterator;
56 : using reverse_iterator = FragmentListType::reverse_iterator;
57 :
58 : private:
59 : MCSymbol *Begin;
60 : MCSymbol *End = nullptr;
61 : /// The alignment requirement of this section.
62 : unsigned Alignment = 1;
63 : /// The section index in the assemblers section list.
64 : unsigned Ordinal = 0;
65 : /// The index of this section in the layout order.
66 : unsigned LayoutOrder;
67 :
68 : /// Keeping track of bundle-locked state.
69 : BundleLockStateType BundleLockState = NotBundleLocked;
70 :
71 : /// Current nesting depth of bundle_lock directives.
72 : unsigned BundleLockNestingDepth = 0;
73 :
74 : /// We've seen a bundle_lock directive but not its first instruction
75 : /// yet.
76 : bool BundleGroupBeforeFirstInst : 1;
77 :
78 : /// Whether this section has had instructions emitted into it.
79 : bool HasInstructions : 1;
80 :
81 : /// Whether this section has had data emitted into it.
82 : /// Right now this is only used by the ARM backend.
83 : bool HasData : 1;
84 :
85 : bool IsRegistered : 1;
86 :
87 : MCDummyFragment DummyFragment;
88 :
89 : FragmentListType Fragments;
90 :
91 : /// Mapping from subsection number to insertion point for subsection numbers
92 : /// below that number.
93 : SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
94 :
95 : protected:
96 : SectionVariant Variant;
97 : SectionKind Kind;
98 :
99 : MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin);
100 : ~MCSection();
101 :
102 : public:
103 : MCSection(const MCSection &) = delete;
104 : MCSection &operator=(const MCSection &) = delete;
105 :
106 0 : SectionKind getKind() const { return Kind; }
107 :
108 0 : SectionVariant getVariant() const { return Variant; }
109 :
110 0 : MCSymbol *getBeginSymbol() { return Begin; }
111 : const MCSymbol *getBeginSymbol() const {
112 2881049 : return const_cast<MCSection *>(this)->getBeginSymbol();
113 : }
114 0 : void setBeginSymbol(MCSymbol *Sym) {
115 : assert(!Begin);
116 90 : Begin = Sym;
117 0 : }
118 : MCSymbol *getEndSymbol(MCContext &Ctx);
119 : bool hasEnded() const;
120 :
121 0 : unsigned getAlignment() const { return Alignment; }
122 686584 : void setAlignment(unsigned Value) { Alignment = Value; }
123 :
124 0 : unsigned getOrdinal() const { return Ordinal; }
125 701329 : void setOrdinal(unsigned Value) { Ordinal = Value; }
126 :
127 0 : unsigned getLayoutOrder() const { return LayoutOrder; }
128 701321 : void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
129 :
130 0 : BundleLockStateType getBundleLockState() const { return BundleLockState; }
131 : void setBundleLockState(BundleLockStateType NewState);
132 3672031 : bool isBundleLocked() const { return BundleLockState != NotBundleLocked; }
133 :
134 : bool isBundleGroupBeforeFirstInst() const {
135 5065 : return BundleGroupBeforeFirstInst;
136 : }
137 : void setBundleGroupBeforeFirstInst(bool IsFirst) {
138 5234 : BundleGroupBeforeFirstInst = IsFirst;
139 : }
140 :
141 3631 : bool hasInstructions() const { return HasInstructions; }
142 30185752 : void setHasInstructions(bool Value) { HasInstructions = Value; }
143 :
144 2 : bool hasData() const { return HasData; }
145 11527741 : void setHasData(bool Value) { HasData = Value; }
146 :
147 806226 : bool isRegistered() const { return IsRegistered; }
148 701494 : void setIsRegistered(bool Value) { IsRegistered = Value; }
149 :
150 : MCSection::FragmentListType &getFragmentList() { return Fragments; }
151 : const MCSection::FragmentListType &getFragmentList() const {
152 : return const_cast<MCSection *>(this)->getFragmentList();
153 : }
154 :
155 : /// Support for MCFragment::getNextNode().
156 0 : static FragmentListType MCSection::*getSublistAccess(MCFragment *) {
157 0 : return &MCSection::Fragments;
158 : }
159 :
160 : const MCDummyFragment &getDummyFragment() const { return DummyFragment; }
161 8243078 : MCDummyFragment &getDummyFragment() { return DummyFragment; }
162 :
163 : iterator begin() { return Fragments.begin(); }
164 : const_iterator begin() const { return Fragments.begin(); }
165 :
166 : iterator end() { return Fragments.end(); }
167 : const_iterator end() const { return Fragments.end(); }
168 :
169 : reverse_iterator rbegin() { return Fragments.rbegin(); }
170 : const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
171 :
172 : reverse_iterator rend() { return Fragments.rend(); }
173 : const_reverse_iterator rend() const { return Fragments.rend(); }
174 :
175 : MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection);
176 :
177 : void dump() const;
178 :
179 : virtual void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
180 : raw_ostream &OS,
181 : const MCExpr *Subsection) const = 0;
182 :
183 : /// Return true if a .align directive should use "optimized nops" to fill
184 : /// instead of 0s.
185 : virtual bool UseCodeAlign() const = 0;
186 :
187 : /// Check whether this section is "virtual", that is has no actual object
188 : /// file contents.
189 : virtual bool isVirtualSection() const = 0;
190 : };
191 :
192 : } // end namespace llvm
193 :
194 : #endif // LLVM_MC_MCSECTION_H
|