Add new merge-by-content Merge attribute for use by anonymous

constants and string literals which the linker should coalesce.

llvm-svn: 172495
This commit is contained in:
Nick Kledzik 2013-01-15 00:17:57 +00:00
parent cb8a9a61f4
commit 233f537799
8 changed files with 88 additions and 17 deletions

View File

@ -101,8 +101,9 @@ public:
mergeAsWeak, // is C++ inline definition that was not inlined,
// but address was not taken, so atom can be hidden
// by linker
mergeAsWeakAndAddressUsed // is C++ definition inline definition whose
mergeAsWeakAndAddressUsed,// is C++ definition inline definition whose
// address was taken.
mergeByContent // merge with other constants with same content
};
enum ContentType {

View File

@ -110,11 +110,8 @@ void Resolver::doDefinedAtom(const DefinedAtom &atom) {
// add to list of known atoms
_atoms.push_back(&atom);
// non-static atoms need extra handling
if (atom.scope() != DefinedAtom::scopeTranslationUnit) {
// tell symbol table about non-static atoms
_symbolTable.add(atom);
}
// tell symbol table
_symbolTable.add(atom);
if (_options.deadCodeStripping()) {
// add to set of dead-strip-roots, all symbols that

View File

@ -46,11 +46,16 @@ void SymbolTable::add(const AbsoluteAtom &atom) {
}
void SymbolTable::add(const DefinedAtom &atom) {
assert(atom.scope() != DefinedAtom::scopeTranslationUnit);
if ( !atom.name().empty() ) {
if (!atom.name().empty() &&
(atom.scope() != DefinedAtom::scopeTranslationUnit)) {
// Named atoms cannot be merged by content.
assert(atom.merge() != DefinedAtom::mergeByContent);
// Track named atoms that are not scoped to file (static).
this->addByName(atom);
}
else {
else if ( atom.merge() == DefinedAtom::mergeByContent ) {
// Named atoms cannot be merged by content.
assert(atom.name().empty());
this->addByContent(atom);
}
}
@ -123,6 +128,7 @@ static MergeResolution mergeSelect(DefinedAtom::Merge first,
void SymbolTable::addByName(const Atom & newAtom) {
StringRef name = newAtom.name();
assert(!name.empty());
const Atom *existing = this->findByName(name);
if (existing == nullptr) {
// Name is not in symbol table yet, add it associate with this atom.
@ -283,6 +289,8 @@ bool SymbolTable::AtomMappingInfo::isEqual(const DefinedAtom * const l,
}
void SymbolTable::addByContent(const DefinedAtom & newAtom) {
// Currently only read-only constants can be merged.
assert(newAtom.permissions() == DefinedAtom::permR__);
AtomContentSet::iterator pos = _contentTable.find(&newAtom);
if ( pos == _contentTable.end() ) {
_contentTable.insert(&newAtom);

View File

@ -351,6 +351,7 @@ struct ScalarEnumerationTraits<lld::DefinedAtom::Merge> {
io.enumCase(value, "as-weak", lld::DefinedAtom::mergeAsWeak);
io.enumCase(value, "as-addressed-weak",
lld::DefinedAtom::mergeAsWeakAndAddressUsed);
io.enumCase(value, "by-content", lld::DefinedAtom::mergeByContent);
}
};

View File

@ -0,0 +1,60 @@
# RUN: lld-core %s | FileCheck %s
#
# Test that duplicate merge-by-content anonymous constants are coalesced
# and non-mergable duplicate constants are not coalesced.
#
---
defined-atoms:
- ref-name: L4-byte
type: constant
merge: by-content
content: [ 01, 02, 03, 04 ]
- ref-name: L8-byte
type: constant
merge: by-content
content: [ 01, 23, 45, 67, 89, AB, CD, EF ]
- ref-name: L1
type: constant
content: [ 01, 02 ]
---
defined-atoms:
- ref-name: L1
type: constant
content: [ 01, 02 ]
- ref-name: L2
type: constant
merge: by-content
content: [ 01, 02, 03, 04 ]
---
defined-atoms:
- ref-name: L2
type: constant
merge: by-content
content: [ 01, 23, 45, 67, 89, AB, CD, EF ]
- ref-name: L3
type: constant
merge: by-content
content: [ 01, 02, 03 ]
...
# CHECK-NOT: name:
# CHECK: type: constant
# CHECK: content: [ 01, 02, 03, 04 ]
# CHECK: merge: by-content
# CHECK: type: constant
# CHECK: content: [ 01, 23, 45, 67, 89, AB, CD, EF ]
# CHECK: merge: by-content
# CHECK: type: constant
# CHECK: content: [ 01, 02 ]
# CHECK: type: constant
# CHECK: content: [ 01, 02 ]
# CHECK: type: constant
# CHECK: content: [ 01, 02, 03 ]
# CHECK: merge: by-content
# CHECK: ...

View File

@ -7,31 +7,35 @@
---
defined-atoms:
- ref-name: L0
scope: hidden
type: c-string
merge: by-content
content: [ 68, 65, 6c, 6c, 6f, 00 ]
- ref-name: L1
scope: hidden
type: c-string
merge: by-content
content: [ 74, 68, 65, 72, 65, 00 ]
---
defined-atoms:
- ref-name: L2
scope: hidden
type: c-string
merge: by-content
content: [ 68, 65, 6c, 6c, 6f, 00 ]
---
defined-atoms:
- ref-name: L2
scope: hidden
type: c-string
merge: by-content
content: [ 74, 68, 65, 72, 65, 00 ]
...
# CHECK-NOT: name:
# CHECK: type: c-string
# CHECK: content: [ 68, 65, 6C, 6C, 6F, 00 ]
# CHECK: merge: by-content
# CHECK: type: c-string
# CHECK: content: [ 74, 68, 65, 72, 65, 00 ]
# CHECK-NOT: name:
# CHECK: merge: by-content
# CHECK: ...

View File

@ -21,8 +21,8 @@ defined-atoms:
target: _printf
- ref-name: LC1
scope: hidden
type: c-string
merge: by-content
content: [ 68, 65, 6C, 6C, 6F, 0A, 00 ]
shared-library-atoms:

View File

@ -20,13 +20,13 @@ defined-atoms:
- ref-name: LC1
scope: hidden
type: c-string
merge: by-content
content: [ 68, 65, 6c, 6c, 6f, 00 ]
- ref-name: LC2
scope: hidden
type: c-string
merge: by-content
content: [ 74, 68, 65, 72, 65, 00 ]