1d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao/*
2d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * Copyright 2012, The Android Open Source Project
3d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao *
4d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * you may not use this file except in compliance with the License.
6d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * You may obtain a copy of the License at
7d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao *
8d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao *
10d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
11d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * See the License for the specific language governing permissions and
14d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao * limitations under the License.
15d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao */
16d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
170ab50b835805c75ad164466767c2c212f48954ccYang Ni#include <iostream>
180ab50b835805c75ad164466767c2c212f48954ccYang Ni#include <list>
190ab50b835805c75ad164466767c2c212f48954ccYang Ni#include <map>
200ab50b835805c75ad164466767c2c212f48954ccYang Ni#include <sstream>
21d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <string>
22d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <vector>
23d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
24c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#include <dlfcn.h>
25d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <stdlib.h>
26d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
27d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/ADT/STLExtras.h>
28d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/ADT/SmallString.h>
29d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Config/config.h>
30d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/CommandLine.h>
31d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/FileSystem.h>
32c46a3f5370364ad5698756d5da5b8845be9970d0Tim Murray#include <llvm/Support/ManagedStatic.h>
338be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines#include <llvm/Support/MemoryBuffer.h>
341e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar#include <llvm/Support/Path.h>
35c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#include <llvm/Support/PluginLoader.h>
36d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/raw_ostream.h>
37d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
38d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/BCCContext.h>
39d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Compiler.h>
40d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Config/Config.h>
418be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines#include <bcc/Renderscript/RSCompilerDriver.h>
42d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Script.h>
43d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Source.h>
44a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar#include <bcc/Support/Log.h>
45d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/CompilerConfig.h>
46d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/Initialization.h>
47d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/InputFile.h>
48d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/OutputFile.h>
49d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
50d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaousing namespace bcc;
51d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
52c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#define STR2(a) #a
53c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#define STR(a) STR2(a)
54c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
55d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
56d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// General Options
57d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
58d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaonamespace {
59d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
60a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Nillvm::cl::list<std::string>
61a4ded1373d7ad3e503f186e65bccf94126a0f020Yang NiOptInputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore,
62a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni                  llvm::cl::desc("<input bitcode files>"));
63a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
640ab50b835805c75ad164466767c2c212f48954ccYang Nillvm::cl::list<std::string>
650ab50b835805c75ad164466767c2c212f48954ccYang NiOptMergePlans("merge", llvm::cl::ZeroOrMore,
660ab50b835805c75ad164466767c2c212f48954ccYang Ni               llvm::cl::desc("Lists of kernels to merge (as source-and-slot "
670ab50b835805c75ad164466767c2c212f48954ccYang Ni                              "pairs) and names for the final merged kernels"));
680ab50b835805c75ad164466767c2c212f48954ccYang Ni
690ab50b835805c75ad164466767c2c212f48954ccYang Nillvm::cl::list<std::string>
700ab50b835805c75ad164466767c2c212f48954ccYang NiOptInvokes("invoke", llvm::cl::ZeroOrMore,
710ab50b835805c75ad164466767c2c212f48954ccYang Ni           llvm::cl::desc("Invocable functions"));
72d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
73d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<std::string>
74d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptOutputFilename("o", llvm::cl::desc("Specify the output filename"),
758be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines                  llvm::cl::value_desc("filename"),
768be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines                  llvm::cl::init("bcc_output"));
778be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines
788be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hinesllvm::cl::opt<std::string>
798be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen HinesOptBCLibFilename("bclib", llvm::cl::desc("Specify the bclib filename"),
808be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines                 llvm::cl::value_desc("bclib"));
818be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines
828be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hinesllvm::cl::opt<std::string>
836da4e253a513feef3405759fef6d0760828808caYang NiOptBCLibRelaxedFilename("bclib_relaxed", llvm::cl::desc("Specify the bclib filename optimized for "
846da4e253a513feef3405759fef6d0760828808caYang Ni                                                        "relaxed precision floating point maths"),
856da4e253a513feef3405759fef6d0760828808caYang Ni                        llvm::cl::init(""),
866da4e253a513feef3405759fef6d0760828808caYang Ni                        llvm::cl::value_desc("bclib_relaxed"));
876da4e253a513feef3405759fef6d0760828808caYang Ni
886da4e253a513feef3405759fef6d0760828808caYang Nillvm::cl::opt<std::string>
898be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen HinesOptOutputPath("output_path", llvm::cl::desc("Specify the output path"),
908be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines              llvm::cl::value_desc("output path"),
918be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines              llvm::cl::init("."));
92d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
937b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosserllvm::cl::opt<bool>
947b980e1717f3cf418f7bc4e40597004bc1139b8bTobias GrosserOptEmitLLVM("emit-llvm",
957b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser            llvm::cl::desc("Emit an LLVM-IR version of the generated program"));
967b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser
97d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<std::string>
98d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptTargetTriple("mtriple",
99d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::desc("Specify the target triple (default: "
100d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                               DEFAULT_TARGET_TRIPLE_STRING ")"),
101d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
102d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::value_desc("triple"));
103d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
104d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
105d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                 llvm::cl::desc("Alias for -mtriple"),
106d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                 llvm::cl::aliasopt(OptTargetTriple));
107d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
108c3437f05c638f8befda59170ae788873db24dc1cStephen Hinesllvm::cl::opt<bool>
109c3437f05c638f8befda59170ae788873db24dc1cStephen HinesOptRSDebugContext("rs-debug-ctx",
110c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    llvm::cl::desc("Enable build to work with a RenderScript debug context"));
111c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
112750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hinesllvm::cl::opt<bool>
113750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen HinesOptRSGlobalInfo("rs-global-info",
114750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines    llvm::cl::desc("Embed information about global variables in the code"));
115750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
116750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hinesllvm::cl::opt<bool>
117750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen HinesOptRSGlobalInfoSkipConstant("rs-global-info-skip-constant",
118750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines    llvm::cl::desc("Skip embedding information about constant global "
119750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines                   "variables in the code"));
120750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
12151ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainarllvm::cl::opt<std::string>
12251ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga NainarOptChecksum("build-checksum",
12351ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar            llvm::cl::desc("Embed a checksum of this compiler invocation for"
12451ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                           " cache invalidation at a later time"),
12551ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar            llvm::cl::value_desc("checksum"));
12651ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar
127d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
128d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Compiler Options
129d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
1301e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainarllvm::cl::opt<bool>
1311e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga NainarOptPIC("fPIC", llvm::cl::desc("Generate fully relocatable, position independent"
1321e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar                              " code"));
1331e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar
1341e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar// If set, use buildForCompatLib to embed RS symbol information into the object
1351e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar// file.  The information is stored in the .rs.info variable.  This option is
1361e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar// to be used in tandem with -fPIC.
1371e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainarllvm::cl::opt<bool>
1381e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga NainarOptEmbedRSInfo("embedRSInfo",
1391e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    llvm::cl::desc("Embed RS Info into the object file instead of generating"
1401e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar                   " a separate .o.info file"));
141d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
1427e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines// RenderScript uses -O3 by default
143d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<char>
144d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptOptLevel("O", llvm::cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
1457e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines                                "(default: -O3)"),
1467e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines            llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::init('3'));
147d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
148d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Override "bcc -version" since the LLVM version information is not correct on
149d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Android build.
150d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaovoid BCCVersionPrinter() {
151d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::raw_ostream &os = llvm::outs();
152d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  os << "libbcc (The Android Open Source Project, http://www.android.com/):\n"
153c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet     << "  Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n\n"
154c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet     << "LLVM (http://llvm.org/):\n"
155d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao     << "  Version: " << PACKAGE_VERSION << "\n";
156d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return;
157d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
158d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
1590ab50b835805c75ad164466767c2c212f48954ccYang Nivoid extractSourcesAndSlots(const llvm::cl::list<std::string>& optList,
1600ab50b835805c75ad164466767c2c212f48954ccYang Ni                            std::list<std::string>* batchNames,
1610ab50b835805c75ad164466767c2c212f48954ccYang Ni                            std::list<std::list<std::pair<int, int>>>* sourcesAndSlots) {
1620ab50b835805c75ad164466767c2c212f48954ccYang Ni  for (unsigned i = 0; i < optList.size(); ++i) {
1630ab50b835805c75ad164466767c2c212f48954ccYang Ni    std::string plan = optList[i];
1640ab50b835805c75ad164466767c2c212f48954ccYang Ni    unsigned found = plan.find(":");
1650ab50b835805c75ad164466767c2c212f48954ccYang Ni
1660ab50b835805c75ad164466767c2c212f48954ccYang Ni    std::string name = plan.substr(0, found);
1670ab50b835805c75ad164466767c2c212f48954ccYang Ni    std::cerr << "new kernel name: " << name << std::endl;
1680ab50b835805c75ad164466767c2c212f48954ccYang Ni    batchNames->push_back(name);
1690ab50b835805c75ad164466767c2c212f48954ccYang Ni
1700ab50b835805c75ad164466767c2c212f48954ccYang Ni    std::istringstream iss(plan.substr(found + 1));
1710ab50b835805c75ad164466767c2c212f48954ccYang Ni    std::string s;
1720ab50b835805c75ad164466767c2c212f48954ccYang Ni    std::list<std::pair<int, int>> planList;
1730ab50b835805c75ad164466767c2c212f48954ccYang Ni    while (getline(iss, s, '.')) {
1740ab50b835805c75ad164466767c2c212f48954ccYang Ni      found = s.find(",");
1750ab50b835805c75ad164466767c2c212f48954ccYang Ni      std::string sourceStr = s.substr(0, found);
1760ab50b835805c75ad164466767c2c212f48954ccYang Ni      std::string slotStr = s.substr(found + 1);
1770ab50b835805c75ad164466767c2c212f48954ccYang Ni
1780ab50b835805c75ad164466767c2c212f48954ccYang Ni      std::cerr << "source " << sourceStr << ", slot " << slotStr << std::endl;
1790ab50b835805c75ad164466767c2c212f48954ccYang Ni
1800ab50b835805c75ad164466767c2c212f48954ccYang Ni      int source = std::stoi(sourceStr);
1810ab50b835805c75ad164466767c2c212f48954ccYang Ni      int slot = std::stoi(slotStr);
1820ab50b835805c75ad164466767c2c212f48954ccYang Ni      planList.push_back(std::make_pair(source, slot));
1830ab50b835805c75ad164466767c2c212f48954ccYang Ni    }
184a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
1850ab50b835805c75ad164466767c2c212f48954ccYang Ni    sourcesAndSlots->push_back(planList);
1860ab50b835805c75ad164466767c2c212f48954ccYang Ni  }
1870ab50b835805c75ad164466767c2c212f48954ccYang Ni}
188a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
1890ab50b835805c75ad164466767c2c212f48954ccYang Nibool compileScriptGroup(BCCContext& Context, RSCompilerDriver& RSCD) {
1900ab50b835805c75ad164466767c2c212f48954ccYang Ni  std::vector<bcc::Source*> sources;
191a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  for (unsigned i = 0; i < OptInputFilenames.size(); ++i) {
1920ab50b835805c75ad164466767c2c212f48954ccYang Ni    bcc::Source* source =
193a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni        bcc::Source::CreateFromFile(Context, OptInputFilenames[i]);
194a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    if (!source) {
195a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      llvm::errs() << "Error loading file '" << OptInputFilenames[i]<< "'\n";
196a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      return false;
197a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    }
198a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    sources.push_back(source);
199a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  }
200a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
2010ab50b835805c75ad164466767c2c212f48954ccYang Ni  std::list<std::string> fusedKernelNames;
2020ab50b835805c75ad164466767c2c212f48954ccYang Ni  std::list<std::list<std::pair<int, int>>> sourcesAndSlots;
2030ab50b835805c75ad164466767c2c212f48954ccYang Ni  extractSourcesAndSlots(OptMergePlans, &fusedKernelNames, &sourcesAndSlots);
2040ab50b835805c75ad164466767c2c212f48954ccYang Ni
2050ab50b835805c75ad164466767c2c212f48954ccYang Ni  std::list<std::string> invokeBatchNames;
2060ab50b835805c75ad164466767c2c212f48954ccYang Ni  std::list<std::list<std::pair<int, int>>> invokeSourcesAndSlots;
2070ab50b835805c75ad164466767c2c212f48954ccYang Ni  extractSourcesAndSlots(OptInvokes, &invokeBatchNames, &invokeSourcesAndSlots);
2080ab50b835805c75ad164466767c2c212f48954ccYang Ni
209a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  std::string outputFilepath(OptOutputPath);
210a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  outputFilepath.append("/");
211a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  outputFilepath.append(OptOutputFilename);
212a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
213a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  bool success = RSCD.buildScriptGroup(
2146da4e253a513feef3405759fef6d0760828808caYang Ni    Context, outputFilepath.c_str(), OptBCLibFilename.c_str(),
215186d2f34573eb20de197d8eb8e08bcadd031a9bdYang Ni    OptBCLibRelaxedFilename.c_str(), OptEmitLLVM, OptChecksum.c_str(),
2160ab50b835805c75ad164466767c2c212f48954ccYang Ni    sources, sourcesAndSlots, fusedKernelNames,
2170ab50b835805c75ad164466767c2c212f48954ccYang Ni    invokeSourcesAndSlots, invokeBatchNames);
218a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
219a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  return success;
220a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni}
221a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
222d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao} // end anonymous namespace
223d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
224d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostatic inline
2257e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hinesbool ConfigCompiler(RSCompilerDriver &pRSCD) {
226b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes  Compiler *RSC = pRSCD.getCompiler();
227900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  CompilerConfig *config = nullptr;
228d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
229d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  config = new (std::nothrow) CompilerConfig(OptTargetTriple);
230900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (config == nullptr) {
231d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Out of memory when create the compiler configuration!\n";
232d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
233d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
234d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
2351e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar  if (OptPIC) {
2361e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    config->setRelocationModel(llvm::Reloc::PIC_);
2371e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar
2381e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    // For x86_64, CodeModel needs to be small if PIC_ reloc is used.
2391e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    // Otherwise, we end up with TEXTRELs in the shared library.
2401e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    if (config->getTriple().find("x86_64") != std::string::npos) {
2411e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar        config->setCodeModel(llvm::CodeModel::Small);
2421e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    }
2431e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar  }
244d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  switch (OptOptLevel) {
245d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    case '0': config->setOptimizationLevel(llvm::CodeGenOpt::None); break;
246d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    case '1': config->setOptimizationLevel(llvm::CodeGenOpt::Less); break;
2477e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines    case '2': config->setOptimizationLevel(llvm::CodeGenOpt::Default); break;
2487e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines    case '3':
249d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    default: {
2507e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines      config->setOptimizationLevel(llvm::CodeGenOpt::Aggressive);
251d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      break;
252d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    }
253d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
254d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
2557e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines  pRSCD.setConfig(config);
2567e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines  Compiler::ErrorCode result = RSC->config(*config);
257d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
258c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  if (OptRSDebugContext) {
259c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    pRSCD.setDebugContext(true);
260c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  }
261c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
262750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  if (OptRSGlobalInfo) {
263750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines    pRSCD.setEmbedGlobalInfo(true);
264750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  }
265750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
266750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  if (OptRSGlobalInfoSkipConstant) {
267750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines    pRSCD.setEmbedGlobalInfoSkipConstant(true);
268750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines  }
269750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines
270d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (result != Compiler::kSuccess) {
271d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Failed to configure the compiler! (detail: "
272d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 << Compiler::GetErrorString(result) << ")\n";
273d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
274d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
275d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
276d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return true;
277d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
278d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
279d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaoint main(int argc, char **argv) {
280c46a3f5370364ad5698756d5da5b8845be9970d0Tim Murray
281c46a3f5370364ad5698756d5da5b8845be9970d0Tim Murray  llvm::llvm_shutdown_obj Y;
282c46a3f5370364ad5698756d5da5b8845be9970d0Tim Murray  init::Initialize();
283d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::cl::SetVersionPrinter(BCCVersionPrinter);
284d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::cl::ParseCommandLineOptions(argc, argv);
285d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
286d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  BCCContext context;
2878be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines  RSCompilerDriver RSCD;
288d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
289c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  if (OptBCLibFilename.empty()) {
290a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    ALOGE("Failed to compile bitcode, -bclib was not specified");
291d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return EXIT_FAILURE;
292d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
2938be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines
2947e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines  if (!ConfigCompiler(RSCD)) {
2957e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines    ALOGE("Failed to configure compiler");
2967e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines    return EXIT_FAILURE;
2977e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines  }
298c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
299c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  // Attempt to dynamically initialize the compiler driver if such a function
300c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  // is present. It is only present if passed via "-load libFOO.so".
301c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  RSCompilerDriverInit_t rscdi = (RSCompilerDriverInit_t)
302c3437f05c638f8befda59170ae788873db24dc1cStephen Hines      dlsym(RTLD_DEFAULT, STR(RS_COMPILER_DRIVER_INIT_FN));
303900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (rscdi != nullptr) {
304c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    rscdi(&RSCD);
305c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  }
306c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
3070ab50b835805c75ad164466767c2c212f48954ccYang Ni  if (OptMergePlans.size() > 0) {
3080ab50b835805c75ad164466767c2c212f48954ccYang Ni    bool success = compileScriptGroup(context, RSCD);
3090ab50b835805c75ad164466767c2c212f48954ccYang Ni
310a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    if (!success) {
311a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      return EXIT_FAILURE;
312a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    }
3130ab50b835805c75ad164466767c2c212f48954ccYang Ni
314a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    return EXIT_SUCCESS;
315a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  }
316a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
317a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> mb_or_error =
318a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      llvm::MemoryBuffer::getFile(OptInputFilenames[0].c_str());
319a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  if (mb_or_error.getError()) {
320a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    ALOGE("Failed to load bitcode from path %s! (%s)",
321a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni          OptInputFilenames[0].c_str(), mb_or_error.getError().message().c_str());
322a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    return EXIT_FAILURE;
323a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  }
324a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  std::unique_ptr<llvm::MemoryBuffer> input_data = std::move(mb_or_error.get());
325a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
326a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  const char *bitcode = input_data->getBufferStart();
327a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  size_t bitcodeSize = input_data->getBufferSize();
328a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
3291e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar  if (!OptEmbedRSInfo) {
330a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar    bool built = RSCD.build(context, OptOutputPath.c_str(),
331a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar                            OptOutputFilename.c_str(),
332a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar                            bitcode, bitcodeSize,
333a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar                            OptChecksum.c_str(), OptBCLibFilename.c_str(),
334a65fba6fd15b14d930809e64c84fb976a893d038Pirama Arumuga Nainar                            nullptr, OptEmitLLVM);
335d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
3361e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    if (!built) {
3371e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      return EXIT_FAILURE;
3381e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    }
3390ab50b835805c75ad164466767c2c212f48954ccYang Ni  } else {
3401e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    // embedRSInfo is set.  Use buildForCompatLib to embed RS symbol information
3411e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    // into the .rs.info symbol.
342a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    Source *source = Source::CreateFromBuffer(context, OptInputFilenames[0].c_str(),
3431e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar                                              bitcode, bitcodeSize);
344656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty
345656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty    // If the bitcode fails verification in the bitcode loader, the returned Source is set to NULL.
346656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty    if (!source) {
347656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty      ALOGE("Failed to load source from file %s", OptInputFilenames[0].c_str());
348656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty      return EXIT_FAILURE;
349656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty    }
350656325bdb4751d5606f9e53d8f417bd727032c31Stephen McGroarty
3518e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar    std::unique_ptr<RSScript> s(new (std::nothrow) RSScript(*source, RSCD.getConfig()));
3521e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    if (s == nullptr) {
3531e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      llvm::errs() << "Out of memory when creating script for file `"
354a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni                   << OptInputFilenames[0] << "'!\n";
3551e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      delete source;
3561e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      return EXIT_FAILURE;
3571e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    }
3581e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar
3591e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    llvm::SmallString<80> output(OptOutputPath);
3601e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    llvm::sys::path::append(output, "/", OptOutputFilename);
3611e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    llvm::sys::path::replace_extension(output, ".o");
3621e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar
36351ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar    if (!RSCD.buildForCompatLib(*s, output.c_str(), OptChecksum.c_str(),
36451ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                                OptBCLibFilename.c_str(), OptEmitLLVM)) {
3651e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      fprintf(stderr, "Failed to compile script!");
3661e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      return EXIT_FAILURE;
3671e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    }
368d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
369d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
370d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return EXIT_SUCCESS;
371d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
372