10fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang/*
20fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * Copyright 2012, The Android Open Source Project
30fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang *
40fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
50fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * you may not use this file except in compliance with the License.
60fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * You may obtain a copy of the License at
70fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang *
80fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
90fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang *
100fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * Unless required by applicable law or agreed to in writing, software
110fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
120fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * See the License for the specific language governing permissions and
140fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * limitations under the License.
150fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang */
160fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
17c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#ifndef BCC_RS_COMPILER_DRIVER_H
18c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#define BCC_RS_COMPILER_DRIVER_H
190fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
20b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes#include "bcc/Compiler.h"
210a2acce3493df1609be2730e3058fe27af01b88fJean-Luc Brouillet#include "bcc/Script.h"
220fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
23a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni#include "bcinfo/MetadataExtractor.h"
24a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
250ab50b835805c75ad164466767c2c212f48954ccYang Ni#include <list>
26552537979f312f62488eee9e45b2f78678eafbeaPirama Arumuga Nainar#include <string>
27a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni#include <vector>
28a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
290fffa7e4adc90079dc0f252359050fe872b360ddZonr Changnamespace bcc {
300fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
317bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liaoclass BCCContext;
320fffa7e4adc90079dc0f252359050fe872b360ddZonr Changclass CompilerConfig;
33c3437f05c638f8befda59170ae788873db24dc1cStephen Hinesclass RSCompilerDriver;
34a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Niclass Source;
350fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
36c3437f05c638f8befda59170ae788873db24dc1cStephen Hines// Type signature for dynamically loaded initialization of an RSCompilerDriver.
37c3437f05c638f8befda59170ae788873db24dc1cStephen Hinestypedef void (*RSCompilerDriverInit_t) (bcc::RSCompilerDriver *);
38c3437f05c638f8befda59170ae788873db24dc1cStephen Hines// Name of the function that we attempt to dynamically load/execute.
39c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#define RS_COMPILER_DRIVER_INIT_FN rsCompilerDriverInit
40c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
410fffa7e4adc90079dc0f252359050fe872b360ddZonr Changclass RSCompilerDriver {
420fffa7e4adc90079dc0f252359050fe872b360ddZonr Changprivate:
430fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  CompilerConfig *mConfig;
44b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes  Compiler mCompiler;
450fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
461d4a9e4646e8786623daa6ac3917782be56a8fb2Stephen Hines  // Are we compiling under an RS debug context with additional checks?
471d4a9e4646e8786623daa6ac3917782be56a8fb2Stephen Hines  bool mDebugContext;
481d4a9e4646e8786623daa6ac3917782be56a8fb2Stephen Hines
49c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  // Callback before linking with the runtime library.
50c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  RSLinkRuntimeCallback mLinkRuntimeCallback;
51c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
52c06cd06078a8c866d5cecbf897326092b55a8955Stephen Hines  // Do we merge global variables on ARM using LLVM's optimization pass?
53ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  // Disabling LLVM's global merge pass allows static globals to be correctly
54ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  // emitted to ELF. This can result in decreased performance due to increased
55ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  // register pressure, but it does make the resulting code easier to debug
56ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  // and work with.
57ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  bool mEnableGlobalMerge;
58ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines
59750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // Specifies whether we should embed global variable information in the
60750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // code via special RS variables that can be examined later by the driver.
61750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  bool mEmbedGlobalInfo;
62750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
63750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // Specifies whether we should skip constant (immutable) global variables
64750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // when potentially embedding information about globals.
65750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  bool mEmbedGlobalInfoSkipConstant;
66750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
670fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // Setup the compiler config for the given script. Return true if mConfig has
680fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // been changed and false if it remains unchanged.
690a2acce3493df1609be2730e3058fe27af01b88fJean-Luc Brouillet  bool setupConfig(const Script &pScript);
700fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
71f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // Compiles the provided bitcode, placing the binary at pOutputPath.
72f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // - If pDumpIR is true, a ".ll" file will also be created.
730a2acce3493df1609be2730e3058fe27af01b88fJean-Luc Brouillet  Compiler::ErrorCode compileScript(Script& pScript, const char* pScriptName,
7451ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                                    const char* pOutputPath,
75a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar                                    const char* pRuntimePath,
7651ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                                    const char* pBuildChecksum,
77a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar                                    bool pDumpIR);
780fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
790fffa7e4adc90079dc0f252359050fe872b360ddZonr Changpublic:
80efe14344d7fbe0456358285aa043cb9f9d3dd2a1David Gross  RSCompilerDriver();
810fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  ~RSCompilerDriver();
820fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
83b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes  Compiler *getCompiler() {
84331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return &mCompiler;
85331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
86331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
87331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  void setConfig(CompilerConfig *config) {
88331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    mConfig = config;
89331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
90331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
911d4a9e4646e8786623daa6ac3917782be56a8fb2Stephen Hines  void setDebugContext(bool v) {
921d4a9e4646e8786623daa6ac3917782be56a8fb2Stephen Hines    mDebugContext = v;
931d4a9e4646e8786623daa6ac3917782be56a8fb2Stephen Hines  }
941d4a9e4646e8786623daa6ac3917782be56a8fb2Stephen Hines
95c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  void setLinkRuntimeCallback(RSLinkRuntimeCallback c) {
96c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    mLinkRuntimeCallback = c;
97c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  }
98c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
99c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  RSLinkRuntimeCallback getLinkRuntimeCallback() const {
100c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    return mLinkRuntimeCallback;
101c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  }
102c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
103c06cd06078a8c866d5cecbf897326092b55a8955Stephen Hines  // This function enables/disables merging of global static variables.
104c06cd06078a8c866d5cecbf897326092b55a8955Stephen Hines  // Note that it only takes effect on ARM architectures (other architectures
105c06cd06078a8c866d5cecbf897326092b55a8955Stephen Hines  // do not offer this option).
106ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  void setEnableGlobalMerge(bool v) {
107ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines    mEnableGlobalMerge = v;
108ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  }
109ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines
110ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  bool getEnableGlobalMerge() const {
111ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines    return mEnableGlobalMerge;
112ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines  }
113ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines
114656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty  const CompilerConfig * getConfig() const {
115656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty    return mConfig;
116656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty  }
117656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty
118750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // Set to true if we should embed global variable information in the code.
119750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  void setEmbedGlobalInfo(bool v) {
120750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines    mEmbedGlobalInfo = v;
121750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  }
122750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
123750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // Returns true if we should embed global variable information in the code.
124750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  bool getEmbedGlobalInfo() const {
125750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines    return mEmbedGlobalInfo;
126750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  }
127750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
128750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // Set to true if we should skip constant (immutable) global variables when
129750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // potentially embedding information about globals.
130750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  void setEmbedGlobalInfoSkipConstant(bool v) {
131750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines    mEmbedGlobalInfoSkipConstant = v;
132750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  }
133750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
134750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // Returns true if we should skip constant (immutable) global variables when
135750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  // potentially embedding information about globals.
136750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  bool getEmbedGlobalInfoSkipConstant() const {
137750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines    return mEmbedGlobalInfoSkipConstant;
138750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  }
139750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
14047f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  // FIXME: This method accompany with loadScript and compileScript should
1410fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //        all be const-methods. They're not now because the getAddress() in
1420fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //        SymbolResolverInterface is not a const-method.
14347f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  // Returns true if script is successfully compiled.
144f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  bool build(BCCContext& pContext, const char* pCacheDir, const char* pResName,
145a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar             const char* pBitcode, size_t pBitcodeSize,
14651ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar             const char *pBuildChecksum, const char* pRuntimePath,
147900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes             RSLinkRuntimeCallback pLinkRuntimeCallback = nullptr,
1487b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser             bool pDumpIR = false);
14947f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines
150a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  bool buildScriptGroup(
151a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      BCCContext& Context, const char* pOutputFilepath, const char* pRuntimePath,
152186d2f34573eb20de197d8eb8e08bcadd031a9bdYang Ni      const char* pRuntimeRelaxedPath, bool dumpIR, const char* buildChecksum,
1536da4e253a513feef3405759fef6d0760828808caYang Ni      const std::vector<Source*>& sources,
1540ab50b835805c75ad164466767c2c212f48954ccYang Ni      const std::list<std::list<std::pair<int, int>>>& toFuse,
1550ab50b835805c75ad164466767c2c212f48954ccYang Ni      const std::list<std::string>& fused,
1560ab50b835805c75ad164466767c2c212f48954ccYang Ni      const std::list<std::list<std::pair<int, int>>>& invokes,
1570ab50b835805c75ad164466767c2c212f48954ccYang Ni      const std::list<std::string>& invokeBatchNames);
158a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
15947f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  // Returns true if script is successfully compiled.
1600a2acce3493df1609be2730e3058fe27af01b88fJean-Luc Brouillet  bool buildForCompatLib(Script &pScript, const char *pOut,
16151ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                         const char *pBuildChecksum, const char *pRuntimePath,
16251ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                         bool pDumpIR);
1630fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang};
1640fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
1650fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang} // end namespace bcc
1660fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
167c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#endif // BCC_RS_COMPILER_DRIVER_H
168