LLVM  14.0.0git
RecordStreamer.cpp
Go to the documentation of this file.
1 //===-- RecordStreamer.cpp - Record asm defined and used symbols ----------===//
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 "RecordStreamer.h"
10 #include "llvm/IR/Mangler.h"
11 #include "llvm/IR/Module.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCSymbol.h"
14 
15 using namespace llvm;
16 
17 void RecordStreamer::markDefined(const MCSymbol &Symbol) {
18  State &S = Symbols[Symbol.getName()];
19  switch (S) {
20  case DefinedGlobal:
21  case Global:
22  S = DefinedGlobal;
23  break;
24  case NeverSeen:
25  case Defined:
26  case Used:
27  S = Defined;
28  break;
29  case DefinedWeak:
30  break;
31  case UndefinedWeak:
32  S = DefinedWeak;
33  }
34 }
35 
36 void RecordStreamer::markGlobal(const MCSymbol &Symbol,
38  State &S = Symbols[Symbol.getName()];
39  switch (S) {
40  case DefinedGlobal:
41  case Defined:
43  break;
44 
45  case NeverSeen:
46  case Global:
47  case Used:
49  break;
50  case UndefinedWeak:
51  case DefinedWeak:
52  break;
53  }
54 }
55 
56 void RecordStreamer::markUsed(const MCSymbol &Symbol) {
57  State &S = Symbols[Symbol.getName()];
58  switch (S) {
59  case DefinedGlobal:
60  case Defined:
61  case Global:
62  case DefinedWeak:
63  case UndefinedWeak:
64  break;
65 
66  case NeverSeen:
67  case Used:
68  S = Used;
69  break;
70  }
71 }
72 
73 void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
74 
76  : MCStreamer(Context), M(M) {}
77 
79  return Symbols.begin();
80 }
81 
83 
85  const MCSubtargetInfo &STI) {
86  MCStreamer::emitInstruction(Inst, STI);
87 }
88 
91  markDefined(*Symbol);
92 }
93 
95  markDefined(*Symbol);
97 }
98 
102  markGlobal(*Symbol, Attribute);
104  markUsed(*Symbol);
105  return true;
106 }
107 
109  uint64_t Size, unsigned ByteAlignment,
110  SMLoc Loc) {
111  markDefined(*Symbol);
112 }
113 
115  unsigned ByteAlignment) {
116  markDefined(*Symbol);
117 }
118 
119 RecordStreamer::State RecordStreamer::getSymbolState(const MCSymbol *Sym) {
120  auto SI = Symbols.find(Sym->getName());
121  if (SI == Symbols.end())
122  return NeverSeen;
123  return SI->second;
124 }
125 
127  StringRef Name,
128  bool KeepOriginalSym) {
129  SymverAliasMap[OriginalSym].push_back(Name);
130 }
131 
134  return {SymverAliasMap.begin(), SymverAliasMap.end()};
135 }
136 
138  // Mapping from mangled name to GV.
139  StringMap<const GlobalValue *> MangledNameMap;
140  // The name in the assembler will be mangled, but the name in the IR
141  // might not, so we first compute a mapping from mangled name to GV.
142  Mangler Mang;
143  SmallString<64> MangledName;
144  for (const GlobalValue &GV : M.global_values()) {
145  if (!GV.hasName())
146  continue;
147  MangledName.clear();
148  MangledName.reserve(GV.getName().size() + 1);
149  Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
150  MangledNameMap[MangledName] = &GV;
151  }
152 
153  // Walk all the recorded .symver aliases, and set up the binding
154  // for each alias.
155  for (auto &Symver : SymverAliasMap) {
156  const MCSymbol *Aliasee = Symver.first;
157  MCSymbolAttr Attr = MCSA_Invalid;
158  bool IsDefined = false;
159 
160  // First check if the aliasee binding was recorded in the asm.
161  RecordStreamer::State state = getSymbolState(Aliasee);
162  switch (state) {
165  Attr = MCSA_Global;
166  break;
169  Attr = MCSA_Weak;
170  break;
171  default:
172  break;
173  }
174 
175  switch (state) {
179  IsDefined = true;
180  break;
185  break;
186  }
187 
188  if (Attr == MCSA_Invalid || !IsDefined) {
189  const GlobalValue *GV = M.getNamedValue(Aliasee->getName());
190  if (!GV) {
191  auto MI = MangledNameMap.find(Aliasee->getName());
192  if (MI != MangledNameMap.end())
193  GV = MI->second;
194  }
195  if (GV) {
196  // If we don't have a symbol attribute from assembly, then check if
197  // the aliasee was defined in the IR.
198  if (Attr == MCSA_Invalid) {
199  if (GV->hasExternalLinkage())
200  Attr = MCSA_Global;
201  else if (GV->hasLocalLinkage())
202  Attr = MCSA_Local;
203  else if (GV->isWeakForLinker())
204  Attr = MCSA_Weak;
205  }
206  IsDefined = IsDefined || !GV->isDeclarationForLinker();
207  }
208  }
209 
210  // Set the detected binding on each alias with this aliasee.
211  for (auto AliasName : Symver.second) {
212  std::pair<StringRef, StringRef> Split = AliasName.split("@@@");
213  SmallString<128> NewName;
214  if (!Split.second.empty() && !Split.second.startswith("@")) {
215  // Special processing for "@@@" according
216  // https://sourceware.org/binutils/docs/as/Symver.html
217  const char *Separator = IsDefined ? "@@" : "@";
218  AliasName =
219  (Split.first + Separator + Split.second).toStringRef(NewName);
220  }
221  MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
222  // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be
223  // converted into @ or @@.
224  const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
225  if (IsDefined)
226  markDefined(*Alias);
227  // Don't use EmitAssignment override as it always marks alias as defined.
229  if (Attr != MCSA_Invalid)
230  emitSymbolAttribute(Alias, Attr);
231  }
232  }
233 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::Module::global_values
iterator_range< global_value_iterator > global_values()
Definition: Module.cpp:424
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
M
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
Definition: README.txt:252
llvm::RecordStreamer::emitLabel
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
Definition: RecordStreamer.cpp:89
llvm::GlobalValue::hasExternalLinkage
bool hasExternalLinkage() const
Definition: GlobalValue.h:434
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::Attribute
Definition: Attributes.h:51
llvm::MCSA_Invalid
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19
llvm::StringMap::end
iterator end()
Definition: StringMap.h:203
Module.h
llvm::RecordStreamer::State
State
Definition: RecordStreamer.h:26
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::RecordStreamer::DefinedGlobal
@ DefinedGlobal
Definition: RecordStreamer.h:26
llvm::StringMap::find
iterator find(StringRef Key)
Definition: StringMap.h:216
llvm::Mangler
Definition: Mangler.h:27
llvm::RecordStreamer::Defined
@ Defined
Definition: RecordStreamer.h:26
llvm::MCSymbolAttr
MCSymbolAttr
Definition: MCDirectives.h:18
Context
ManagedStatic< detail::RecordContext > Context
Definition: Record.cpp:96
llvm::MCSA_Local
@ MCSA_Local
.local (ELF)
Definition: MCDirectives.h:37
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:82
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:199
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:191
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
MCContext.h
RecordStreamer.h
llvm::MCStreamer::emitLabel
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:415
MCSymbol.h
llvm::MCSA_LazyReference
@ MCSA_LazyReference
.lazy_reference (MachO)
Definition: MCDirectives.h:36
llvm::RecordStreamer::emitZerofill
void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, SMLoc Loc=SMLoc()) override
Emit the zerofill section and an optional symbol.
Definition: RecordStreamer.cpp:108
llvm::Mangler::getNameWithPrefix
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition: Mangler.cpp:119
llvm::dwarf::toStringRef
StringRef toStringRef(const Optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
Definition: DWARFFormValue.h:186
llvm::MCStreamer::emitAssignment
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
Definition: MCStreamer.cpp:1042
llvm::RecordStreamer::begin
const_iterator begin()
Definition: RecordStreamer.cpp:78
llvm::RecordStreamer::emitCommonSymbol
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit a common symbol.
Definition: RecordStreamer.cpp:114
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:198
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:108
llvm::SmallString< 64 >
llvm::RecordStreamer::symverAliases
iterator_range< const_symver_iterator > symverAliases()
Definition: RecordStreamer.cpp:133
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::RecordStreamer::RecordStreamer
RecordStreamer(MCContext &Context, const Module &M)
Definition: RecordStreamer.cpp:75
llvm::GlobalValue::isWeakForLinker
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
Definition: GlobalValue.h:381
uint64_t
llvm::MCStreamer::emitInstruction
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:1087
llvm::RecordStreamer::DefinedWeak
@ DefinedWeak
Definition: RecordStreamer.h:26
llvm::RecordStreamer::emitSymbolAttribute
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
Definition: RecordStreamer.cpp:99
llvm::StringMap::begin
iterator begin()
Definition: StringMap.h:202
SI
StandardInstrumentations SI(Debug, VerifyEach)
llvm::GlobalValue::hasLocalLinkage
bool hasLocalLinkage() const
Definition: GlobalValue.h:451
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Mangler.h
llvm::RecordStreamer::UndefinedWeak
@ UndefinedWeak
Definition: RecordStreamer.h:27
llvm::RecordStreamer::const_iterator
StringMap< State >::const_iterator const_iterator
Definition: RecordStreamer.h:74
llvm::RecordStreamer::end
const_iterator end()
Definition: RecordStreamer.cpp:82
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::MCSection
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
S
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
Definition: README.txt:210
llvm::RecordStreamer::emitAssignment
void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override
Emit an assignment of Value to Symbol.
Definition: RecordStreamer.cpp:94
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::RecordStreamer::Global
@ Global
Definition: RecordStreamer.h:26
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:585
llvm::MCSA_Global
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
llvm::LCOMM::ByteAlignment
@ ByteAlignment
Definition: MCAsmInfo.h:50
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
llvm::RecordStreamer::emitELFSymverDirective
void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, bool KeepOriginalSym) override
Record .symver aliases for later processing.
Definition: RecordStreamer.cpp:126
llvm::MCSA_Weak
@ MCSA_Weak
.weak
Definition: MCDirectives.h:44
llvm::MCStreamer::getContext
MCContext & getContext() const
Definition: MCStreamer.h:280
llvm::RecordStreamer::Used
@ Used
Definition: RecordStreamer.h:26
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::GlobalValue::isDeclarationForLinker
bool isDeclarationForLinker() const
Definition: GlobalValue.h:540
llvm::RecordStreamer::NeverSeen
@ NeverSeen
Definition: RecordStreamer.h:26
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:624
llvm::RecordStreamer::flushSymverDirectives
void flushSymverDirectives()
Definition: RecordStreamer.cpp:137
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::Module::getNamedValue
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type.
Definition: Module.cpp:113
llvm::RecordStreamer::emitInstruction
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
Definition: RecordStreamer.cpp:84