LLVM  11.0.0git
MCSection.cpp
Go to the documentation of this file.
1 //===- lib/MC/MCSection.cpp - Machine Code Section Representation ---------===//
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 #include "llvm/MC/MCSection.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/Config/llvm-config.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCFragment.h"
14 #include "llvm/MC/MCSymbol.h"
15 #include "llvm/Support/Compiler.h"
18 #include <algorithm>
19 #include <utility>
20 
21 using namespace llvm;
22 
24  MCSymbol *Begin)
25  : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false),
26  IsRegistered(false), DummyFragment(this), Name(Name), Variant(V),
27  Kind(K) {}
28 
30  if (!End)
31  End = Ctx.createTempSymbol("sec_end", true);
32  return End;
33 }
34 
35 bool MCSection::hasEnded() const { return End && End->isInSection(); }
36 
37 MCSection::~MCSection() = default;
38 
40  if (NewState == NotBundleLocked) {
41  if (BundleLockNestingDepth == 0) {
42  report_fatal_error("Mismatched bundle_lock/unlock directives");
43  }
44  if (--BundleLockNestingDepth == 0) {
45  BundleLockState = NotBundleLocked;
46  }
47  return;
48  }
49 
50  // If any of the directives is an align_to_end directive, the whole nested
51  // group is align_to_end. So don't downgrade from align_to_end to just locked.
52  if (BundleLockState != BundleLockedAlignToEnd) {
53  BundleLockState = NewState;
54  }
55  ++BundleLockNestingDepth;
56 }
57 
60  if (Subsection == 0 && SubsectionFragmentMap.empty())
61  return end();
62 
64  std::lower_bound(SubsectionFragmentMap.begin(),
65  SubsectionFragmentMap.end(),
66  std::make_pair(Subsection, (MCFragment *)nullptr));
67  bool ExactMatch = false;
68  if (MI != SubsectionFragmentMap.end()) {
69  ExactMatch = MI->first == Subsection;
70  if (ExactMatch)
71  ++MI;
72  }
73  iterator IP;
74  if (MI == SubsectionFragmentMap.end())
75  IP = end();
76  else
77  IP = MI->second->getIterator();
78  if (!ExactMatch && Subsection != 0) {
79  // The GNU as documentation claims that subsections have an alignment of 4,
80  // although this appears not to be the case.
81  MCFragment *F = new MCDataFragment();
82  SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F));
83  getFragmentList().insert(IP, F);
84  F->setParent(this);
85  }
86 
87  return IP;
88 }
89 
90 StringRef MCSection::getVirtualSectionKind() const { return "virtual"; }
91 
92 void MCSection::addPendingLabel(MCSymbol *label, unsigned Subsection) {
93  PendingLabels.push_back(PendingLabel(label, Subsection));
94 }
95 
96 void MCSection::flushPendingLabels(MCFragment *F, uint64_t FOffset,
97  unsigned Subsection) {
98  if (PendingLabels.empty())
99  return;
100 
101  // Set the fragment and fragment offset for all pending symbols in the
102  // specified Subsection, and remove those symbols from the pending list.
103  for (auto It = PendingLabels.begin(); It != PendingLabels.end(); ++It) {
104  PendingLabel& Label = *It;
105  if (Label.Subsection == Subsection) {
106  Label.Sym->setFragment(F);
107  Label.Sym->setOffset(FOffset);
108  PendingLabels.erase(It--);
109  }
110  }
111 }
112 
114  // Make sure all remaining pending labels point to data fragments, by
115  // creating new empty data fragments for each Subsection with labels pending.
116  while (!PendingLabels.empty()) {
117  PendingLabel& Label = PendingLabels[0];
118  iterator CurInsertionPoint =
119  this->getSubsectionInsertionPoint(Label.Subsection);
120  MCFragment *F = new MCDataFragment();
121  getFragmentList().insert(CurInsertionPoint, F);
122  F->setParent(this);
123  flushPendingLabels(F, 0, Label.Subsection);
124  }
125 }
126 
127 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
129  raw_ostream &OS = errs();
130 
131  OS << "<MCSection";
132  OS << " Fragments:[\n ";
133  for (auto it = begin(), ie = end(); it != ie; ++it) {
134  if (it != begin())
135  OS << ",\n ";
136  it->dump();
137  }
138  OS << "]>";
139 }
140 #endif
void addPendingLabel(MCSymbol *label, unsigned Subsection=0)
Add a pending label for the requested subsection.
Definition: MCSection.cpp:92
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:23
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:508
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:69
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
void push_back(const T &Elt)
Definition: SmallVector.h:246
MCSection(SectionVariant V, StringRef Name, SectionKind K, MCSymbol *Begin)
Definition: MCSection.cpp:23
void setBundleLockState(BundleLockStateType NewState)
Definition: MCSection.cpp:39
F(f)
void dump() const
Definition: MCSection.cpp:128
BundleLockStateType
Express the state of bundle locked groups while emitting code.
Definition: MCSection.h:46
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
Definition: MCSymbol.h:245
MCSymbol * getEndSymbol(MCContext &Ctx)
Definition: MCSection.cpp:29
Context object for machine code objects.
Definition: MCContext.h:66
bool hasEnded() const
Definition: MCSection.cpp:35
void flushPendingLabels()
Associate all pending labels with empty data fragments.
Definition: MCSection.cpp:113
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1586
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
Definition: MCContext.cpp:239
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:22
iterator erase(const_iterator CI)
Definition: SmallVector.h:480
Iterator for intrusive lists based on ilist_node.
iterator insert(iterator where, pointer New)
Definition: ilist.h:228
virtual StringRef getVirtualSectionKind() const
Definition: MCSection.cpp:90
Fragment for data and encoded instructions.
Definition: MCFragment.h:229
MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection)
Definition: MCSection.cpp:59
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
iterator end()
Definition: MCSection.h:173
void setParent(MCSection *Value)
Definition: MCFragment.h:88
MCSection::FragmentListType & getFragmentList()
Definition: MCSection.h:157
iterator begin()
Definition: MCSection.h:170