summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCAssembler.h11
-rw-r--r--include/llvm/MC/MCSymbol.h71
-rw-r--r--lib/MC/MCAssembler.cpp10
-rw-r--r--lib/MC/MCELF.cpp1
-rw-r--r--lib/MC/MCMachOStreamer.cpp4
-rw-r--r--lib/MC/MCSymbol.cpp3
6 files changed, 64 insertions, 36 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index d335db92d0c..a6178c214d4 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -23,7 +23,6 @@
#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <algorithm>
@@ -910,15 +909,7 @@ public:
return true;
}
- void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr) {
- bool New = !Symbol.isRegistered();
- if (Created)
- *Created = New;
- if (New) {
- Symbol.setIsRegistered(true);
- Symbols.push_back(&Symbol);
- }
- }
+ void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr);
ArrayRef<std::string> getFileNames() { return FileNames; }
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index 3194ed1863b..68c2d99a904 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -14,8 +14,8 @@
#ifndef LLVM_MC_MCSYMBOL_H
#define LLVM_MC_MCSYMBOL_H
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/Compiler.h"
@@ -44,10 +44,20 @@ class MCSymbol {
/// held by the StringMap that lives in MCContext.
const StringMapEntry<bool> *Name;
- /// The section the symbol is defined in. This is null for undefined symbols,
- /// and the special AbsolutePseudoSection value for absolute symbols. If this
- /// is a variable symbol, this caches the variable value's section.
- mutable MCSection *Section;
+ /// If a symbol has a Fragment, the section is implied, so we only need
+ /// one pointer.
+ /// FIXME: We might be able to simplify this by having the asm streamer create
+ /// dummy fragments.
+ union {
+ /// The section the symbol is defined in. This is null for undefined
+ /// symbols, and the special AbsolutePseudoSection value for absolute
+ /// symbols. If this is a variable symbol, this caches the variable value's
+ /// section.
+ mutable MCSection *Section;
+
+ /// The fragment this symbol's value is relative to, if any.
+ mutable MCFragment *Fragment;
+ };
/// Value - If non-null, the value for a variable symbol.
const MCExpr *Value;
@@ -65,6 +75,14 @@ class MCSymbol {
mutable bool IsRegistered : 1;
+ /// This symbol is visible outside this translation unit.
+ mutable unsigned IsExternal : 1;
+
+ /// This symbol is private extern.
+ mutable unsigned IsPrivateExtern : 1;
+
+ mutable unsigned HasFragment : 1;
+
/// Index field, for use by the object file implementation.
mutable uint32_t Index = 0;
@@ -89,23 +107,22 @@ class MCSymbol {
/// additional per symbol information which is not easily classified.
mutable uint32_t Flags = 0;
- /// The fragment this symbol's value is relative to, if any. Also stores if
- /// this symbol is visible outside this translation unit (bit 0) or if it is
- /// private extern (bit 1).
- mutable PointerIntPair<MCFragment *, 2> Fragment;
-
private: // MCContext creates and uniques these.
friend class MCExpr;
friend class MCContext;
MCSymbol(const StringMapEntry<bool> *Name, bool isTemporary)
: Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary),
- IsRedefinable(false), IsUsed(false), IsRegistered(false) {
+ IsRedefinable(false), IsUsed(false), IsRegistered(false),
+ IsExternal(false), IsPrivateExtern(false), HasFragment(false) {
Offset = 0;
}
MCSymbol(const MCSymbol &) = delete;
void operator=(const MCSymbol &) = delete;
MCSection *getSectionPtr() const {
+ if (MCFragment *F = getFragment())
+ return F->getParent();
+ assert(!HasFragment);
if (Section || !Value)
return Section;
return Section = Value->findAssociatedSection();
@@ -137,6 +154,7 @@ public:
if (IsRedefinable) {
Value = nullptr;
Section = nullptr;
+ HasFragment = false;
IsRedefinable = false;
}
}
@@ -169,11 +187,15 @@ public:
/// Mark the symbol as defined in the section \p S.
void setSection(MCSection &S) {
assert(!isVariable() && "Cannot set section of variable");
+ assert(!HasFragment);
Section = &S;
}
- /// setUndefined - Mark the symbol as undefined.
- void setUndefined() { Section = nullptr; }
+ /// Mark the symbol as undefined.
+ void setUndefined() {
+ HasFragment = false;
+ Section = nullptr;
+ }
/// @}
/// \name Variable Symbols
@@ -252,19 +274,22 @@ public:
Flags = (Flags & ~Mask) | Value;
}
- MCFragment *getFragment() const { return Fragment.getPointer(); }
- void setFragment(MCFragment *Value) const { Fragment.setPointer(Value); }
-
- bool isExternal() const { return Fragment.getInt() & 1; }
- void setExternal(bool Value) const {
- Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value));
+ MCFragment *getFragment() const {
+ if (!HasFragment)
+ return nullptr;
+ return Fragment;
}
-
- bool isPrivateExtern() const { return Fragment.getInt() & 2; }
- void setPrivateExtern(bool Value) {
- Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1));
+ void setFragment(MCFragment *Value) const {
+ HasFragment = true;
+ Fragment = Value;
}
+ bool isExternal() const { return IsExternal; }
+ void setExternal(bool Value) const { IsExternal = Value; }
+
+ bool isPrivateExtern() const { return IsPrivateExtern; }
+ void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
+
/// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 7f09e748eb1..087caae59c4 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -579,6 +579,16 @@ static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) {
OW->WriteBytes(EF.getContents());
}
+void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) {
+ bool New = !Symbol.isRegistered();
+ if (Created)
+ *Created = New;
+ if (New) {
+ Symbol.setIsRegistered(true);
+ Symbols.push_back(&Symbol);
+ }
+}
+
void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize,
MCObjectWriter *OW) const {
// Should NOP padding be written out before this fragment?
diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp
index 2d27994428f..8d7fbf25549 100644
--- a/lib/MC/MCELF.cpp
+++ b/lib/MC/MCELF.cpp
@@ -13,6 +13,7 @@
#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCELFSymbolFlags.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/Support/ELF.h"
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 74ec6a8fe26..ff4b391789f 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -419,11 +419,11 @@ void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
if (ByteAlignment != 1)
new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, Section);
+ AssignSection(Symbol, Section);
+
MCFragment *F = new MCFillFragment(0, 0, Size, Section);
Symbol->setFragment(F);
- AssignSection(Symbol, Section);
-
// Update the maximum alignment on the zero fill section if necessary.
if (ByteAlignment > Section->getAlignment())
Section->setAlignment(ByteAlignment);
diff --git a/lib/MC/MCSymbol.cpp b/lib/MC/MCSymbol.cpp
index ddc381407df..35208eb0466 100644
--- a/lib/MC/MCSymbol.cpp
+++ b/lib/MC/MCSymbol.cpp
@@ -42,7 +42,8 @@ void MCSymbol::setVariableValue(const MCExpr *Value) {
assert(!IsUsed && "Cannot set a variable that has already been used.");
assert(Value && "Invalid variable value!");
this->Value = Value;
- this->Section = nullptr;
+ Section = nullptr;
+ HasFragment = false;
}
void MCSymbol::print(raw_ostream &OS) const {