Home | History | Annotate | Download | only in Renderscript
      1 /*
      2  * Copyright 2012, 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 #ifndef BCC_RS_INFO_H
     18 #define BCC_RS_INFO_H
     19 
     20 #include <stdint.h>
     21 
     22 #include <utility>
     23 
     24 #include "bcc/Support/Log.h"
     25 #include "bcc/Support/Sha1Util.h"
     26 
     27 #include <utils/String8.h>
     28 #include <utils/Vector.h>
     29 
     30 namespace llvm {
     31 class Module;
     32 }
     33 
     34 namespace bcc {
     35 
     36 // Forward declarations
     37 class FileBase;
     38 class InputFile;
     39 class OutputFile;
     40 class Source;
     41 class RSScript;
     42 
     43 typedef llvm::Module* (*RSLinkRuntimeCallback) (bcc::RSScript *, llvm::Module *, llvm::Module *);
     44 
     45 namespace rsinfo {
     46 
     47 /* RS info file magic */
     48 #define RSINFO_MAGIC      "\0rsinfo\n"
     49 
     50 /* RS info file version, encoded in 4 bytes of ASCII */
     51 #define RSINFO_VERSION    "004\0"
     52 
     53 struct __attribute__((packed)) ListHeader {
     54   // The offset from the beginning of the file of data
     55   uint32_t offset;
     56   // Number of item in the list
     57   uint32_t count;
     58   // Size of each item
     59   uint8_t itemSize;
     60 };
     61 
     62 /* RS info file header */
     63 struct __attribute__((packed)) Header {
     64   // Magic versus version
     65   uint8_t magic[8];
     66   uint8_t version[4];
     67 
     68   uint8_t isThreadable;
     69   uint8_t hasDebugInformation;
     70 
     71   uint16_t headerSize;
     72 
     73   uint32_t strPoolSize;
     74 
     75   struct ListHeader dependencyTable;
     76   struct ListHeader pragmaList;
     77   struct ListHeader objectSlotList;
     78   struct ListHeader exportVarNameList;
     79   struct ListHeader exportFuncNameList;
     80   struct ListHeader exportForeachFuncList;
     81 };
     82 
     83 typedef uint32_t StringIndexTy;
     84 // Use value -1 as an invalid string index marker. No need to declare with
     85 // 'static' modifier since 'const' variable has internal linkage by default.
     86 const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1);
     87 
     88 struct __attribute__((packed)) DependencyTableItem {
     89   StringIndexTy id;
     90   // SHA-1 checksum is stored as a string in string pool (and has fixed-length
     91   // SHA1_DIGEST_LENGTH (=20) bytes)
     92   StringIndexTy sha1;
     93 };
     94 
     95 struct __attribute__((packed)) PragmaItem {
     96   // Pragma is a key-value pair.
     97   StringIndexTy key;
     98   StringIndexTy value;
     99 };
    100 
    101 struct __attribute__((packed)) ObjectSlotItem {
    102   uint32_t slot;
    103 };
    104 
    105 struct __attribute__((packed)) ExportVarNameItem {
    106   StringIndexTy name;
    107 };
    108 
    109 struct __attribute__((packed)) ExportFuncNameItem {
    110   StringIndexTy name;
    111 };
    112 
    113 struct __attribute__((packed)) ExportForeachFuncItem {
    114   StringIndexTy name;
    115   uint32_t signature;
    116 };
    117 
    118 // Return the human-readable name of the given rsinfo::*Item in the template
    119 // parameter. This is for debugging and error message.
    120 template<typename Item>
    121 inline const char *GetItemTypeName();
    122 
    123 template<>
    124 inline const char *GetItemTypeName<DependencyTableItem>()
    125 { return "rs dependency info"; }
    126 
    127 template<>
    128 inline const char *GetItemTypeName<PragmaItem>()
    129 {  return "rs pragma"; }
    130 
    131 template<>
    132 inline const char *GetItemTypeName<ObjectSlotItem>()
    133 {  return "rs object slot"; }
    134 
    135 template<>
    136 inline const char *GetItemTypeName<ExportVarNameItem>()
    137 { return "rs export var"; }
    138 
    139 template<>
    140 inline const char *GetItemTypeName<ExportFuncNameItem>()
    141 {  return "rs export func"; }
    142 
    143 template<>
    144 inline const char *GetItemTypeName<ExportForeachFuncItem>()
    145 { return "rs export foreach"; }
    146 
    147 } // end namespace rsinfo
    148 
    149 class RSInfo {
    150 public:
    151   typedef android::Vector<std::pair<const char *,
    152                                     const uint8_t *> > DependencyTableTy;
    153   typedef android::Vector<std::pair<const char*, const char*> > PragmaListTy;
    154   typedef android::Vector<uint32_t> ObjectSlotListTy;
    155   typedef android::Vector<const char *> ExportVarNameListTy;
    156   typedef android::Vector<const char *> ExportFuncNameListTy;
    157   typedef android::Vector<std::pair<const char *,
    158                                     uint32_t> > ExportForeachFuncListTy;
    159 
    160 public:
    161   // Calculate or load the SHA-1 information of the built-in dependencies.
    162   static bool LoadBuiltInSHA1Information();
    163 
    164   // Return the path of the RS info file corresponded to the given output
    165   // executable file.
    166   static android::String8 GetPath(const char *pFilename);
    167 
    168   static const char LibBCCPath[];
    169   static const char LibCompilerRTPath[];
    170   static const char LibRSPath[];
    171   static const char LibCLCorePath[];
    172   static const char LibCLCoreDebugPath[];
    173 #if defined(ARCH_X86_HAVE_SSE2)
    174   static const char LibCLCoreX86Path[];
    175 #endif
    176 #if defined(ARCH_ARM_HAVE_NEON)
    177   static const char LibCLCoreNEONPath[];
    178 #endif
    179 
    180 private:
    181   // SHA-1 of the built-in dependencies. Will be initialized in
    182   // LoadBuiltInSHA1Information().
    183   static const uint8_t *LibBCCSHA1;
    184   static const uint8_t *LibCompilerRTSHA1;
    185   static const uint8_t *LibRSSHA1;
    186   static const uint8_t *LibCLCoreSHA1;
    187   static const uint8_t *LibCLCoreDebugSHA1;
    188 #if defined(ARCH_ARM_HAVE_NEON)
    189   static const uint8_t *LibCLCoreNEONSHA1;
    190 #endif
    191 
    192   static bool CheckDependency(const RSInfo &pInfo,
    193                               const char *pInputFilename,
    194                               const DependencyTableTy &pDeps);
    195   static bool AddBuiltInDependencies(RSInfo &pInfo);
    196 
    197   rsinfo::Header mHeader;
    198 
    199   char *mStringPool;
    200 
    201   // In most of the time, there're 4 source dependencies stored (libbcc.so,
    202   // libRS.so, libclcore and the input bitcode itself.)
    203   DependencyTableTy mDependencyTable;
    204   PragmaListTy mPragmas;
    205   ObjectSlotListTy mObjectSlots;
    206   ExportVarNameListTy mExportVarNames;
    207   ExportFuncNameListTy mExportFuncNames;
    208   ExportForeachFuncListTy mExportForeachFuncs;
    209 
    210   // Initialize an empty RSInfo with its size of string pool is pStringPoolSize.
    211   RSInfo(size_t pStringPoolSize);
    212 
    213   // layout() assigns value of offset in each ListHeader (i.e., it decides where
    214   // data should go in the file.) It also updates fields other than offset to
    215   // reflect the current RSInfo object states to mHeader.
    216   bool layout(off_t initial_offset);
    217 
    218 public:
    219   ~RSInfo();
    220 
    221   // Implemented in RSInfoExtractor.cpp.
    222   static RSInfo *ExtractFromSource(const Source &pSource,
    223                                    const DependencyTableTy &pDeps);
    224 
    225   // Implemented in RSInfoReader.cpp.
    226   static RSInfo *ReadFromFile(InputFile &pInput,
    227                               const DependencyTableTy &pDeps);
    228 
    229   // Implemneted in RSInfoWriter.cpp
    230   bool write(OutputFile &pOutput);
    231 
    232   void dump() const;
    233 
    234   // const getter
    235   inline bool isThreadable() const
    236   { return mHeader.isThreadable; }
    237   inline bool hasDebugInformation() const
    238   { return mHeader.hasDebugInformation; }
    239   inline const DependencyTableTy &getDependencyTable() const
    240   { return mDependencyTable; }
    241   inline const PragmaListTy &getPragmas() const
    242   { return mPragmas; }
    243   inline const ObjectSlotListTy &getObjectSlots() const
    244   { return mObjectSlots; }
    245   inline const ExportVarNameListTy &getExportVarNames() const
    246   { return mExportVarNames; }
    247   inline const ExportFuncNameListTy &getExportFuncNames() const
    248   { return mExportFuncNames; }
    249   inline const ExportForeachFuncListTy &getExportForeachFuncs() const
    250   { return mExportForeachFuncs; }
    251 
    252   const char *getStringFromPool(rsinfo::StringIndexTy pStrIdx) const;
    253   rsinfo::StringIndexTy getStringIdxInPool(const char *pStr) const;
    254 
    255   // setter
    256   inline void setThreadable(bool pThreadable = true)
    257   { mHeader.isThreadable = pThreadable; }
    258 
    259 public:
    260   enum FloatPrecision {
    261     FP_Full,
    262     FP_Relaxed,
    263     FP_Imprecise,
    264   };
    265 
    266   // Return the minimal floating point precision required for the associated
    267   // script.
    268   FloatPrecision getFloatPrecisionRequirement() const;
    269 };
    270 
    271 } // end namespace bcc
    272 
    273 #endif  // BCC_RS_INFO_H
    274