1 //===- IdenticalCodeFolding.h ---------------------------------------------===//
2 //
3 //                     The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef MCLD_LD_IDENTICALCODEFOLDING_H
10 #define MCLD_LD_IDENTICALCODEFOLDING_H
11 
12 #include <llvm/ADT/MapVector.h>
13 #include <string>
14 #include <vector>
15 
16 namespace mcld {
17 class Input;
18 class LDSection;
19 class LinkerConfig;
20 class Module;
21 class Relocation;
22 class TargetLDBackend;
23 
24 /** \class IdenticalCodeFolding
25  *  \brief Implementation of identical code folding for --icf=[none|all|safe]
26  *  @ref Safe ICF: Pointer Safe and Unwinding Aware Identical Code Folding in
27  *       Gold, http://research.google.com/pubs/pub36912.html
28  */
29 class IdenticalCodeFolding {
30 public:
31   typedef std::pair<Input*, size_t> ObjectAndId;
32   typedef llvm::MapVector<LDSection*, ObjectAndId> KeptSections;
33 
34 private:
35   class FoldingCandidate {
36   public:
FoldingCandidate()37     FoldingCandidate()
38         : sect(NULL), reloc_sect(NULL), obj(NULL)
39     { }
FoldingCandidate(LDSection * pCode,LDSection * pReloc,Input * pInput)40     FoldingCandidate(LDSection* pCode, LDSection* pReloc, Input* pInput)
41         : sect(pCode), reloc_sect(pReloc), obj(pInput)
42     { }
43 
44     void initConstantContent(const TargetLDBackend& pBackend,
45         const IdenticalCodeFolding::KeptSections& pKeptSections);
46     std::string getContentWithVariables(const TargetLDBackend& pBackend,
47         const IdenticalCodeFolding::KeptSections& pKeptSections);
48 
49     LDSection* sect;
50     LDSection* reloc_sect;
51     Input* obj;
52     std::string content;
53     std::vector<Relocation*> variable_relocs;
54   };
55 
56   typedef std::vector<FoldingCandidate> FoldingCandidates;
57 
58 public:
59   IdenticalCodeFolding(const LinkerConfig& pConfig,
60                        const TargetLDBackend& pBackend,
61                        Module& pModule);
62 
63   void foldIdenticalCode();
64 
65 private:
66   void findCandidates(FoldingCandidates& pCandidateList);
67 
68   bool matchCandidates(FoldingCandidates& pCandidateList);
69 
70 private:
71   const LinkerConfig& m_Config;
72   const TargetLDBackend& m_Backend;
73   Module& m_Module;
74   KeptSections m_KeptSections;
75 };
76 
77 } // namespace of mcld
78 
79 #endif
80