summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2013-01-15 00:17:57 +0000
committerNick Kledzik <kledzik@apple.com>2013-01-15 00:17:57 +0000
commit233f5377999892630b8869a6010638b5d9b6ddc7 (patch)
tree45e61291693a01d4e4efb033610d7baaf21f0602
parentcb8a9a61f4355578cbc3f45aacfcbb27e30023fc (diff)
downloadbcm5719-llvm-233f5377999892630b8869a6010638b5d9b6ddc7.tar.gz
bcm5719-llvm-233f5377999892630b8869a6010638b5d9b6ddc7.zip
Add new merge-by-content Merge attribute for use by anonymous
constants and string literals which the linker should coalesce. llvm-svn: 172495
-rw-r--r--lld/include/lld/Core/DefinedAtom.h3
-rw-r--r--lld/lib/Core/Resolver.cpp7
-rw-r--r--lld/lib/Core/SymbolTable.cpp14
-rw-r--r--lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp1
-rw-r--r--lld/test/constants-coalesce.objtxt60
-rw-r--r--lld/test/cstring-coalesce.objtxt14
-rw-r--r--lld/test/darwin/hello-world.objtxt2
-rw-r--r--lld/test/fixups-unnamed.objtxt4
8 files changed, 88 insertions, 17 deletions
diff --git a/lld/include/lld/Core/DefinedAtom.h b/lld/include/lld/Core/DefinedAtom.h
index 5c5b4acb47f..f3ab5434a1e 100644
--- a/lld/include/lld/Core/DefinedAtom.h
+++ b/lld/include/lld/Core/DefinedAtom.h
@@ -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 {
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp
index 8b426fae87f..7e0d2e2895b 100644
--- a/lld/lib/Core/Resolver.cpp
+++ b/lld/lib/Core/Resolver.cpp
@@ -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
diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp
index b3fe8e8a50e..1c7ea99ff05 100644
--- a/lld/lib/Core/SymbolTable.cpp
+++ b/lld/lib/Core/SymbolTable.cpp
@@ -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);
diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
index 0581c2e056a..310e8b41654 100644
--- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -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);
}
};
diff --git a/lld/test/constants-coalesce.objtxt b/lld/test/constants-coalesce.objtxt
new file mode 100644
index 00000000000..da388e50fe3
--- /dev/null
+++ b/lld/test/constants-coalesce.objtxt
@@ -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: ...
+
+
diff --git a/lld/test/cstring-coalesce.objtxt b/lld/test/cstring-coalesce.objtxt
index 5b37acca5c7..5723299c110 100644
--- a/lld/test/cstring-coalesce.objtxt
+++ b/lld/test/cstring-coalesce.objtxt
@@ -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: ...
+
+
diff --git a/lld/test/darwin/hello-world.objtxt b/lld/test/darwin/hello-world.objtxt
index 3b99933eb33..0d96c0746b0 100644
--- a/lld/test/darwin/hello-world.objtxt
+++ b/lld/test/darwin/hello-world.objtxt
@@ -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:
diff --git a/lld/test/fixups-unnamed.objtxt b/lld/test/fixups-unnamed.objtxt
index 20cf373580e..2c3d7aa09d9 100644
--- a/lld/test/fixups-unnamed.objtxt
+++ b/lld/test/fixups-unnamed.objtxt
@@ -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 ]
OpenPOWER on IntegriCloud