10dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//===- IdenticalCodeFolding.h ---------------------------------------------===//
20dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//
30dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//                     The MCLinker Project
40dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//
50dea6bc96bb52346737966839ac68644f7939f58Stephen Hines// This file is distributed under the University of Illinois Open Source
60dea6bc96bb52346737966839ac68644f7939f58Stephen Hines// License. See LICENSE.TXT for details.
70dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//
80dea6bc96bb52346737966839ac68644f7939f58Stephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_LD_IDENTICALCODEFOLDING_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_LD_IDENTICALCODEFOLDING_H_
110dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
120dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <llvm/ADT/MapVector.h>
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
140dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <string>
150dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <vector>
160dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
170dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesnamespace mcld {
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
190dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesclass Input;
200dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesclass LDSection;
210dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesclass LinkerConfig;
220dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesclass Module;
230dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesclass Relocation;
240dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesclass TargetLDBackend;
250dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
260dea6bc96bb52346737966839ac68644f7939f58Stephen Hines/** \class IdenticalCodeFolding
270dea6bc96bb52346737966839ac68644f7939f58Stephen Hines *  \brief Implementation of identical code folding for --icf=[none|all|safe]
280dea6bc96bb52346737966839ac68644f7939f58Stephen Hines *  @ref Safe ICF: Pointer Safe and Unwinding Aware Identical Code Folding in
290dea6bc96bb52346737966839ac68644f7939f58Stephen Hines *       Gold, http://research.google.com/pubs/pub36912.html
300dea6bc96bb52346737966839ac68644f7939f58Stephen Hines */
310dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesclass IdenticalCodeFolding {
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
330dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  typedef std::pair<Input*, size_t> ObjectAndId;
340dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  typedef llvm::MapVector<LDSection*, ObjectAndId> KeptSections;
350dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
370dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  class FoldingCandidate {
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines   public:
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    FoldingCandidate() : sect(NULL), reloc_sect(NULL), obj(NULL) {}
400dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    FoldingCandidate(LDSection* pCode, LDSection* pReloc, Input* pInput)
4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        : sect(pCode), reloc_sect(pReloc), obj(pInput) {}
420dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    void initConstantContent(
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        const TargetLDBackend& pBackend,
450dea6bc96bb52346737966839ac68644f7939f58Stephen Hines        const IdenticalCodeFolding::KeptSections& pKeptSections);
4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    std::string getContentWithVariables(
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        const TargetLDBackend& pBackend,
480dea6bc96bb52346737966839ac68644f7939f58Stephen Hines        const IdenticalCodeFolding::KeptSections& pKeptSections);
490dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
500dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    LDSection* sect;
510dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    LDSection* reloc_sect;
520dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    Input* obj;
530dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    std::string content;
540dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    std::vector<Relocation*> variable_relocs;
550dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  };
560dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
570dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  typedef std::vector<FoldingCandidate> FoldingCandidates;
580dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
600dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  IdenticalCodeFolding(const LinkerConfig& pConfig,
610dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                       const TargetLDBackend& pBackend,
620dea6bc96bb52346737966839ac68644f7939f58Stephen Hines                       Module& pModule);
630dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
640dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  void foldIdenticalCode();
650dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
670dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  void findCandidates(FoldingCandidates& pCandidateList);
680dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
690dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  bool matchCandidates(FoldingCandidates& pCandidateList);
700dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
720dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  const LinkerConfig& m_Config;
730dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  const TargetLDBackend& m_Backend;
740dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  Module& m_Module;
750dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  KeptSections m_KeptSections;
760dea6bc96bb52346737966839ac68644f7939f58Stephen Hines};
770dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
790dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_LD_IDENTICALCODEFOLDING_H_
81