IdenticalCodeFolding.cpp revision b3323086ee04f9db9e85f7cae46510f91a137237
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//===----------------------------------------------------------------------===//
9b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
10b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Fragment/RegionFragment.h>
11b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/IdenticalCodeFolding.h>
12b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/LDContext.h>
13b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/LDSection.h>
14b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/RelocData.h>
15b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/Relocator.h>
16b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/ResolveInfo.h>
17b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/SectionData.h>
18b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LinkerConfig.h>
19b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/MC/Input.h>
20b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/GeneralOptions.h>
21b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Module.h>
22b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Support/Demangle.h>
23b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Support/MsgHandling.h>
24b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#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 Chouusing namespace mcld;
36b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
37b3323086ee04f9db9e85f7cae46510f91a137237Pete Choustatic bool isSymCtorOrDtor(const ResolveInfo& pSym)
38b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{
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)
51b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    : m_Config(pConfig), m_Backend(pBackend), m_Module(pModule)
52b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{
53b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou}
54b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
55b3323086ee04f9db9e85f7cae46510f91a137237Pete Chouvoid IdenticalCodeFolding::foldIdenticalCode()
56b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{
57b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  // 1. Find folding candidates.
58b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  FoldingCandidates candidate_list;
59b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  findCandidates(candidate_list);
60b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
61b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  // 2. Initialize constant section content
62b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  for (size_t i = 0; i < candidate_list.size(); ++i) {
63b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    candidate_list[i].initConstantContent(m_Backend, m_KeptSections);
64b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  }
65b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
66b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  // 3. Find identical code until convergence
67b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  bool converged = false;
68b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  size_t iterations = 0;
69b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  while (!converged && (iterations < m_Config.options().getICFIterations())) {
70b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    converged = matchCandidates(candidate_list);
71b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    ++iterations;
72b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  }
73b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  if (m_Config.options().printICFSections()) {
74b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    debug(diag::debug_icf_iterations) << iterations;
75b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  }
76b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
77b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  // 4. Fold the identical code
78b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  typedef std::set<Input*> FoldedObjects;
79b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  FoldedObjects folded_objs;
80b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  KeptSections::iterator kept, keptEnd = m_KeptSections.end();
81b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  size_t index = 0;
82b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  for (kept = m_KeptSections.begin(); kept != keptEnd; ++kept, ++index) {
83b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    LDSection* sect = (*kept).first;
84b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    Input* obj = (*kept).second.first;
85b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    size_t kept_index = (*kept).second.second;
86b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    if (index != kept_index) {
87b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      sect->setKind(LDFileFormat::Folded);
88b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      folded_objs.insert(obj);
89b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
90b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      if (m_Config.options().printICFSections()) {
91b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        KeptSections::iterator it = m_KeptSections.begin() + kept_index;
92b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        LDSection* kept_sect = (*it).first;
93b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        Input* kept_obj = (*it).second.first;
94b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        debug(diag::debug_icf_folded_section) << sect->name()
95b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                                              << obj->name()
96b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                                              << kept_sect->name()
97b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                                              << kept_obj->name();
98b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      }
99b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    }
100b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  }
101b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
102b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  // Adjust the fragment reference of the folded symbols.
103b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  FoldedObjects::iterator fobj, fobjEnd = folded_objs.end();
104b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  for (fobj = folded_objs.begin(); fobj != fobjEnd; ++fobj) {
105b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    LDContext::sym_iterator sym, symEnd = (*fobj)->context()->symTabEnd();
106b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    for (sym = (*fobj)->context()->symTabBegin(); sym != symEnd; ++sym) {
107b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      if ((*sym)->hasFragRef() && ((*sym)->type() == ResolveInfo::Function)) {
108b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        LDSymbol* out_sym = (*sym)->resolveInfo()->outSymbol();
109b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        FragmentRef* frag_ref = out_sym->fragRef();
110b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        LDSection* sect = &(frag_ref->frag()->getParent()->getSection());
111b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        if (sect->kind() == LDFileFormat::Folded) {
112b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          size_t kept_index = m_KeptSections[sect].second;
113b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          LDSection* kept_sect =
114b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou              (*(m_KeptSections.begin() + kept_index)).first;
115b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          frag_ref->assign(kept_sect->getSectionData()->front(),
116b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                           frag_ref->offset());
117b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        }
118b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      }
119b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    } // for each symbol
120b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  } // for each folded object
121b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou}
122b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
123b3323086ee04f9db9e85f7cae46510f91a137237Pete Chouvoid IdenticalCodeFolding::findCandidates(FoldingCandidates& pCandidateList)
124b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{
125b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  Module::obj_iterator obj, objEnd = m_Module.obj_end();
126b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) {
127b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    std::set<const LDSection*> funcptr_access_set;
128b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    typedef std::map<LDSection*, LDSection*> CandidateMap;
129b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    CandidateMap candidate_map;
130b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
131b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
132b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      switch ((*sect)->kind()) {
133b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        case LDFileFormat::TEXT: {
134b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          candidate_map.insert(std::make_pair(*sect, (LDSection*)NULL));
135b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          break;
136b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        }
137b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        case LDFileFormat::Relocation: {
138b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          LDSection* target = (*sect)->getLink();
139b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          if (target->kind() == LDFileFormat::TEXT) {
140b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou            candidate_map[target] = *sect;
141b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          }
142b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
143b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          // Safe icf
144b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          if (m_Config.options().getICFMode() == GeneralOptions::ICF_Safe) {
145b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou            RelocData::iterator rel, relEnd = (*sect)->getRelocData()->end();
146b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou            for (rel = (*sect)->getRelocData()->begin(); rel != relEnd; ++rel) {
147b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou              LDSymbol* sym = rel->symInfo()->outSymbol();
148b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou              if (sym->hasFragRef() && (sym->type() == ResolveInfo::Function)) {
149b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                const LDSection* def =
150b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                    &sym->fragRef()->frag()->getParent()->getSection();
151b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                if (!isSymCtorOrDtor(*rel->symInfo()) &&
152b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                    m_Backend.mayHaveUnsafeFunctionPointerAccess(*target) &&
153b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                    m_Backend.
154b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                         getRelocator()->mayHaveFunctionPointerAccess(*rel)) {
155b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                  funcptr_access_set.insert(def);
156b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                }
157b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou              }
158b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou            } // for each reloc
159b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          }
160b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
161b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          break;
162b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        }
163b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        default: {
164b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          // skip
165b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          break;;
166b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        }
167b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      } // end of switch
168b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    } // for each section
169b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
170b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    CandidateMap::iterator candidate, candidateEnd = candidate_map.end();
171b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    for (candidate = candidate_map.begin(); candidate != candidateEnd;
172b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou         ++candidate) {
173b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      if ((m_Config.options().getICFMode() == GeneralOptions::ICF_All) ||
174b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          (funcptr_access_set.count(candidate->first) == 0)) {
175b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        size_t index = m_KeptSections.size();
176b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        m_KeptSections[candidate->first] = ObjectAndId(*obj, index);
177b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        pCandidateList.push_back(FoldingCandidate(candidate->first,
178b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                                                  candidate->second,
179b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                                                  *obj));
180b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      }
181b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    } // for each possible candidate
182b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
183b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  } // for each obj
184b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou}
185b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
186b3323086ee04f9db9e85f7cae46510f91a137237Pete Choubool IdenticalCodeFolding::matchCandidates(FoldingCandidates& pCandidateList)
187b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{
188b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  typedef std::multimap<uint32_t, size_t> ChecksumMap;
189b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  ChecksumMap checksum_map;
190b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  std::vector<std::string> contents(pCandidateList.size());
191b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  bool converged = true;
192b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
193b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  for (size_t index = 0; index < pCandidateList.size(); ++index) {
194b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    contents[index] = pCandidateList[index].
195b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                          getContentWithVariables(m_Backend, m_KeptSections);
196b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    uint32_t checksum = ::crc32(0xFFFFFFFF,
197b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                                (const uint8_t*)contents[index].c_str(),
198b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                                contents[index].length());
199b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
200b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    size_t count = checksum_map.count(checksum);
201b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    if (count == 0) {
202b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      checksum_map.insert(std::make_pair(checksum, index));
203b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    } else {
204b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      std::pair<ChecksumMap::iterator, ChecksumMap::iterator> ret =
205b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          checksum_map.equal_range(checksum);
206b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      for (ChecksumMap::iterator it = ret.first; it != ret.second; ++it) {
207b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        size_t kept_index = (*it).second;
208b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        if (contents[index].compare(contents[kept_index]) == 0) {
209b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          m_KeptSections[pCandidateList[index].sect].second = kept_index;
210b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          converged = false;
211b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          break;
212b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        }
213b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      }
214b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    }
215b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  }
216b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
217b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  return converged;
218b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou}
219b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
220b3323086ee04f9db9e85f7cae46510f91a137237Pete Chouvoid IdenticalCodeFolding::FoldingCandidate::initConstantContent(
221b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    const TargetLDBackend& pBackend,
222b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    const IdenticalCodeFolding::KeptSections& pKeptSections)
223b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{
224b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  // Get the static content from text.
225b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  assert(sect != NULL && sect->hasSectionData());
226b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  SectionData::const_iterator frag, fragEnd = sect->getSectionData()->end();
227b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  for (frag = sect->getSectionData()->begin(); frag != fragEnd; ++frag) {
228b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    switch (frag->getKind()) {
229b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      case Fragment::Region: {
230b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        const RegionFragment& region = llvm::cast<RegionFragment>(*frag);
231b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        content.append(region.getRegion().begin(), region.size());
232b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        break;
233b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      }
234b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      default: {
235b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        // FIXME: Currently we only take care of RegionFragment.
236b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        break;
237b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      }
238b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    }
239b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  }
240b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
241b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  // Get the static content from relocs.
242b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  if (reloc_sect != NULL && reloc_sect->hasRelocData()) {
243b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    RelocData::iterator rel, relEnd = reloc_sect->getRelocData()->end();
244b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    for (rel = reloc_sect->getRelocData()->begin(); rel != relEnd; ++rel) {
245b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      llvm::format_object4<Relocation::Type, Relocation::Address,
246b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                           Relocation::Address, Relocation::Address>
247b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          rel_info("%x%llx%llx%llx", rel->type(), rel->symValue(),
248b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                   rel->addend(), rel->place());
249b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      char rel_str[48];
250b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      rel_info.print(rel_str, sizeof(rel_str));
251b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      content.append(rel_str);
252b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
253b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      // Handle the recursive call.
254b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      LDSymbol* sym = rel->symInfo()->outSymbol();
255b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      if ((sym->type() == ResolveInfo::Function) && sym->hasFragRef()) {
256b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        LDSection* def = &sym->fragRef()->frag()->getParent()->getSection();
257b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        if (def == sect) {
258b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          continue;
259b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        }
260b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      }
261b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
262b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      if (!pBackend.isSymbolPreemptible(*rel->symInfo()) &&
263b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          sym->hasFragRef() &&
264b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          (pKeptSections.find(
265b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou              &sym->fragRef()->frag()->getParent()->getSection()) !=
266b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou              pKeptSections.end())) {
267b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        // Mark this reloc as a variable.
268b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        variable_relocs.push_back(rel);
269b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      } else {
270b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        // TODO: Support inlining merge sections if possible (target-dependent).
271b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        if ((sym->binding() == ResolveInfo::Local) ||
272b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou            (sym->binding() == ResolveInfo::Absolute)) {
273b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          // ABS or Local symbols.
274b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          content.append(sym->name())
275b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                 .append(obj->name())
276b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou                 .append(obj->path().native());
277b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        } else {
278b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou          content.append(sym->name());
279b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou        }
280b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou      }
281b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    }
282b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  }
283b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou}
284b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
285b3323086ee04f9db9e85f7cae46510f91a137237Pete Choustd::string IdenticalCodeFolding::FoldingCandidate::getContentWithVariables(
286b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    const TargetLDBackend& pBackend,
287b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    const IdenticalCodeFolding::KeptSections& pKeptSections)
288b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{
289b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  std::string result(content);
290b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  // Compute the variable content from relocs.
291b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  std::vector<Relocation*>::const_iterator rel, relEnd = variable_relocs.end();
292b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  for (rel = variable_relocs.begin(); rel != relEnd; ++rel) {
293b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    LDSymbol* sym = (*rel)->symInfo()->outSymbol();
294b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    LDSection* def = &sym->fragRef()->frag()->getParent()->getSection();
295b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    // Use the kept section index.
296b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    KeptSections::const_iterator it = pKeptSections.find(def);
297b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    llvm::format_object1<size_t> kept_info("%x", (*it).second.second);
298b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    char kept_str[8];
299b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    kept_info.print(kept_str, sizeof(kept_str));
300b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou    result.append(kept_str);
301b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  }
302b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou
303b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou  return result;
304b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou}
305