summaryrefslogtreecommitdiffstats
path: root/include/bcc/Compiler.h
blob: 630be08fbfa24b5ddba06c0d8f29add719a65d3c (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
154
155
/*
 * Copyright 2010-2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef BCC_COMPILER_H
#define BCC_COMPILER_H

namespace llvm {

class raw_ostream;
class DataLayout;
class TargetMachine;

namespace legacy {
class PassManager;
} // end namespace legacy

using legacy::PassManager;

} // end namespace llvm

namespace bcc {

class CompilerConfig;
class OutputFile;
class Script;

//===----------------------------------------------------------------------===//
// Design of Compiler
//===----------------------------------------------------------------------===//
// 1. A compiler instance can be constructed provided an "initial config."
// 2. A compiler can later be re-configured using config().
// 3. Once config() is invoked, it'll re-create TargetMachine instance (i.e.,
//    mTarget) according to the configuration supplied. TargetMachine instance
//    is *shared* across the different calls to compile() before the next call
//    to config().
// 4. Once a compiler instance is created, you can use the compile() service
//    to compile the file over and over again. Each call uses TargetMachine
//    instance to construct the compilation passes.
class Compiler {
public:
  enum ErrorCode {
    kSuccess,

    kInvalidConfigNoTarget,
    kErrCreateTargetMachine,
    kErrSwitchTargetMachine,
    kErrNoTargetMachine,
    kErrDataLayoutNoMemory,
    kErrMaterialization,
    kErrInvalidOutputFileState,
    kErrPrepareOutput,
    kPrepareCodeGenPass,

    kErrHookBeforeAddLTOPasses,
    kErrHookAfterAddLTOPasses,
    kErrHookAfterExecuteLTOPasses,

    kErrHookBeforeAddCodeGenPasses,
    kErrHookAfterAddCodeGenPasses,
    kErrHookBeforeExecuteCodeGenPasses,
    kErrHookAfterExecuteCodeGenPasses,

    kErrInvalidSource
  };

  static const char *GetErrorString(enum ErrorCode pErrCode);

private:
  llvm::TargetMachine *mTarget;
  // LTO is enabled by default.
  bool mEnableLTO;

  enum ErrorCode runLTO(Script &pScript);
  enum ErrorCode runCodeGen(Script &pScript, llvm::raw_ostream &pResult);

public:
  Compiler();
  Compiler(const CompilerConfig &pConfig);

  enum ErrorCode config(const CompilerConfig &pConfig);

  // Compile a script and output the result to a LLVM stream.
  //
  // @param IRStream If not NULL, the LLVM-IR that is fed to code generation
  //                 will be written to IRStream.
  enum ErrorCode compile(Script &pScript, llvm::raw_ostream &pResult,
                         llvm::raw_ostream *IRStream);

  // Compile a script and output the result to a file.
  enum ErrorCode compile(Script &pScript, OutputFile &pResult,
                         llvm::raw_ostream *IRStream = 0);

  const llvm::TargetMachine& getTargetMachine() const
  { return *mTarget; }

  void enableLTO(bool pEnable = true)
  { mEnableLTO = pEnable; }

  virtual ~Compiler();

protected:
  //===--------------------------------------------------------------------===//
  // Plugin callbacks for sub-class.
  //===--------------------------------------------------------------------===//
  // Called before adding first pass to code-generation passes.
  virtual bool beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM)
  { return true; }

  // Called after adding last pass to code-generation passes.
  virtual bool afterAddLTOPasses(Script &pScript, llvm::PassManager &pPM)
  { return true; }

  // Called before executing code-generation passes.
  virtual bool beforeExecuteLTOPasses(Script &pScript,
                                          llvm::PassManager &pPM)
  { return true; }

  // Called after executing code-generation passes.
  virtual bool afterExecuteLTOPasses(Script &pScript)
  { return true; }

  // Called before adding first pass to code-generation passes.
  virtual bool beforeAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM)
  { return true; }

  // Called after adding last pass to code-generation passes.
  virtual bool afterAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM)
  { return true; }

  // Called before executing code-generation passes.
  virtual bool beforeExecuteCodeGenPasses(Script &pScript,
                                          llvm::PassManager &pPM)
  { return true; }

  // Called after executing code-generation passes.
  virtual bool afterExecuteCodeGenPasses(Script &pScript)
  { return true; }
};

} // end namespace bcc

#endif // BCC_COMPILER_H