Skip to content

Commit ae679b2

Browse files
parth-07quic-seaswara
authored andcommitted
Remove unnecessary and incorrect sorting of input sections
This commit removes the unnecessary and incorrect sorting of input sections before the merge input sections phase when the LTO is enabled. Resolves #1204 Signed-off-by: Parth Arora <partaror@qti.qualcomm.com>
1 parent 282e30a commit ae679b2

7 files changed

Lines changed: 63 additions & 46 deletions

File tree

include/eld/Object/ObjectLinker.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,6 @@ class ObjectLinker {
269269
bool mergeInputSections(ObjectBuilder &Builder,
270270
std::vector<Section *> &Sections);
271271

272-
bool mayBeSortSections(std::vector<Section *> &Sections);
273-
274272
bool createOutputSection(ObjectBuilder &Builder, OutputSectionEntry *Output,
275273
bool PostLayout = false);
276274

lib/Object/ObjectLinker.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -784,44 +784,6 @@ void ObjectLinker::markDiscardFileFormatSections() {
784784
}
785785
}
786786

787-
bool ObjectLinker::mayBeSortSections(std::vector<Section *> &Sections) {
788-
// If no linker scripts, we dont store the original input. Lets not sort.
789-
if (!ThisModule->getScript().linkerScriptHasSectionsCommand())
790-
return true;
791-
if (ThisConfig.options().disableLTOLinkOrder())
792-
return true;
793-
// If we are doing partial link, lets not sort it.
794-
bool IsPartialLink = (LinkerConfig::Object == ThisConfig.codeGenType());
795-
if (IsPartialLink || LtoObjects.empty())
796-
return true;
797-
std::stable_sort(Sections.begin(), Sections.end(),
798-
[](Section *ASection, Section *BSection) {
799-
ELFSection *A = llvm::dyn_cast<ELFSection>(ASection);
800-
ELFSection *B = llvm::dyn_cast<ELFSection>(BSection);
801-
if (A == nullptr or B == nullptr)
802-
return false;
803-
// FIXME: Redundant checks. All files have original input.
804-
if (!A->originalInput())
805-
return false;
806-
if (!B->originalInput())
807-
return false;
808-
if ((A->name().starts_with(".ctors")) ||
809-
(B->name().starts_with(".ctors")))
810-
return false;
811-
if ((A->name().starts_with(".dtors")) ||
812-
(B->name().starts_with(".dtors")))
813-
return false;
814-
int64_t AOrdinal =
815-
A->originalInput()->getInput()->getInputOrdinal();
816-
int64_t BOrdinal =
817-
B->originalInput()->getInput()->getInputOrdinal();
818-
if (AOrdinal == BOrdinal)
819-
return false;
820-
return (AOrdinal < BOrdinal);
821-
});
822-
return true;
823-
}
824-
825787
bool ObjectLinker::mergeInputSections(ObjectBuilder &Builder,
826788
std::vector<Section *> &Sections) {
827789
bool IsPartialLink = ThisConfig.isLinkPartial();
@@ -1112,12 +1074,6 @@ bool ObjectLinker::initializeMerge() {
11121074
}
11131075
}
11141076
}
1115-
{
1116-
eld::RegisterTimer T("Sort sections if LTO enabled", "Merge Sections",
1117-
ThisConfig.options().printTimingStats());
1118-
// Sort sections if we have LTO enabled.
1119-
mayBeSortSections(AllInputSections);
1120-
}
11211077
return true;
11221078
}
11231079

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__attribute__((section(".ctors"))) int bar() { return 6; }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int baz() { return 5; }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import sys
2+
3+
N = 300
4+
output = sys.argv[1]
5+
6+
with open(output, 'w') as f:
7+
f.write("int bar();\n")
8+
f.write("int baz();\n")
9+
for i in range(N):
10+
f.write(f"int foo_{i}() {{ return {i}; }}\n")
11+
f.write("int main() {\n return ")
12+
for i in range(N):
13+
f.write(f"foo_{i}()")
14+
if i != N - 1:
15+
f.write(" + ")
16+
f.write(" + baz() + bar();\n}\n")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SECTIONS {
2+
.text : { *(.text*) }
3+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
UNSUPPORTED: x86
2+
#---NonLTOSectionsOrderWithLTO.test------------- Executable,LTO,LS ----------------#
3+
#BEGIN_COMMENT
4+
# When a linker script rule matches input sections without explicit ordering,
5+
# the output should contain matched input sections in input order. With LTO,
6+
# ordering is relaxed for LTO-generated sections, but sections from non-LTO
7+
# object files must still maintain their original order. This test verifies
8+
# that non-LTO input section ordering is preserved when mixed with LTO objects.
9+
#END_COMMENT
10+
#START_TEST
11+
RUN: %python %p/Inputs/gen.py %t1.1.c
12+
RUN: %clang %clangopts -o %t1.1.o -c %t1.1.c -ffunction-sections
13+
RUN: %clang %clangopts -o %t1.2.o -c %p/Inputs/2.c -flto -ffunction-sections
14+
RUN: %clang %clangopts -o %t1.3.o -c %p/Inputs/3.c -flto -ffunction-sections
15+
RUN: %link -MapStyle txt %linkopts -o %t2.out %t1.2.o %t1.1.o %t1.3.o -T %p/Inputs/script.t -e main -Map %t2.map
16+
RUN: %filecheck %s < %t2.map
17+
#END_TEST
18+
19+
CHECK: .text.foo_0
20+
CHECK: .text.foo_1
21+
CHECK: .text.foo_2
22+
CHECK: .text.foo_3
23+
CHECK: .text.foo_4
24+
CHECK: .text.foo_5
25+
CHECK: .text.foo_6
26+
CHECK: .text.foo_7
27+
CHECK: .text.foo_8
28+
CHECK: .text.foo_9
29+
CHECK: .text.foo_10
30+
CHECK: .text.foo_11
31+
CHECK: .text.foo_12
32+
CHECK: .text.foo_13
33+
CHECK: .text.foo_14
34+
CHECK: .text.foo_15
35+
CHECK: .text.foo_16
36+
CHECK: .text.foo_17
37+
CHECK: .text.foo_18
38+
CHECK: .text.foo_19
39+
CHECK: .text.foo_20
40+
CHECK: .text.foo_298
41+
CHECK: .text.foo_299
42+
CHECK: .text.main

0 commit comments

Comments
 (0)