[ELF] Refactor ThunkCreator to not key on OutputSection for Thunks

In preparation for inserting Thunks into InputSectionDescriptions this
simple change associates added Thunks with a vector of InputSections instead
of an OutputSection. As of now we are just using OutputSection::Sections.

Differential Revision: https://reviews.llvm.org/D33832

llvm-svn: 304782
This commit is contained in:
Peter Smith 2017-06-06 09:42:44 +00:00
parent 28f03bbcbb
commit 8f7565b6f2
2 changed files with 37 additions and 32 deletions

View File

@ -967,33 +967,38 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
// in the Sections vector, and recalculate the InputSection output section // in the Sections vector, and recalculate the InputSection output section
// offsets. // offsets.
// This may invalidate any output section offsets stored outside of InputSection // This may invalidate any output section offsets stored outside of InputSection
void ThunkCreator::mergeThunks(OutputSection *OS, void ThunkCreator::mergeThunks() {
std::vector<ThunkSection *> &Thunks) { for (auto &KV : ThunkSections) {
// Order Thunks in ascending OutSecOff std::vector<InputSection *> *ISR = KV.first;
auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) { std::vector<ThunkSection *> &Thunks = KV.second;
return A->OutSecOff < B->OutSecOff;
};
std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
// Merge sorted vectors of Thunks and InputSections by OutSecOff // Order Thunks in ascending OutSecOff
std::vector<InputSection *> Tmp; auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
Tmp.reserve(OS->Sections.size() + Thunks.size()); return A->OutSecOff < B->OutSecOff;
auto MergeCmp = [](const InputSection *A, const InputSection *B) { };
// std::merge requires a strict weak ordering. std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
if (A->OutSecOff < B->OutSecOff)
return true; // Merge sorted vectors of Thunks and InputSections by OutSecOff
if (A->OutSecOff == B->OutSecOff) std::vector<InputSection *> Tmp;
// Check if Thunk is immediately before any specific Target InputSection Tmp.reserve(ISR->size() + Thunks.size());
// for example Mips LA25 Thunks. auto MergeCmp = [](const InputSection *A, const InputSection *B) {
if (auto *TA = dyn_cast<ThunkSection>(A)) // std::merge requires a strict weak ordering.
if (TA && TA->getTargetInputSection() == B) if (A->OutSecOff < B->OutSecOff)
return true; return true;
return false; if (A->OutSecOff == B->OutSecOff)
}; // Check if Thunk is immediately before any specific Target InputSection
std::merge(OS->Sections.begin(), OS->Sections.end(), Thunks.begin(), // for example Mips LA25 Thunks.
Thunks.end(), std::back_inserter(Tmp), MergeCmp); if (auto *TA = dyn_cast<ThunkSection>(A))
OS->Sections = std::move(Tmp); if (TA && TA->getTargetInputSection() == B)
OS->assignOffsets(); return true;
return false;
};
std::merge(ISR->begin(), ISR->end(), Thunks.begin(), Thunks.end(),
std::back_inserter(Tmp), MergeCmp);
OutputSection *OS = Thunks.front()->getParent();
OS->Sections = std::move(Tmp);
OS->assignOffsets();
}
} }
ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS, ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS,
@ -1006,7 +1011,7 @@ ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS,
break; break;
} }
TS = make<ThunkSection>(OS, Off); TS = make<ThunkSection>(OS, Off);
ThunkSections[OS].push_back(TS); ThunkSections[&OS->Sections].push_back(TS);
} }
return TS; return TS;
} }
@ -1017,7 +1022,7 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
return TS; return TS;
auto *TOS = IS->getParent(); auto *TOS = IS->getParent();
TS = make<ThunkSection>(TOS, IS->OutSecOff); TS = make<ThunkSection>(TOS, IS->OutSecOff);
ThunkSections[TOS].push_back(TS); ThunkSections[&TOS->Sections].push_back(TS);
ThunkedSections[IS] = TS; ThunkedSections[IS] = TS;
return TS; return TS;
} }
@ -1074,8 +1079,7 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
} }
// Merge all created synthetic ThunkSections back into OutputSection // Merge all created synthetic ThunkSections back into OutputSection
for (auto &KV : ThunkSections) mergeThunks();
mergeThunks(KV.first, KV.second);
return !ThunkSections.empty(); return !ThunkSections.empty();
} }

View File

@ -126,7 +126,7 @@ public:
bool createThunks(ArrayRef<OutputSection *> OutputSections); bool createThunks(ArrayRef<OutputSection *> OutputSections);
private: private:
void mergeThunks(OutputSection *OS, std::vector<ThunkSection *> &Thunks); void mergeThunks();
ThunkSection *getOSThunkSec(ThunkSection *&TS, OutputSection *OS); ThunkSection *getOSThunkSec(ThunkSection *&TS, OutputSection *OS);
ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS); ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type); std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
@ -138,7 +138,8 @@ private:
llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections; llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections;
// Track the ThunksSections that need to be inserted into an OutputSection // Track the ThunksSections that need to be inserted into an OutputSection
std::map<OutputSection *, std::vector<ThunkSection *>> ThunkSections; std::map<std::vector<InputSection *> *, std::vector<ThunkSection *>>
ThunkSections;
}; };
// Return a int64_t to make sure we get the sign extension out of the way as // Return a int64_t to make sure we get the sign extension out of the way as