summaryrefslogtreecommitdiff
path: root/include/llvm/LinkTimeOptimizer.h
blob: 164232d20989b0559e5482a9f8a9178bdd527e1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//===-- llvm/LinkTimeOptimizer.h - Public Interface  ------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Devang Patel and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This header provides public interface to use LLVM link time optimization
// library. This is intended to be used by linker to do link time optimization.
//
//===----------------------------------------------------------------------===//

#ifndef __LTO_H__
#define __LTO_H__

#include <string>
#include <vector>
#include <set>
#include <llvm/ADT/hash_map>

namespace llvm {

  class Module;
  class GlobalValue;
  class TargetMachine;

  enum LTOStatus {
    LTO_UNKNOWN,
    LTO_OPT_SUCCESS,
    LTO_READ_SUCCESS,
    LTO_READ_FAILURE,
    LTO_WRITE_FAILURE,
    LTO_NO_TARGET,
    LTO_NO_WORK,
    LTO_MODULE_MERGE_FAILURE,
    LTO_ASM_FAILURE
  };
 
  enum LTOLinkageTypes {
    LTOExternalLinkage, // Externally visible function
    LTOLinkOnceLinkage, // Keep one copy of named function when linking (inline)
    LTOWeakLinkage,     // Keep one copy of named function when linking (weak)
    LTOInternalLinkage  // Rename collisions when linking (static functions)
  };

  /// This class represents LLVM symbol information without exposing details
  /// of LLVM global values. It encapsulates symbol linkage information. This
  /// is typically used in hash_map where associated name identifies the 
  /// the symbol name.
  class LLVMSymbol {

  public:

    LTOLinkageTypes getLinkage() const { return linkage; }
    void mayBeNotUsed();

    LLVMSymbol (enum LTOLinkageTypes lt, GlobalValue *g, const std::string &n, 
                const std::string &m, int a) : linkage(lt), gv(g), name(n), 
                                               mangledName(m), alignment(a) {}

    const char *getName() { return name.c_str(); }
    const char *getMangledName() { return mangledName.c_str(); }
    int getAlignment() { return alignment; }

  private:
    enum LTOLinkageTypes linkage;
    GlobalValue *gv;
    std::string name;
    std::string mangledName;
    int alignment;
  };

  class string_compare {
  public:
    bool operator()(const char* left, const char* right) const { 
      return (strcmp(left, right) == 0); 
    }
  };

  /// This is abstract class to facilitate dlopen() interface.
  /// See LTO below for more info.
  class LinkTimeOptimizer {
  public:
    typedef hash_map<const char*, LLVMSymbol*, hash<const char*>, 
                     string_compare> NameToSymbolMap;
    typedef hash_map<const char*, Module*, hash<const char*>, 
                     string_compare> NameToModuleMap;
    virtual enum LTOStatus readLLVMObjectFile(const std::string &,
                                              NameToSymbolMap &,
                                              std::set<std::string> &) = 0;
    virtual enum LTOStatus optimizeModules(const std::string &,
                                           std::vector<const char*> &,
                                           std::string &, bool, 
                                           const char *) = 0;
    virtual void getTargetTriple(const std::string &, std::string &) = 0;
    virtual void removeModule (const std::string &InputFilename) = 0;
    virtual void printVersion () = 0;
    virtual ~LinkTimeOptimizer() = 0;
  };

  /// This is the main link time optimization class. It exposes simple API
  /// to perform link time optimization using LLVM intermodular optimizer.
  class LTO : public LinkTimeOptimizer {

  public:
    typedef hash_map<const char*, LLVMSymbol*, hash<const char*>, 
                     string_compare> NameToSymbolMap;
    typedef hash_map<const char*, Module*, hash<const char*>, 
                     string_compare> NameToModuleMap;

    enum LTOStatus readLLVMObjectFile(const std::string &InputFilename,
                                      NameToSymbolMap &symbols,
                                      std::set<std::string> &references);
    enum LTOStatus optimizeModules(const std::string &OutputFilename,
                                   std::vector<const char*> &exportList,
                                   std::string &targetTriple, bool saveTemps,
                                   const char *);
    void getTargetTriple(const std::string &InputFilename, 
                         std::string &targetTriple);
    void removeModule (const std::string &InputFilename);
    void printVersion();

    // Constructors and destructors
    LTO() { 
      /// TODO: Use Target info, it is available at this time.
      Target = NULL; 
    }
    ~LTO();

  private:
    Module *getModule (const std::string &InputFilename);
    enum LTOStatus optimize(Module *, std::ostream &, 
                            std::vector<const char *> &);
    void getTarget(Module *);

  private:
    std::vector<Module *> modules;
    NameToSymbolMap allSymbols;
    NameToModuleMap allModules;
    TargetMachine *Target;
  };

} // End llvm namespace

/// This provides C interface to initialize link time optimizer. This allows
/// linker to use dlopen() interface to dynamically load LinkTimeOptimizer.
/// extern "C" helps, because dlopen() interface uses name to find the symbol.
extern "C"
llvm::LinkTimeOptimizer *createLLVMOptimizer();

#endif