Main.cpp revision 51ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dc
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
17d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <string>
18d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <vector>
19d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
20c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#include <dlfcn.h>
21d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <stdlib.h>
22d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
23d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/ADT/STLExtras.h>
24d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/ADT/SmallString.h>
25d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Config/config.h>
26d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/CommandLine.h>
27d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/FileSystem.h>
28c46a3f5370364ad5698756d5da5b8845be9970d0Tim Murray#include <llvm/Support/ManagedStatic.h>
298be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines#include <llvm/Support/MemoryBuffer.h>
301e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar#include <llvm/Support/Path.h>
31c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#include <llvm/Support/PluginLoader.h>
32d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <llvm/Support/raw_ostream.h>
33d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
34d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/BCCContext.h>
35d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Compiler.h>
36d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Config/Config.h>
378be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines#include <bcc/Renderscript/RSCompilerDriver.h>
38d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Script.h>
39d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Source.h>
40d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/CompilerConfig.h>
41d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/Initialization.h>
42d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/InputFile.h>
43d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao#include <bcc/Support/OutputFile.h>
44d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
45d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaousing namespace bcc;
46d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
47c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#define STR2(a) #a
48c3437f05c638f8befda59170ae788873db24dc1cStephen Hines#define STR(a) STR2(a)
49c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
50d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
51d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// General Options
52d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
53d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaonamespace {
54d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
55a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Nillvm::cl::list<std::string>
56a4ded1373d7ad3e503f186e65bccf94126a0f020Yang NiOptInputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore,
57a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni                  llvm::cl::desc("<input bitcode files>"));
58a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
59a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Nillvm::cl::list<int>
60a4ded1373d7ad3e503f186e65bccf94126a0f020Yang NiOptKernelSlots("k", llvm::cl::ZeroOrMore,
61a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni               llvm::cl::desc("kernel function slot numbers"));
62d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
63d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<std::string>
64d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptOutputFilename("o", llvm::cl::desc("Specify the output filename"),
658be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines                  llvm::cl::value_desc("filename"),
668be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines                  llvm::cl::init("bcc_output"));
678be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines
688be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hinesllvm::cl::opt<std::string>
698be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen HinesOptBCLibFilename("bclib", llvm::cl::desc("Specify the bclib filename"),
708be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines                 llvm::cl::value_desc("bclib"));
718be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines
728be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hinesllvm::cl::opt<std::string>
738be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen HinesOptOutputPath("output_path", llvm::cl::desc("Specify the output path"),
748be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines              llvm::cl::value_desc("output path"),
758be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines              llvm::cl::init("."));
76d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
777b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosserllvm::cl::opt<bool>
787b980e1717f3cf418f7bc4e40597004bc1139b8bTobias GrosserOptEmitLLVM("emit-llvm",
797b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser            llvm::cl::desc("Emit an LLVM-IR version of the generated program"));
807b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser
81d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<std::string>
82d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptTargetTriple("mtriple",
83d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::desc("Specify the target triple (default: "
84d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                               DEFAULT_TARGET_TRIPLE_STRING ")"),
85d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
86d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                llvm::cl::value_desc("triple"));
87d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
88d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
89d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                 llvm::cl::desc("Alias for -mtriple"),
90d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                                 llvm::cl::aliasopt(OptTargetTriple));
91d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
92c3437f05c638f8befda59170ae788873db24dc1cStephen Hinesllvm::cl::opt<bool>
93c3437f05c638f8befda59170ae788873db24dc1cStephen HinesOptRSDebugContext("rs-debug-ctx",
94c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    llvm::cl::desc("Enable build to work with a RenderScript debug context"));
95c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
9651ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainarllvm::cl::opt<std::string>
9751ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga NainarOptChecksum("build-checksum",
9851ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar            llvm::cl::desc("Embed a checksum of this compiler invocation for"
9951ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                           " cache invalidation at a later time"),
10051ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar            llvm::cl::value_desc("checksum"));
10151ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar
102d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
103d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Compiler Options
104d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao//===----------------------------------------------------------------------===//
1051e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainarllvm::cl::opt<bool>
1061e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga NainarOptPIC("fPIC", llvm::cl::desc("Generate fully relocatable, position independent"
1071e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar                              " code"));
1081e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar
1091e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar// If set, use buildForCompatLib to embed RS symbol information into the object
1101e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar// file.  The information is stored in the .rs.info variable.  This option is
1111e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar// to be used in tandem with -fPIC.
1121e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainarllvm::cl::opt<bool>
1131e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga NainarOptEmbedRSInfo("embedRSInfo",
1141e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    llvm::cl::desc("Embed RS Info into the object file instead of generating"
1151e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar                   " a separate .o.info file"));
116d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
1177e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines// RenderScript uses -O3 by default
118d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaollvm::cl::opt<char>
119d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei LiaoOptOptLevel("O", llvm::cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
1207e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines                                "(default: -O3)"),
1217e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines            llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::init('3'));
122d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
123d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Override "bcc -version" since the LLVM version information is not correct on
124d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao// Android build.
125d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaovoid BCCVersionPrinter() {
126d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::raw_ostream &os = llvm::outs();
127d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  os << "libbcc (The Android Open Source Project, http://www.android.com/):\n"
128c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet     << "  Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n\n"
129c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet     << "LLVM (http://llvm.org/):\n"
130d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao     << "  Version: " << PACKAGE_VERSION << "\n";
131d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return;
132d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
133d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
134a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Nibool fuseKernels(BCCContext& Context, RSCompilerDriver& RSCD) {
135a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  if (OptInputFilenames.size() != OptKernelSlots.size()) {
136a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    llvm::errs() << "Mismatching number of input files and kernel slots.\n";
137a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    return false;
138a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  }
139a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
140a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  std::vector<const bcc::Source*> sources;
141a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  std::vector<int> slots;
142a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
143a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  for (unsigned i = 0; i < OptInputFilenames.size(); ++i) {
144a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    const bcc::Source* source =
145a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni        bcc::Source::CreateFromFile(Context, OptInputFilenames[i]);
146a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    if (!source) {
147a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      llvm::errs() << "Error loading file '" << OptInputFilenames[i]<< "'\n";
148a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      return false;
149a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    }
150a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    int slot = OptKernelSlots[i];
151a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
152a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    sources.push_back(source);
153a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    slots.push_back(slot);
154a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  }
155a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
156a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  std::string outputFilepath(OptOutputPath);
157a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  outputFilepath.append("/");
158a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  outputFilepath.append(OptOutputFilename);
159a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
160a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  bool success = RSCD.buildScriptGroup(
161a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      Context, outputFilepath.c_str(), OptBCLibFilename.c_str(), sources,
162a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      slots, true);
163a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
164a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  return success;
165a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni}
166a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
167d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao} // end anonymous namespace
168d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
169d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaostatic inline
1707e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hinesbool ConfigCompiler(RSCompilerDriver &pRSCD) {
171b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes  Compiler *RSC = pRSCD.getCompiler();
172900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  CompilerConfig *config = nullptr;
173d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
174d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  config = new (std::nothrow) CompilerConfig(OptTargetTriple);
175900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (config == nullptr) {
176d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Out of memory when create the compiler configuration!\n";
177d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
178d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
179d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
180602ce0336c0ff5109923cee9b4426e913e718605Jian Li  // llvm3.5 has removed the auto-detect feature for x86 subtarget,
181602ce0336c0ff5109923cee9b4426e913e718605Jian Li  // so set features explicitly in bcc.
182602ce0336c0ff5109923cee9b4426e913e718605Jian Li  if ((config->getTriple().find("i686") != std::string::npos) ||
183602ce0336c0ff5109923cee9b4426e913e718605Jian Li    (config->getTriple().find("x86_64") != std::string::npos)) {
184602ce0336c0ff5109923cee9b4426e913e718605Jian Li    std::vector<std::string> fv;
185602ce0336c0ff5109923cee9b4426e913e718605Jian Li
186602ce0336c0ff5109923cee9b4426e913e718605Jian Li#if defined(__SSE3__)
187602ce0336c0ff5109923cee9b4426e913e718605Jian Li    fv.push_back("+sse3");
188602ce0336c0ff5109923cee9b4426e913e718605Jian Li#endif
189602ce0336c0ff5109923cee9b4426e913e718605Jian Li#if defined(__SSSE3__)
190602ce0336c0ff5109923cee9b4426e913e718605Jian Li    fv.push_back("+ssse3");
191602ce0336c0ff5109923cee9b4426e913e718605Jian Li#endif
192602ce0336c0ff5109923cee9b4426e913e718605Jian Li#if defined(__SSE4_1__)
193602ce0336c0ff5109923cee9b4426e913e718605Jian Li    fv.push_back("+sse4.1");
194602ce0336c0ff5109923cee9b4426e913e718605Jian Li#endif
195602ce0336c0ff5109923cee9b4426e913e718605Jian Li#if defined(__SSE4_2__)
196602ce0336c0ff5109923cee9b4426e913e718605Jian Li    fv.push_back("+sse4.2");
197602ce0336c0ff5109923cee9b4426e913e718605Jian Li#endif
198602ce0336c0ff5109923cee9b4426e913e718605Jian Li
199602ce0336c0ff5109923cee9b4426e913e718605Jian Li    if (fv.size()) {
200602ce0336c0ff5109923cee9b4426e913e718605Jian Li      config->setFeatureString(fv);
201602ce0336c0ff5109923cee9b4426e913e718605Jian Li    }
202602ce0336c0ff5109923cee9b4426e913e718605Jian Li  }
203602ce0336c0ff5109923cee9b4426e913e718605Jian Li
2041e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar  if (OptPIC) {
2051e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    config->setRelocationModel(llvm::Reloc::PIC_);
2061e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar
2071e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    // For x86_64, CodeModel needs to be small if PIC_ reloc is used.
2081e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    // Otherwise, we end up with TEXTRELs in the shared library.
2091e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    if (config->getTriple().find("x86_64") != std::string::npos) {
2101e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar        config->setCodeModel(llvm::CodeModel::Small);
2111e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    }
2121e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar  }
213d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  switch (OptOptLevel) {
214d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    case '0': config->setOptimizationLevel(llvm::CodeGenOpt::None); break;
215d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    case '1': config->setOptimizationLevel(llvm::CodeGenOpt::Less); break;
2167e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines    case '2': config->setOptimizationLevel(llvm::CodeGenOpt::Default); break;
2177e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines    case '3':
218d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    default: {
2197e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines      config->setOptimizationLevel(llvm::CodeGenOpt::Aggressive);
220d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao      break;
221d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    }
222d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
223d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
2247e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines  pRSCD.setConfig(config);
2257e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines  Compiler::ErrorCode result = RSC->config(*config);
226d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
227c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  if (OptRSDebugContext) {
228c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    pRSCD.setDebugContext(true);
229c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  }
230c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
231d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  if (result != Compiler::kSuccess) {
232d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    llvm::errs() << "Failed to configure the compiler! (detail: "
233d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao                 << Compiler::GetErrorString(result) << ")\n";
234d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return false;
235d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
236d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
237d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return true;
238d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
239d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
240d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liaoint main(int argc, char **argv) {
241c46a3f5370364ad5698756d5da5b8845be9970d0Tim Murray
242c46a3f5370364ad5698756d5da5b8845be9970d0Tim Murray  llvm::llvm_shutdown_obj Y;
243c46a3f5370364ad5698756d5da5b8845be9970d0Tim Murray  init::Initialize();
244d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::cl::SetVersionPrinter(BCCVersionPrinter);
245d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  llvm::cl::ParseCommandLineOptions(argc, argv);
246f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  std::string commandLine = bcc::getCommandLine(argc, argv);
247d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
248d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  BCCContext context;
2498be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines  RSCompilerDriver RSCD;
250d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
251c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  if (OptBCLibFilename.empty()) {
252a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    ALOGE("Failed to compile bitcode, -bclib was not specified");
253d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao    return EXIT_FAILURE;
254d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
2558be8dba08c97dff239ac8c6bdc7f3a52d96116aeStephen Hines
2567e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines  if (!ConfigCompiler(RSCD)) {
2577e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines    ALOGE("Failed to configure compiler");
2587e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines    return EXIT_FAILURE;
2597e9c1853efd1615e9187611e8f47ef3ec30de686Stephen Hines  }
260c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
261c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  // Attempt to dynamically initialize the compiler driver if such a function
262c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  // is present. It is only present if passed via "-load libFOO.so".
263c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  RSCompilerDriverInit_t rscdi = (RSCompilerDriverInit_t)
264c3437f05c638f8befda59170ae788873db24dc1cStephen Hines      dlsym(RTLD_DEFAULT, STR(RS_COMPILER_DRIVER_INIT_FN));
265900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (rscdi != nullptr) {
266c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    rscdi(&RSCD);
267c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  }
268c3437f05c638f8befda59170ae788873db24dc1cStephen Hines
269a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  if (OptInputFilenames.size() > 1) {
270a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    bool success = fuseKernels(context, RSCD);
271a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    if (!success) {
272a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      return EXIT_FAILURE;
273a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    }
274a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    return EXIT_SUCCESS;
275a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  }
276a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
277a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> mb_or_error =
278a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni      llvm::MemoryBuffer::getFile(OptInputFilenames[0].c_str());
279a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  if (mb_or_error.getError()) {
280a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    ALOGE("Failed to load bitcode from path %s! (%s)",
281a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni          OptInputFilenames[0].c_str(), mb_or_error.getError().message().c_str());
282a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    return EXIT_FAILURE;
283a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  }
284a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  std::unique_ptr<llvm::MemoryBuffer> input_data = std::move(mb_or_error.get());
285a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
286a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  const char *bitcode = input_data->getBufferStart();
287a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  size_t bitcodeSize = input_data->getBufferSize();
288a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni
2891e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar  if (!OptEmbedRSInfo) {
2901e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    bool built = RSCD.build(context, OptOutputPath.c_str(), OptOutputFilename.c_str(), bitcode,
29151ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                            bitcodeSize, commandLine.c_str(), OptChecksum.c_str(), OptBCLibFilename.c_str(), nullptr,
2921e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar                            OptEmitLLVM);
293d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
2941e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    if (!built) {
2951e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      return EXIT_FAILURE;
2961e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    }
2971e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar  }
2981e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar  else {
2991e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    // embedRSInfo is set.  Use buildForCompatLib to embed RS symbol information
3001e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    // into the .rs.info symbol.
301a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni    Source *source = Source::CreateFromBuffer(context, OptInputFilenames[0].c_str(),
3021e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar                                              bitcode, bitcodeSize);
3031e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    RSScript *s = new (std::nothrow) RSScript(*source);
3041e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    if (s == nullptr) {
3051e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      llvm::errs() << "Out of memory when creating script for file `"
306a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni                   << OptInputFilenames[0] << "'!\n";
3071e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      delete source;
3081e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      return EXIT_FAILURE;
3091e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    }
3101e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar
3111e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    llvm::SmallString<80> output(OptOutputPath);
3121e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    llvm::sys::path::append(output, "/", OptOutputFilename);
3131e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    llvm::sys::path::replace_extension(output, ".o");
3141e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar
31551ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar    if (!RSCD.buildForCompatLib(*s, output.c_str(), OptChecksum.c_str(),
31651ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar                                OptBCLibFilename.c_str(), OptEmitLLVM)) {
3171e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      fprintf(stderr, "Failed to compile script!");
3181e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar      return EXIT_FAILURE;
3191e0557ae75ae780352845bd2ba0f4babdc5ae4e6Pirama Arumuga Nainar    }
320d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  }
321d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao
322d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao  return EXIT_SUCCESS;
323d577d11347cdad9b88c0802bf6f5ee1fd3c06f19Shih-wei Liao}
324