1331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines/*
2331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * Copyright 2012, The Android Open Source Project
3331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines *
4331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * you may not use this file except in compliance with the License.
6331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * You may obtain a copy of the License at
7331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines *
8331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
9331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines *
10331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * Unless required by applicable law or agreed to in writing, software
11331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * See the License for the specific language governing permissions and
14331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * limitations under the License.
15331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines */
16331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
17331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <string>
18331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <vector>
19331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
20331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <stdlib.h>
21331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
22331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/ADT/STLExtras.h>
23331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/ADT/SmallString.h>
24331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Config/config.h>
25331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/CommandLine.h>
26331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/FileSystem.h>
27331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/Path.h>
28331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/raw_ostream.h>
29331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
30331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/BCCContext.h>
31331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Compiler.h>
32331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Config/Config.h>
33331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Renderscript/RSCompilerDriver.h>
34331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Script.h>
35331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Source.h>
36331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/CompilerConfig.h>
37331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/Initialization.h>
38331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/InputFile.h>
39331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/OutputFile.h>
40331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
41331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesusing namespace bcc;
42331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
43331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
44331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// General Options
45331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
46331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesnamespace {
47331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
48331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::list<std::string>
49331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptInputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore,
50331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                  llvm::cl::desc("<input bitcode files>"));
51331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
52331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<std::string>
53331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptOutputFilename("o", llvm::cl::desc("Specify the output filename"),
54331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                  llvm::cl::value_desc("filename"));
55331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
56331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<std::string>
57331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptRuntimePath("rt-path", llvm::cl::desc("Specify the runtime library path"),
58331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines               llvm::cl::value_desc("path"));
59331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
60331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<std::string>
61331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptTargetTriple("mtriple",
62331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                llvm::cl::desc("Specify the target triple (default: "
63331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                               DEFAULT_TARGET_TRIPLE_STRING ")"),
64331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
65331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                llvm::cl::value_desc("triple"));
66331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
67331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
68331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                 llvm::cl::desc("Alias for -mtriple"),
69331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                 llvm::cl::aliasopt(OptTargetTriple));
70331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
71331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
72331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// Compiler Options
73331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
74331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<bool>
75331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptPIC("fPIC", llvm::cl::desc("Generate fully relocatable, position independent"
76331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                              " code"));
77331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
78331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<char>
79331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptOptLevel("O", llvm::cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
80331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                "(default: -O2)"),
81331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines            llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::init('2'));
82331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
83331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<bool>
84331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptC("c", llvm::cl::desc("Compile and assemble, but do not link."));
85331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
86331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
87331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// Linker Options
88331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
89331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// FIXME: this option will be removed in the future when MCLinker is capable
90331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//        of generating shared library directly from given bitcode. It only
91331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//        takes effect when -shared is supplied.
92331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<std::string>
93331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptImmObjectOutput("or", llvm::cl::desc("Specify the filename for output the "
94331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                        "intermediate relocatable when linking "
95331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                        "the input bitcode to the shared "
96331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                        "library"), llvm::cl::ValueRequired);
97331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
98331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<bool>
99331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptShared("shared", llvm::cl::desc("Create a shared library from input bitcode "
100331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                   "files"));
101331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
102331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
103331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// Override "bcc -version" since the LLVM version information is not correct on
104331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// Android build.
105331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesvoid BCCVersionPrinter() {
106331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::raw_ostream &os = llvm::outs();
107331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  os << "libbcc (The Android Open Source Project, http://www.android.com/):\n"
108c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet     << "  Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n\n"
109c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet     << "LLVM (http://llvm.org/):\n"
110331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines     << "  Version: " << PACKAGE_VERSION << "\n";
111331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return;
112331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
113331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
114331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines} // end anonymous namespace
115331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
116331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesRSScript *PrepareRSScript(BCCContext &pContext,
117331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                          const llvm::cl::list<std::string> &pBitcodeFiles) {
118900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  RSScript *result = nullptr;
119331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
120331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  for (unsigned i = 0; i < pBitcodeFiles.size(); i++) {
121331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    const std::string &input_bitcode = pBitcodeFiles[i];
122331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    Source *source = Source::CreateFromFile(pContext, input_bitcode);
123900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes    if (source == nullptr) {
124331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      llvm::errs() << "Failed to load llvm module from file `" << input_bitcode
125331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                   << "'!\n";
126900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes      return nullptr;
127331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    }
128331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
129900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes    if (result != nullptr) {
130579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines      if (!result->mergeSource(*source)) {
131331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        llvm::errs() << "Failed to merge the llvm module `" << input_bitcode
132331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                     << "' to compile!\n";
133331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        delete source;
134900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes        return nullptr;
135331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      }
136331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    } else {
137331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      result = new (std::nothrow) RSScript(*source);
138900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes      if (result == nullptr) {
139331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        llvm::errs() << "Out of memory when create script for file `"
140331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                     << input_bitcode << "'!\n";
141331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        delete source;
142900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes        return nullptr;
143331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      }
144331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    }
145331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
146331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
147331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return result;
148331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
149331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
150331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesstatic inline
151331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesbool ConfigCompiler(RSCompilerDriver &pCompilerDriver) {
152b4447cd2b14f53efd9102d28da48000be7b2d4fdChris Wailes  Compiler *compiler = pCompilerDriver.getCompiler();
153900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  CompilerConfig *config = nullptr;
154331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
155331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  config = new (std::nothrow) CompilerConfig(OptTargetTriple);
156900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (config == nullptr) {
157331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Out of memory when create the compiler configuration!\n";
158331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return false;
159331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
160331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
161e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines  // Explicitly set ARM feature vector
162e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines  if (config->getTriple().find("arm") != std::string::npos) {
163e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    std::vector<std::string> fv;
164e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    fv.push_back("+vfp3");
165e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    fv.push_back("+d16");
166e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    fv.push_back("-neon");
167e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    fv.push_back("-neonfp");
168e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    config->setFeatureString(fv);
169e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines  }
170634ac6c59bf2d46270da48fdf7c2af834d2a78b2Stephen Hines
17132e8068b311574a3085e7bc662daa18c1f2f285eYong Chen  // Explicitly set X86 feature vector
17232e8068b311574a3085e7bc662daa18c1f2f285eYong Chen  if ((config->getTriple().find("i686") != std::string::npos) ||
17332e8068b311574a3085e7bc662daa18c1f2f285eYong Chen    (config->getTriple().find("x86_64") != std::string::npos)) {
17432e8068b311574a3085e7bc662daa18c1f2f285eYong Chen    std::vector<std::string> fv;
17532e8068b311574a3085e7bc662daa18c1f2f285eYong Chen    fv.push_back("+sse3");
17632e8068b311574a3085e7bc662daa18c1f2f285eYong Chen    config->setFeatureString(fv);
17732e8068b311574a3085e7bc662daa18c1f2f285eYong Chen  }
17832e8068b311574a3085e7bc662daa18c1f2f285eYong Chen
179221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines  // Compatibility mode on x86 requires atom code generation.
180221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines  if (config->getTriple().find("i686") != std::string::npos) {
181221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines    config->setCPU("atom");
182221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines  }
183221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines
184331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // Setup the config according to the value of command line option.
185331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptPIC) {
186331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    config->setRelocationModel(llvm::Reloc::PIC_);
18796627fc90a36bd7657dd86c66349a4a61ed976a5Miao Wang    // For x86_64, CodeModel needs to be small if PIC_ reloc is used.
18896627fc90a36bd7657dd86c66349a4a61ed976a5Miao Wang    // Otherwise, we end up with TEXTRELs in the shared library.
18996627fc90a36bd7657dd86c66349a4a61ed976a5Miao Wang    if (config->getTriple().find("x86_64") != std::string::npos) {
19096627fc90a36bd7657dd86c66349a4a61ed976a5Miao Wang        config->setCodeModel(llvm::CodeModel::Small);
19196627fc90a36bd7657dd86c66349a4a61ed976a5Miao Wang    }
192331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
193331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  switch (OptOptLevel) {
194331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '0': config->setOptimizationLevel(llvm::CodeGenOpt::None); break;
195331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '1': config->setOptimizationLevel(llvm::CodeGenOpt::Less); break;
196331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '3': config->setOptimizationLevel(llvm::CodeGenOpt::Aggressive); break;
197331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '2':
198331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    default: {
199331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      config->setOptimizationLevel(llvm::CodeGenOpt::Default);
200331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      break;
201331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    }
202331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
203331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
204331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  pCompilerDriver.setConfig(config);
205331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  Compiler::ErrorCode result = compiler->config(*config);
206331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
207331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (result != Compiler::kSuccess) {
208331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Failed to configure the compiler! (detail: "
209331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                 << Compiler::GetErrorString(result) << ")\n";
210331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return false;
211331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
212331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
213331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return true;
214331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
215331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
216331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#define DEFAULT_OUTPUT_PATH   "/sdcard/a.out"
217331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesstatic inline
218331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesstd::string DetermineOutputFilename(const std::string &pOutputPath) {
219331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (!pOutputPath.empty()) {
220331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return pOutputPath;
221331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
222331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
223331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // User doesn't specify the value to -o.
224331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptInputFilenames.size() > 1) {
225331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Use " DEFAULT_OUTPUT_PATH " for output file!\n";
226331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return DEFAULT_OUTPUT_PATH;
227331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
228331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
229331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // There's only one input bitcode file.
230331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  const std::string &input_path = OptInputFilenames[0];
231331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::SmallString<200> output_path(input_path);
232331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
233d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines  std::error_code err = llvm::sys::fs::make_absolute(output_path);
234d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines  if (err) {
235331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Failed to determine the absolute path of `" << input_path
236331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                 << "'! (detail: " << err.message() << ")\n";
237331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return "";
238331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
239331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
240331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptC) {
241331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // -c was specified. Replace the extension to .o.
242331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::replace_extension(output_path, "o");
243331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  } else {
244331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // Use a.out under current working directory when compile executable or
245331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // shared library.
246331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::remove_filename(output_path);
247331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::append(output_path, "a.out");
248331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
249331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
250331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return output_path.c_str();
251331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
252331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
253331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesint main(int argc, char **argv) {
254331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::cl::SetVersionPrinter(BCCVersionPrinter);
255331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::cl::ParseCommandLineOptions(argc, argv);
256331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  init::Initialize();
257331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
258331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptRuntimePath.empty()) {
259331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    fprintf(stderr, "You must set \"-rt-path </path/to/libclcore.bc>\" with "
260331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                    "this tool\n");
261331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
262331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
263331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
264331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  BCCContext context;
2653ab9da1e1b3d7794994393af086d096397fb84dbStephen Hines  RSCompilerDriver rscd(false);
266331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  Compiler compiler;
267331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
268331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (!ConfigCompiler(rscd)) {
269331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
270331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
271331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
272331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  std::string OutputFilename = DetermineOutputFilename(OptOutputFilename);
273331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OutputFilename.empty()) {
274331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
275331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
276331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
2778e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  std::unique_ptr<RSScript> s(PrepareRSScript(context, OptInputFilenames));
27851ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar  if (!rscd.buildForCompatLib(*s, OutputFilename.c_str(), nullptr, OptRuntimePath.c_str(), false)) {
27947f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    fprintf(stderr, "Failed to compile script!");
28047f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return EXIT_FAILURE;
28147f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  }
282331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
283331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return EXIT_SUCCESS;
284331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
285