aboutsummaryrefslogtreecommitdiff
path: root/include/bcc/Compiler.h
blob: 708e1b0037cf9c6997613aec8beda2ea233bd78b (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
/*
 * 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 raw_pwrite_stream;
class DataLayout;
class TargetMachine;

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

} // end namespace llvm

namespace bcc {

class CompilerConfig;
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,
    kErrMaterialization,
    kErrInvalidOutputFileState,
    kErrPrepareOutput,
    kPrepareCodeGenPass,

    kErrCustomPasses,

    kErrInvalidSource,

    kIllegalGlobalFunction,

    kErrInvalidTargetMachine,

    kErrInvalidLayout
  };

  static const char *GetErrorString(enum ErrorCode pErrCode);

private:
  llvm::TargetMachine *mTarget;
  // Optimization is enabled by default.
  bool mEnableOpt;

  enum ErrorCode runPasses(Script &pScript, llvm::raw_pwrite_stream &pResult);

  bool addInternalizeSymbolsPass(Script &pScript, llvm::legacy::PassManager &pPM);
  void addExpandKernelPass(llvm::legacy::PassManager &pPM);
  void addDebugInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
  void addGlobalInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
  void addInvariantPass(llvm::legacy::PassManager &pPM);
  void addInvokeHelperPass(llvm::legacy::PassManager &pPM);

public:
  Compiler();
  explicit 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_pwrite_stream &pResult,
                         llvm::raw_ostream *IRStream);

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

  void enableOpt(bool pEnable = true)
  { mEnableOpt = pEnable; }

  ~Compiler();

  // Compare undefined external functions in pScript against a 'whitelist' of
  // all RenderScript functions.  Returns error if any external function that is
  // not in this whitelist is callable from the script.
  enum ErrorCode screenGlobalFunctions(Script &pScript);

  void translateGEPs(Script &pScript);
};

} // end namespace bcc

#endif // BCC_COMPILER_H