166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang/* 266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * Copyright 2010, The Android Open Source Project 366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * 466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * you may not use this file except in compliance with the License. 666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * You may obtain a copy of the License at 766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * 866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * 1066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * Unless required by applicable law or agreed to in writing, software 1166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 1266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * See the License for the specific language governing permissions and 1466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang * limitations under the License. 1566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang */ 1666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 1766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#include "slang_rs_metadata_spec.h" 1866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <cstdlib> 2066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#include <list> 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <map> 2266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#include <string> 2366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 2466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#include "llvm/ADT/SmallVector.h" 2566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#include "llvm/ADT/StringRef.h" 2666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Metadata.h" 28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Module.h" 29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 306e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 3166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#include "slang_rs_type_spec.h" 3266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 3366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#define RS_METADATA_STRTAB_MN "#rs_metadata_strtab" 3466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#define RS_TYPE_INFO_MN "#rs_type_info" 3566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#define RS_EXPORT_VAR_MN "#rs_export_var" 3666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#define RS_EXPORT_FUNC_MN "#rs_export_func" 3766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#define RS_EXPORT_RECORD_TYPE_NAME_MN_PREFIX "%" 3866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 3966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang/////////////////////////////////////////////////////////////////////////////// 4066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang// Useful utility functions 4166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang/////////////////////////////////////////////////////////////////////////////// 4266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changstatic bool EncodeInteger(llvm::LLVMContext &C, 4366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned I, 4466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::SmallVectorImpl<llvm::Value*> &Op) { 4566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::StringRef S(reinterpret_cast<const char*>(&I), sizeof(I)); 4666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::MDString *MDS = llvm::MDString::get(C, S); 4766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 4866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (MDS == NULL) 4966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return false; 5066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang Op.push_back(MDS); 5166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return true; 5266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 5366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 5466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang/////////////////////////////////////////////////////////////////////////////// 5566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang// class RSMetadataEncoderInternal 5666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang/////////////////////////////////////////////////////////////////////////////// 5766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changnamespace { 5866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 5966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changclass RSMetadataEncoderInternal { 6066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang private: 6166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::Module *mModule; 6266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 6366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang typedef std::map</* key */unsigned, unsigned/* index */> TypesMapTy; 6466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang TypesMapTy mTypes; 6566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang std::list<unsigned> mEncodedRSTypeInfo; // simply a sequece of integers 6666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned mCurTypeIndex; 6766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 6866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // A special type for lookup created record type. It uses record name as key. 6966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang typedef std::map</* name */std::string, unsigned/* index */> RecordTypesMapTy; 7066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RecordTypesMapTy mRecordTypes; 7166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 7266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang typedef std::map<std::string, unsigned/* index */> StringsMapTy; 7366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StringsMapTy mStrings; 7466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang std::list<const char*> mEncodedStrings; 7566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned mCurStringIndex; 7666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 7766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::NamedMDNode *mVarInfoMetadata; 7866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::NamedMDNode *mFuncInfoMetadata; 7966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 8066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // This function check the return value of function: 8166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // joinString, encodeTypeBase, encode*Type(), encodeRSType, encodeRSVar, 8266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // and encodeRSFunc. Return false if the value of Index indicates failure. 83e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines inline bool checkReturnIndex(unsigned *Index) { 84e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (*Index == 0) 8566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return false; 8666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang else 87e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines (*Index)--; 8866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return true; 8966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang } 9066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 9166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned joinString(const std::string &S); 9266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 9366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned encodeTypeBase(const struct RSTypeBase *Base); 9466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned encodeTypeBaseAsKey(const struct RSTypeBase *Base); 9566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#define ENUM_RS_DATA_TYPE_CLASS(x) \ 9666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned encode ## x ## Type(const union RSType *T); 9766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr ChangRS_DATA_TYPE_CLASS_ENUMS 9866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#undef ENUM_RS_DATA_TYPE_CLASS 9966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 10066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned encodeRSType(const union RSType *T); 10166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 10266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang int flushStringTable(); 10366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang int flushTypeInfo(); 10466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 10566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang public: 106e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines explicit RSMetadataEncoderInternal(llvm::Module *M); 10766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 10866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang int encodeRSVar(const RSVar *V); 10966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang int encodeRSFunc(const RSFunction *F); 11066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 11166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang int finalize(); 11266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang}; 113e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines 114e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines} // namespace 11566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 11666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr ChangRSMetadataEncoderInternal::RSMetadataEncoderInternal(llvm::Module *M) 11766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang : mModule(M), 11866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mCurTypeIndex(0), 11966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mCurStringIndex(0), 12066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mVarInfoMetadata(NULL), 12166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mFuncInfoMetadata(NULL) { 12266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mTypes.clear(); 12366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mEncodedRSTypeInfo.clear(); 12466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mRecordTypes.clear(); 12566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mStrings.clear(); 12666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 12766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return; 12866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 12966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 13066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang// Return (StringIndex + 1) when successfully join the string and 0 if there's 13166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang// any error. 13266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned RSMetadataEncoderInternal::joinString(const std::string &S) { 13366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StringsMapTy::const_iterator I = mStrings.find(S); 13466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 13566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (I != mStrings.end()) 13666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return (I->second + 1); 13766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 13866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Add S into mStrings 13966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang std::pair<StringsMapTy::iterator, bool> Res = 14066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mStrings.insert(std::make_pair(S, mCurStringIndex)); 14166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Insertion failed 14266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (!Res.second) 14366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 14466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 14566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Add S into mEncodedStrings 14666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mEncodedStrings.push_back(Res.first->first.c_str()); 14766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mCurStringIndex++; 14866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 14966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Return (StringIndex + 1) 15066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return (Res.first->second + 1); 15166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 15266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 15366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned 15466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr ChangRSMetadataEncoderInternal::encodeTypeBase(const struct RSTypeBase *Base) { 15566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mEncodedRSTypeInfo.push_back(Base->bits); 15666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return ++mCurTypeIndex; 15766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 15866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 15966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned RSMetadataEncoderInternal::encodeTypeBaseAsKey( 16066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang const struct RSTypeBase *Base) { 16166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang TypesMapTy::const_iterator I = mTypes.find(Base->bits); 16266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (I != mTypes.end()) 16366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return (I->second + 1); 16466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 16566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Add Base into mTypes 16666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang std::pair<TypesMapTy::iterator, bool> Res = 16766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mTypes.insert(std::make_pair(Base->bits, mCurTypeIndex)); 16866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Insertion failed 16966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (!Res.second) 17066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 17166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 17266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Push to mEncodedRSTypeInfo. This will also update mCurTypeIndex. 17366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return encodeTypeBase(Base); 17466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 17566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 17666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned RSMetadataEncoderInternal::encodePrimitiveType(const union RSType *T) { 17766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return encodeTypeBaseAsKey(RS_GET_TYPE_BASE(T)); 17866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 17966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 18066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned RSMetadataEncoderInternal::encodePointerType(const union RSType *T) { 18166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Encode pointee type first 18266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned PointeeType = encodeRSType(RS_POINTER_TYPE_GET_POINTEE_TYPE(T)); 183e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (!checkReturnIndex(&PointeeType)) 18466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 18566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 18666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned Res = encodeTypeBaseAsKey(RS_GET_TYPE_BASE(T)); 18766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Push PointeeType after the base type 18866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mEncodedRSTypeInfo.push_back(PointeeType); 18966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return Res; 19066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 19166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 19266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned RSMetadataEncoderInternal::encodeVectorType(const union RSType *T) { 19366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return encodeTypeBaseAsKey(RS_GET_TYPE_BASE(T)); 19466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 19566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 19666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned RSMetadataEncoderInternal::encodeMatrixType(const union RSType *T) { 19766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return encodeTypeBaseAsKey(RS_GET_TYPE_BASE(T)); 19866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 19966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 20066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned 20166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr ChangRSMetadataEncoderInternal::encodeConstantArrayType(const union RSType *T) { 20266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Encode element type 20366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned ElementType = 20466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang encodeRSType(RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(T)); 205e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (!checkReturnIndex(&ElementType)) 20666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 20766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 20866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned Res = encodeTypeBase(RS_GET_TYPE_BASE(T)); 20966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Push the ElementType after the type base 21066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mEncodedRSTypeInfo.push_back(ElementType); 21166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return Res; 21266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 21366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 21466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned RSMetadataEncoderInternal::encodeRecordType(const union RSType *T) { 21566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Construct record name 21666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang std::string RecordInfoMetadataName(RS_EXPORT_RECORD_TYPE_NAME_MN_PREFIX); 21766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RecordInfoMetadataName.append(RS_RECORD_TYPE_GET_NAME(T)); 21866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 21966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Try to find it in mRecordTypes 22066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RecordTypesMapTy::const_iterator I = 22166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mRecordTypes.find(RecordInfoMetadataName); 22266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 22366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // This record type has been encoded before. Fast return its index here. 22466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (I != mRecordTypes.end()) 22566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return (I->second + 1); 22666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 22766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Encode this record type into mTypes. Encode record name string first. 22866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned RecordName = joinString(RecordInfoMetadataName); 229e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (!checkReturnIndex(&RecordName)) 23066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 23166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 23266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned Base = encodeTypeBase(RS_GET_TYPE_BASE(T)); 233e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (!checkReturnIndex(&Base)) 23466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 23566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 23666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Push record name after encoding the type base 23766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mEncodedRSTypeInfo.push_back(RecordName); 23866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 23966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Add this record type into the map 24066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang std::pair<StringsMapTy::iterator, bool> Res = 24166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mRecordTypes.insert(std::make_pair(RecordInfoMetadataName, Base)); 24266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Insertion failed 24366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (!Res.second) 24466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 24566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 24666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Create a named MDNode for this record type. We cannot create this before 24766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // encoding type base into Types and updating mRecordTypes. This is because 24866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // we may have structure like: 24966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // 25066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // struct foo { 25166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // ... 25266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // struct foo *bar; // self type reference 25366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // ... 25466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // } 25566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::NamedMDNode *RecordInfoMetadata = 25666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mModule->getOrInsertNamedMetadata(RecordInfoMetadataName); 25766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 2586e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RecordInfoMetadata->getNumOperands() == 0) && 2596e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Record created before!"); 26066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 26166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Encode field info into this named MDNode 26266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::SmallVector<llvm::Value*, 3> FieldInfo; 26366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 26466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang for (unsigned i = 0; i < RS_RECORD_TYPE_GET_NUM_FIELDS(T); i++) { 26566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // 1. field name 26666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned FieldName = joinString(RS_RECORD_TYPE_GET_FIELD_NAME(T, i)); 267e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (!checkReturnIndex(&FieldName)) 26866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 26966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (!EncodeInteger(mModule->getContext(), 27066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang FieldName, 27183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao FieldInfo)) { 27266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 27383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 27466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 27566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // 2. field type 27666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned FieldType = encodeRSType(RS_RECORD_TYPE_GET_FIELD_TYPE(T, i)); 277e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (!checkReturnIndex(&FieldType)) 27866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 27966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (!EncodeInteger(mModule->getContext(), 28066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang FieldType, 28183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao FieldInfo)) { 28266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 28383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 28466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 28566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RecordInfoMetadata->addOperand(llvm::MDNode::get(mModule->getContext(), 28618c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines FieldInfo)); 28766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang FieldInfo.clear(); 28866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang } 28966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 29066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return (Res.first->second + 1); 29166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 29266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 29366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changunsigned RSMetadataEncoderInternal::encodeRSType(const union RSType *T) { 29466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang switch (static_cast<enum RSTypeClass>(RS_TYPE_GET_CLASS(T))) { 29566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#define ENUM_RS_DATA_TYPE_CLASS(x) \ 29666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang case RS_TC_ ## x: return encode ## x ## Type(T); 29766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RS_DATA_TYPE_CLASS_ENUMS 29866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang#undef ENUM_RS_DATA_TYPE_CLASS 29966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang default: return 0; 30066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang } 30166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 30266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 30366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 30466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changint RSMetadataEncoderInternal::encodeRSVar(const RSVar *V) { 30566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // check parameter 30666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if ((V == NULL) || (V->name == NULL) || (V->type == NULL)) 30766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -1; 30866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 30966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // 1. var name 31066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned VarName = joinString(V->name); 31183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!checkReturnIndex(&VarName)) { 31266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -2; 31383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 31466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 31566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // 2. type 31666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned Type = encodeRSType(V->type); 31766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 31866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::SmallVector<llvm::Value*, 1> VarInfo; 31966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 32083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!EncodeInteger(mModule->getContext(), VarName, VarInfo)) { 32166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -3; 32283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 32383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!EncodeInteger(mModule->getContext(), Type, VarInfo)) { 32466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -4; 32583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 32666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 32766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (mVarInfoMetadata == NULL) 32866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mVarInfoMetadata = mModule->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN); 32966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 33066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mVarInfoMetadata->addOperand(llvm::MDNode::get(mModule->getContext(), 33118c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines VarInfo)); 33266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 33366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 33466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 33566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 33666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changint RSMetadataEncoderInternal::encodeRSFunc(const RSFunction *F) { 33766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // check parameter 33883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if ((F == NULL) || (F->name == NULL)) { 33966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -1; 34083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 34166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 34266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // 1. var name 34366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned FuncName = joinString(F->name); 34483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!checkReturnIndex(&FuncName)) { 34566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -2; 34683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 34766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 34866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::SmallVector<llvm::Value*, 1> FuncInfo; 34983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!EncodeInteger(mModule->getContext(), FuncName, FuncInfo)) { 35066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -3; 35183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 35266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 35366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (mFuncInfoMetadata == NULL) 35466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mFuncInfoMetadata = mModule->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN); 35566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 35666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mFuncInfoMetadata->addOperand(llvm::MDNode::get(mModule->getContext(), 35718c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines FuncInfo)); 35866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 35966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 36066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 36166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 36266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang// Write string table and string index table 36366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changint RSMetadataEncoderInternal::flushStringTable() { 3646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((mCurStringIndex == mEncodedStrings.size())); 3656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((mCurStringIndex == mStrings.size())); 36666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 36766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (mCurStringIndex == 0) 36866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 36966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 37066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Prepare named MDNode for string table and string index table. 37166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::NamedMDNode *RSMetadataStrTab = 37266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mModule->getOrInsertNamedMetadata(RS_METADATA_STRTAB_MN); 37366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RSMetadataStrTab->dropAllReferences(); 37466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 37566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned StrTabSize = 0; 37666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned *StrIdx = reinterpret_cast<unsigned*>( 37766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang ::malloc((mStrings.size() + 1) * sizeof(unsigned))); 37866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 37966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (StrIdx == NULL) 38066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -1; 38166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 38266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned StrIdxI = 0; // iterator for array StrIdx 38366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 38466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // count StrTabSize and fill StrIdx by the way 38566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang for (std::list<const char*>::const_iterator I = mEncodedStrings.begin(), 38666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang E = mEncodedStrings.end(); 38766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang I != E; 38866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang I++) { 38966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StrIdx[StrIdxI++] = StrTabSize; 39066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StrTabSize += ::strlen(*I) + 1 /* for '\0' */; 39166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang } 39266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StrIdx[StrIdxI] = StrTabSize; 39366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 39466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Allocate 39566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang char *StrTab = reinterpret_cast<char*>(::malloc(StrTabSize)); 39666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (StrTab == NULL) { 39766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang free(StrIdx); 39866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -1; 39966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang } 40066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 40166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::StringRef StrTabData(StrTab, StrTabSize); 40266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::StringRef StrIdxData(reinterpret_cast<const char*>(StrIdx), 40366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mStrings.size() * sizeof(unsigned)); 40466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 40566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Copy 40666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StrIdxI = 1; 40766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang for (std::list<const char*>::const_iterator I = mEncodedStrings.begin(), 40866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang E = mEncodedStrings.end(); 40966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang I != E; 41066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang I++) { 41166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Get string length from StrIdx (O(1)) instead of call strlen again (O(n)). 41266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned CurStrLength = StrIdx[StrIdxI] - StrIdx[StrIdxI - 1]; 41366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang ::memcpy(StrTab, *I, CurStrLength); 41466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Move forward the pointer 41566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StrTab += CurStrLength; 41666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StrIdxI++; 41766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang } 41866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 41966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang // Flush to metadata 42066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::Value *StrTabMDS = 42166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::MDString::get(mModule->getContext(), StrTabData); 42266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::Value *StrIdxMDS = 42366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::MDString::get(mModule->getContext(), StrIdxData); 42466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 42566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if ((StrTabMDS == NULL) || (StrIdxMDS == NULL)) { 42666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang free(StrIdx); 42766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang free(StrTab); 42866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -1; 42966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang } 43066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 43166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::SmallVector<llvm::Value*, 2> StrTabVal; 43266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StrTabVal.push_back(StrTabMDS); 43366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang StrTabVal.push_back(StrIdxMDS); 43466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RSMetadataStrTab->addOperand(llvm::MDNode::get(mModule->getContext(), 43518c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines StrTabVal)); 43666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 43766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 43866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 43966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 44066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang// Write RS type stream 44166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changint RSMetadataEncoderInternal::flushTypeInfo() { 44266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned TypeInfoCount = mEncodedRSTypeInfo.size(); 44383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (TypeInfoCount <= 0) { 44466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 44583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 44666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 44766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::NamedMDNode *RSTypeInfo = 44866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang mModule->getOrInsertNamedMetadata(RS_TYPE_INFO_MN); 44966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RSTypeInfo->dropAllReferences(); 45066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 45166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned *TypeInfos = 45266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang reinterpret_cast<unsigned*>(::malloc(TypeInfoCount * sizeof(unsigned))); 45366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang unsigned TypeInfosIdx = 0; // iterator for array TypeInfos 45466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 45566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (TypeInfos == NULL) 45666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -1; 45766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 45866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang for (std::list<unsigned>::const_iterator I = mEncodedRSTypeInfo.begin(), 45966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang E = mEncodedRSTypeInfo.end(); 46066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang I != E; 46166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang I++) 46266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang TypeInfos[TypeInfosIdx++] = *I; 46366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 46466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::StringRef TypeInfoData(reinterpret_cast<const char*>(TypeInfos), 46566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang TypeInfoCount * sizeof(unsigned)); 46666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::Value *TypeInfoMDS = 46766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang llvm::MDString::get(mModule->getContext(), TypeInfoData); 46866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (TypeInfoMDS == NULL) { 46966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang free(TypeInfos); 47066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return -1; 47166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang } 47266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 47383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao llvm::SmallVector<llvm::Value*, 1> TypeInfo; 47483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao TypeInfo.push_back(TypeInfoMDS); 47583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 47666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RSTypeInfo->addOperand(llvm::MDNode::get(mModule->getContext(), 47718c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines TypeInfo)); 47866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang free(TypeInfos); 47966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 48066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 48166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 48266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 48366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changint RSMetadataEncoderInternal::finalize() { 48466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang int Res = flushStringTable(); 48566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (Res != 0) 48666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return Res; 48766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 48866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang Res = flushTypeInfo(); 48966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang if (Res != 0) 49066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return Res; 49166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 49266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return 0; 49366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 49466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 49566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang/////////////////////////////////////////////////////////////////////////////// 49666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang// APIs 49766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang/////////////////////////////////////////////////////////////////////////////// 49866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr ChangRSMetadataEncoder *CreateRSMetadataEncoder(llvm::Module *M) { 49966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return reinterpret_cast<RSMetadataEncoder*>(new RSMetadataEncoderInternal(M)); 50066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 50166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 50266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changint RSEncodeVarMetadata(RSMetadataEncoder *E, const RSVar *V) { 50366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return reinterpret_cast<RSMetadataEncoderInternal*>(E)->encodeRSVar(V); 50466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 50566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 50666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changint RSEncodeFunctionMetadata(RSMetadataEncoder *E, const RSFunction *F) { 50766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return reinterpret_cast<RSMetadataEncoderInternal*>(E)->encodeRSFunc(F); 50866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 50966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 51066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changvoid DestroyRSMetadataEncoder(RSMetadataEncoder *E) { 51166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RSMetadataEncoderInternal *C = 51266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang reinterpret_cast<RSMetadataEncoderInternal*>(E); 51366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang delete C; 51466a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return; 51566a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 51666a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang 51766a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Changint FinalizeRSMetadataEncoder(RSMetadataEncoder *E) { 51866a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang RSMetadataEncoderInternal *C = 51966a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang reinterpret_cast<RSMetadataEncoderInternal*>(E); 52066a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang int Res = C->finalize(); 52166a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang DestroyRSMetadataEncoder(E); 52266a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang return Res; 52366a1a5abf5f2f771d33d6b70a84a1efd7fb22f23Zonr Chang} 524