IdenticalCodeFolding.cpp revision 2bf3f881f79c4d883f379e63725e788c310739a3
1b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou//===- IndenticalCodeFolding.cpp ------------------------------------------===// 2b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// 3b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// The MCLinker Project 4b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// 5b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// This file is distributed under the University of Illinois Open Source 6b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// License. See LICENSE.TXT for details. 7b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// 8b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/IdenticalCodeFolding.h" 10b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/GeneralOptions.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/RegionFragment.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocData.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/Relocator.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ResolveInfo.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Input.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Demangle.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h" 25b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 26b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <llvm/ADT/StringRef.h> 27b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <llvm/Support/Casting.h> 28b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <llvm/Support/Format.h> 29b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 30b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <cassert> 31b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <map> 32b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <set> 33b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 34b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <zlib.h> 35b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic bool isSymCtorOrDtor(const ResolveInfo& pSym) { 39b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // We can always fold ctors and dtors since accessing function pointer in C++ 40b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // is forbidden. 41b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou llvm::StringRef name(pSym.name(), pSym.nameSize()); 42b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (!name.startswith("_ZZ") && !name.startswith("_ZN")) { 43b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou return false; 44b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 45b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou return isCtorOrDtor(pSym.name(), pSym.nameSize()); 46b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 47b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 48b3323086ee04f9db9e85f7cae46510f91a137237Pete ChouIdenticalCodeFolding::IdenticalCodeFolding(const LinkerConfig& pConfig, 49b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const TargetLDBackend& pBackend, 50b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Module& pModule) 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_Config(pConfig), m_Backend(pBackend), m_Module(pModule) { 52b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 53b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IdenticalCodeFolding::foldIdenticalCode() { 55b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // 1. Find folding candidates. 56b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou FoldingCandidates candidate_list; 57b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou findCandidates(candidate_list); 58b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 59b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // 2. Initialize constant section content 60b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (size_t i = 0; i < candidate_list.size(); ++i) { 61b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou candidate_list[i].initConstantContent(m_Backend, m_KeptSections); 62b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 63b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 64b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // 3. Find identical code until convergence 65b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou bool converged = false; 66b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t iterations = 0; 67b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou while (!converged && (iterations < m_Config.options().getICFIterations())) { 68b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou converged = matchCandidates(candidate_list); 69b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou ++iterations; 70b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 71b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (m_Config.options().printICFSections()) { 72b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou debug(diag::debug_icf_iterations) << iterations; 73b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 74b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 75b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // 4. Fold the identical code 76b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou typedef std::set<Input*> FoldedObjects; 77b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou FoldedObjects folded_objs; 78b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou KeptSections::iterator kept, keptEnd = m_KeptSections.end(); 79b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t index = 0; 80b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (kept = m_KeptSections.begin(); kept != keptEnd; ++kept, ++index) { 81b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* sect = (*kept).first; 82b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Input* obj = (*kept).second.first; 83b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t kept_index = (*kept).second.second; 84b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (index != kept_index) { 85b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou sect->setKind(LDFileFormat::Folded); 86b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou folded_objs.insert(obj); 87b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 88b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (m_Config.options().printICFSections()) { 89b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou KeptSections::iterator it = m_KeptSections.begin() + kept_index; 90b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* kept_sect = (*it).first; 91b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Input* kept_obj = (*it).second.first; 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines debug(diag::debug_icf_folded_section) << sect->name() << obj->name() 93b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou << kept_sect->name() 94b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou << kept_obj->name(); 95b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 96b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 97b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 98b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 99b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Adjust the fragment reference of the folded symbols. 100b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou FoldedObjects::iterator fobj, fobjEnd = folded_objs.end(); 101b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (fobj = folded_objs.begin(); fobj != fobjEnd; ++fobj) { 102b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDContext::sym_iterator sym, symEnd = (*fobj)->context()->symTabEnd(); 103b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (sym = (*fobj)->context()->symTabBegin(); sym != symEnd; ++sym) { 104b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if ((*sym)->hasFragRef() && ((*sym)->type() == ResolveInfo::Function)) { 105b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSymbol* out_sym = (*sym)->resolveInfo()->outSymbol(); 106b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou FragmentRef* frag_ref = out_sym->fragRef(); 107b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* sect = &(frag_ref->frag()->getParent()->getSection()); 108b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (sect->kind() == LDFileFormat::Folded) { 109b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t kept_index = m_KeptSections[sect].second; 11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSection* kept_sect = (*(m_KeptSections.begin() + kept_index)).first; 111b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou frag_ref->assign(kept_sect->getSectionData()->front(), 112b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou frag_ref->offset()); 113b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 114b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each symbol 11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each folded object 117b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 118b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 11937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IdenticalCodeFolding::findCandidates(FoldingCandidates& pCandidateList) { 120b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Module::obj_iterator obj, objEnd = m_Module.obj_end(); 121b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) { 122b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::set<const LDSection*> funcptr_access_set; 123b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou typedef std::map<LDSection*, LDSection*> CandidateMap; 124b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou CandidateMap candidate_map; 125b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd(); 126b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) { 127b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou switch ((*sect)->kind()) { 128b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou case LDFileFormat::TEXT: { 12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines candidate_map.insert( 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::make_pair(*sect, reinterpret_cast<LDSection*>(NULL))); 131b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 132b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 133b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou case LDFileFormat::Relocation: { 134b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* target = (*sect)->getLink(); 135b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (target->kind() == LDFileFormat::TEXT) { 136b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou candidate_map[target] = *sect; 137b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 138b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 139b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Safe icf 1402bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar if (m_Config.options().getICFMode() == GeneralOptions::ICF::Safe) { 141b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou RelocData::iterator rel, relEnd = (*sect)->getRelocData()->end(); 142b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (rel = (*sect)->getRelocData()->begin(); rel != relEnd; ++rel) { 143b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSymbol* sym = rel->symInfo()->outSymbol(); 144b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (sym->hasFragRef() && (sym->type() == ResolveInfo::Function)) { 145b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const LDSection* def = 146b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou &sym->fragRef()->frag()->getParent()->getSection(); 147b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (!isSymCtorOrDtor(*rel->symInfo()) && 148b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou m_Backend.mayHaveUnsafeFunctionPointerAccess(*target) && 14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Backend.getRelocator() 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ->mayHaveFunctionPointerAccess(*rel)) { 151b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou funcptr_access_set.insert(def); 152b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 153b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each reloc 155b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 156b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 157b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 158b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 159b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou default: { 160b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // skip 16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 162b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 16337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 16437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each section 165b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 166b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou CandidateMap::iterator candidate, candidateEnd = candidate_map.end(); 167b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (candidate = candidate_map.begin(); candidate != candidateEnd; 168b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou ++candidate) { 1692bf3f881f79c4d883f379e63725e788c310739a3Pirama Arumuga Nainar if ((m_Config.options().getICFMode() == GeneralOptions::ICF::All) || 170b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (funcptr_access_set.count(candidate->first) == 0)) { 171b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t index = m_KeptSections.size(); 172b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou m_KeptSections[candidate->first] = ObjectAndId(*obj, index); 17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines pCandidateList.push_back( 17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines FoldingCandidate(candidate->first, candidate->second, *obj)); 175b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each possible candidate 17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for each obj 178b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 179b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 18037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool IdenticalCodeFolding::matchCandidates(FoldingCandidates& pCandidateList) { 181b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou typedef std::multimap<uint32_t, size_t> ChecksumMap; 182b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou ChecksumMap checksum_map; 183b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::vector<std::string> contents(pCandidateList.size()); 184b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou bool converged = true; 185b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 186b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (size_t index = 0; index < pCandidateList.size(); ++index) { 18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines contents[index] = pCandidateList[index].getContentWithVariables( 18837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Backend, m_KeptSections); 189b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou uint32_t checksum = ::crc32(0xFFFFFFFF, 190b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (const uint8_t*)contents[index].c_str(), 191b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou contents[index].length()); 192b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 193b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t count = checksum_map.count(checksum); 194b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (count == 0) { 195b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou checksum_map.insert(std::make_pair(checksum, index)); 196b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } else { 197b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::pair<ChecksumMap::iterator, ChecksumMap::iterator> ret = 198b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou checksum_map.equal_range(checksum); 199b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (ChecksumMap::iterator it = ret.first; it != ret.second; ++it) { 200b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t kept_index = (*it).second; 201b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (contents[index].compare(contents[kept_index]) == 0) { 202b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou m_KeptSections[pCandidateList[index].sect].second = kept_index; 203b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou converged = false; 204b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 205b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 206b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 207b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 208b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 209b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 210b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou return converged; 211b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 212b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 213b3323086ee04f9db9e85f7cae46510f91a137237Pete Chouvoid IdenticalCodeFolding::FoldingCandidate::initConstantContent( 214b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const TargetLDBackend& pBackend, 21537b74a387bb3993387029859c2d9d051c41c724eStephen Hines const IdenticalCodeFolding::KeptSections& pKeptSections) { 216b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Get the static content from text. 217b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou assert(sect != NULL && sect->hasSectionData()); 218b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou SectionData::const_iterator frag, fragEnd = sect->getSectionData()->end(); 219b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (frag = sect->getSectionData()->begin(); frag != fragEnd; ++frag) { 220b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou switch (frag->getKind()) { 221b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou case Fragment::Region: { 222b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const RegionFragment& region = llvm::cast<RegionFragment>(*frag); 223b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou content.append(region.getRegion().begin(), region.size()); 224b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 225b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 226b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou default: { 227b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // FIXME: Currently we only take care of RegionFragment. 228b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 229b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 230b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 231b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 232b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 233b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Get the static content from relocs. 234b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (reloc_sect != NULL && reloc_sect->hasRelocData()) { 235b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou RelocData::iterator rel, relEnd = reloc_sect->getRelocData()->end(); 236b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (rel = reloc_sect->getRelocData()->begin(); rel != relEnd; ++rel) { 237a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines llvm::format_object<Relocation::Type, 238a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines Relocation::Address, 239a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines Relocation::Address, 240a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines Relocation::Address> rel_info("%x%llx%llx%llx", 241a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines rel->type(), 242a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines rel->symValue(), 243a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines rel->addend(), 244a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines rel->place()); 245b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou char rel_str[48]; 246b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou rel_info.print(rel_str, sizeof(rel_str)); 247b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou content.append(rel_str); 248b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 249b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Handle the recursive call. 250b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSymbol* sym = rel->symInfo()->outSymbol(); 251b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if ((sym->type() == ResolveInfo::Function) && sym->hasFragRef()) { 252b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* def = &sym->fragRef()->frag()->getParent()->getSection(); 253b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (def == sect) { 254b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou continue; 255b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 256b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 257b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 25837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!pBackend.isSymbolPreemptible(*rel->symInfo()) && sym->hasFragRef() && 259b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (pKeptSections.find( 26037b74a387bb3993387029859c2d9d051c41c724eStephen Hines &sym->fragRef()->frag()->getParent()->getSection()) != 26137b74a387bb3993387029859c2d9d051c41c724eStephen Hines pKeptSections.end())) { 262b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Mark this reloc as a variable. 263b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou variable_relocs.push_back(rel); 264b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } else { 265b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // TODO: Support inlining merge sections if possible (target-dependent). 266b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if ((sym->binding() == ResolveInfo::Local) || 267b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (sym->binding() == ResolveInfo::Absolute)) { 268b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // ABS or Local symbols. 26937b74a387bb3993387029859c2d9d051c41c724eStephen Hines content.append(sym->name()).append(obj->name()).append( 27037b74a387bb3993387029859c2d9d051c41c724eStephen Hines obj->path().native()); 271b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } else { 272b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou content.append(sym->name()); 273b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 274b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 275b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 276b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 277b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 278b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 279b3323086ee04f9db9e85f7cae46510f91a137237Pete Choustd::string IdenticalCodeFolding::FoldingCandidate::getContentWithVariables( 280b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const TargetLDBackend& pBackend, 28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines const IdenticalCodeFolding::KeptSections& pKeptSections) { 282b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::string result(content); 283b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Compute the variable content from relocs. 284b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::vector<Relocation*>::const_iterator rel, relEnd = variable_relocs.end(); 285b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (rel = variable_relocs.begin(); rel != relEnd; ++rel) { 286b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSymbol* sym = (*rel)->symInfo()->outSymbol(); 287b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* def = &sym->fragRef()->frag()->getParent()->getSection(); 288b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Use the kept section index. 289b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou KeptSections::const_iterator it = pKeptSections.find(def); 290a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines llvm::format_object<size_t> kept_info("%x", (*it).second.second); 291b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou char kept_str[8]; 292b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou kept_info.print(kept_str, sizeof(kept_str)); 293b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou result.append(kept_str); 294b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 295b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 296b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou return result; 297b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 29837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 29937b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 300