Home | History | Annotate | Download | only in compiler
      1 /*
      2  * Copyright 2016, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "RSSPIRVWriter.h"
     18 #include "bcinfo/MetadataExtractor.h"
     19 #include "spirit/file_utils.h"
     20 
     21 #include "llvm/Bitcode/ReaderWriter.h"
     22 #include "llvm/IR/LLVMContext.h"
     23 #include "llvm/IR/Module.h"
     24 #include "llvm/Support/CommandLine.h"
     25 #include "llvm/Support/DataStream.h"
     26 #include "llvm/Support/Debug.h"
     27 #include "llvm/Support/FileSystem.h"
     28 #include "llvm/Support/PrettyStackTrace.h"
     29 #include "llvm/Support/Signals.h"
     30 #include "llvm/Support/ToolOutputFile.h"
     31 #include "llvm/Support/raw_ostream.h"
     32 
     33 #define DEBUG_TYPE "rs2spirv"
     34 
     35 namespace kExt {
     36 const char SPIRVBinary[] = ".spv";
     37 } // namespace kExt
     38 
     39 using namespace llvm;
     40 
     41 static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
     42                                       cl::init("-"));
     43 
     44 static cl::opt<std::string> OutputFile("o",
     45                                        cl::desc("Override output filename"),
     46                                        cl::value_desc("filename"));
     47 
     48 static std::string removeExt(const std::string &FileName) {
     49   size_t Pos = FileName.find_last_of(".");
     50   if (Pos != std::string::npos)
     51     return FileName.substr(0, Pos);
     52   return FileName;
     53 }
     54 
     55 static int convertLLVMToSPIRV() {
     56   LLVMContext Context;
     57 
     58   std::string Err;
     59   auto DS = getDataFileStreamer(InputFile, &Err);
     60   if (!DS) {
     61     errs() << "Fails to open input file: " << Err;
     62     return -1;
     63   }
     64   ErrorOr<std::unique_ptr<Module>> MOrErr =
     65       getStreamedBitcodeModule(InputFile, std::move(DS), Context);
     66 
     67   if (std::error_code EC = MOrErr.getError()) {
     68     errs() << "Fails to load bitcode: " << EC.message();
     69     return -1;
     70   }
     71 
     72   std::unique_ptr<Module> M = std::move(*MOrErr);
     73 
     74   if (std::error_code EC = M->materializeAll()) {
     75     errs() << "Fails to materialize: " << EC.message();
     76     return -1;
     77   }
     78 
     79   if (OutputFile.empty()) {
     80     if (InputFile == "-")
     81       OutputFile = "-";
     82     else
     83       OutputFile = removeExt(InputFile) + kExt::SPIRVBinary;
     84   }
     85 
     86   llvm::StringRef outFile(OutputFile);
     87   std::error_code EC;
     88   llvm::raw_fd_ostream OFS(outFile, EC, llvm::sys::fs::F_None);
     89 
     90   std::vector<char> bitcode = android::spirit::readFile<char>(InputFile);
     91   std::unique_ptr<bcinfo::MetadataExtractor> ME(
     92       new bcinfo::MetadataExtractor(bitcode.data(), bitcode.size()));
     93 
     94   if (!rs2spirv::WriteSPIRV(M.get(), std::move(ME), OFS, Err)) {
     95     errs() << "compiler error: " << Err << '\n';
     96     return -1;
     97   }
     98 
     99   return 0;
    100 }
    101 
    102 int main(int ac, char **av) {
    103   EnablePrettyStackTrace();
    104   sys::PrintStackTraceOnErrorSignal(av[0]);
    105   PrettyStackTraceProgram X(ac, av);
    106 
    107   cl::ParseCommandLineOptions(ac, av, "RenderScript to SPIRV translator");
    108 
    109   return convertLLVMToSPIRV();
    110 }
    111