/*
 * Copyright 2015, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bcc/Assert.h"
#include "bcc/Renderscript/RSUtils.h"
#include "bcc/Support/Log.h"

#include "rsDefines.h"

#include <llvm/IR/Constant.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/Type.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Function.h>
#include <llvm/Pass.h>

#include <sstream>
#include <vector>

namespace {

const bool kDebugGlobalInfo = false;

/* RSGlobalInfoPass: Embeds additional information about RenderScript global
 * variables into the Module. The 5 variables added are specified as follows:
 * 1) .rs.global_entries
 *    i32 - int
 *    Optional number of global variables.
 * 2) .rs.global_names
 *    [N * i8*] - const char *[N]
 *    Optional global variable name info. Each entry corresponds to the name
 *    of 1 of the N global variables.
 * 3) .rs.global_addresses
 *    [N * i8*] - void*[N] or void**
 *    Optional global variable address info. Each entry corresponds to the
 *    address of 1 of the N global variables.
 * 4) .rs.global_sizes
 *    [N * i32] or [N * i64] - size_t[N]
 *    Optional global variable size info. Each entry corresponds to the size
 *    of 1 of the N global variables.
 * 5) .rs.global_properties
 *    [N * i32]
 *    Optional global properties. Each entry corresponds to the properties
 *    for 1 of the N global variables. The 32-bit integer for properties
 *    can be broken down as follows:
 *    bit(s)    Encoded value
 *    ------    -------------
 *        18    Pointer (1 is pointer, 0 is non-pointer)
 *        17    Static (1 is static, 0 is extern)
 *        16    Constant (1 is const, 0 is non-const)
 *    15 - 0    RsDataType (see frameworks/rs/rsDefines.h for more info)
 */
class RSGlobalInfoPass: public llvm::ModulePass {
private:
  // If true, we don't include information about immutable global variables
  // in our various exported data structures.
  bool mSkipConstants;

  // Encodes properties of the GlobalVariable into a uint32_t.
  // These values are used to populate the .rs.global_properties array.
  static uint32_t getEncodedProperties(const llvm::GlobalVariable &GV) {
    auto GlobalType = GV.getType()->getPointerElementType();

    // We start by getting the RsDataType and placing it into our result.
    uint32_t result = getRsDataTypeForType(GlobalType);
    bccAssert(!(result & ~RS_GLOBAL_TYPE));  // Can only alter lower 16-bits.

    if (GlobalType->isPointerTy()) {
      // Global variables that are pointers can all be used with "bind".
      result |= RS_GLOBAL_POINTER;
    }

    if (GV.isConstant()) {
      result |= RS_GLOBAL_CONSTANT;
    }

    if (GV.getLinkage() == llvm::GlobalValue::InternalLinkage) {
      // We only have internal linkage in RS to signify static.
      result |= RS_GLOBAL_STATIC;
    }

    return result;
  }

public:
  static char ID;

  explicit RSGlobalInfoPass(bool pSkipConstants = false)
    : ModulePass (ID), mSkipConstants(pSkipConstants) {
  }

  void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
    // This pass does not use any other analysis passes, but it does
    // add new global variables.
  }

  bool runOnModule(llvm::Module &M) override {
    std::vector<llvm::Constant *> GVAddresses;
    std::vector<llvm::Constant *> GVNames;
    std::vector<std::string> GVNameStrings;
    std::vector<uint32_t> GVSizes32;
    std::vector<uint64_t> GVSizes64;
    std::vector<uint32_t> GVProperties;

    const llvm::DataLayout &DL = M.getDataLayout();
    const size_t PointerSizeInBits = DL.getPointerSizeInBits();

    bccAssert(PointerSizeInBits == 32 || PointerSizeInBits == 64);

    int GlobalNumber = 0;

    // i8* - LLVM uses this to represent void* and char*
    llvm::Type *VoidPtrTy = llvm::Type::getInt8PtrTy(M.getContext());

    // i32
    llvm::Type *Int32Ty = llvm::Type::getInt32Ty(M.getContext());

    // i32 or i64 depending on our actual size_t
    llvm::Type *SizeTy = llvm::Type::getIntNTy(M.getContext(),
                                               PointerSizeInBits);

    for (auto &GV : M.globals()) {
      // Skip constant variables if we were configured to do so.
      if (mSkipConstants && GV.isConstant()) {
        continue;
      }

      // Skip intrinsic variables.
      if (GV.getName().startswith("llvm.")) {
        continue;
      }

      // In LLVM, an instance of GlobalVariable is actually a Value
      // corresponding to the address of it.
      GVAddresses.push_back(llvm::ConstantExpr::getBitCast(&GV, VoidPtrTy));
      GVNameStrings.push_back(GV.getName());

      // Since these are all global variables, their type is actually a
      // pointer to the underlying data. We can extract the total underlying
      // storage size by looking at the first contained type.
      auto GlobalType = GV.getType()->getPointerElementType();
      auto TypeSize = DL.getTypeAllocSize(GlobalType);
      if (PointerSizeInBits == 32) {
        GVSizes32.push_back(TypeSize);
      } else {
        GVSizes64.push_back(TypeSize);
      }

      GVProperties.push_back(getEncodedProperties(GV));
    }

    // Create the new strings for storing the names of the global variables.
    // This has to be done as a separate pass (over the original global
    // variables), because these strings are new global variables themselves.
    for (const auto &GVN : GVNameStrings) {
      llvm::Constant *C =
          llvm::ConstantDataArray::getString(M.getContext(), GVN);
      std::stringstream VarName;
      VarName << ".rs.name_str_" << GlobalNumber++;
      llvm::Value *V = M.getOrInsertGlobal(VarName.str(), C->getType());
      llvm::GlobalVariable *VarAsStr = llvm::dyn_cast<llvm::GlobalVariable>(V);
      VarAsStr->setInitializer(C);
      VarAsStr->setConstant(true);
      VarAsStr->setLinkage(llvm::GlobalValue::PrivateLinkage);
      VarAsStr->setUnnamedAddr(true);
      // VarAsStr has type [_ x i8]*. Cast to i8* for storing in
      // .rs.global_names.
      GVNames.push_back(llvm::ConstantExpr::getBitCast(VarAsStr, VoidPtrTy));
    }

    if (PointerSizeInBits == 32) {
      bccAssert(GVAddresses.size() == GVSizes32.size());
      bccAssert(GVSizes64.size() == 0);
      bccAssert(GVAddresses.size() == GVProperties.size());
    } else {
      bccAssert(GVSizes32.size() == 0);
      bccAssert(GVAddresses.size() == GVSizes64.size());
      bccAssert(GVAddresses.size() == GVProperties.size());
    }

    size_t NumGlobals = GVAddresses.size();

    // [NumGlobals * i8*]
    llvm::ArrayType *VoidPtrArrayTy = llvm::ArrayType::get(VoidPtrTy,
                                                           NumGlobals);
    // [NumGlobals * i32] or [NumGlobals * i64]
    llvm::ArrayType *SizeArrayTy = llvm::ArrayType::get(SizeTy, NumGlobals);

    // [NumGlobals * i32]
    llvm::ArrayType *Int32ArrayTy = llvm::ArrayType::get(Int32Ty, NumGlobals);

    // 1) @.rs.global_entries = constant i32 NumGlobals
    llvm::Value *V = M.getOrInsertGlobal(kRsGlobalEntries, Int32Ty);
    llvm::GlobalVariable *GlobalEntries =
        llvm::dyn_cast<llvm::GlobalVariable>(V);
    llvm::Constant *GlobalEntriesInit =
        llvm::ConstantInt::get(Int32Ty, NumGlobals);
    GlobalEntries->setInitializer(GlobalEntriesInit);
    GlobalEntries->setConstant(true);

    // 2) @.rs.global_names = constant [N * i8*] [...]
    V = M.getOrInsertGlobal(kRsGlobalNames, VoidPtrArrayTy);
    llvm::GlobalVariable *GlobalNames =
        llvm::dyn_cast<llvm::GlobalVariable>(V);
    llvm::Constant *GlobalNamesInit =
        llvm::ConstantArray::get(VoidPtrArrayTy, GVNames);
    GlobalNames->setInitializer(GlobalNamesInit);
    GlobalNames->setConstant(true);

    // 3) @.rs.global_addresses = constant [N * i8*] [...]
    V = M.getOrInsertGlobal(kRsGlobalAddresses, VoidPtrArrayTy);
    llvm::GlobalVariable *GlobalAddresses =
        llvm::dyn_cast<llvm::GlobalVariable>(V);
    llvm::Constant *GlobalAddressesInit =
        llvm::ConstantArray::get(VoidPtrArrayTy, GVAddresses);
    GlobalAddresses->setInitializer(GlobalAddressesInit);
    GlobalAddresses->setConstant(true);


    // 4) @.rs.global_sizes = constant [N * i32 or i64] [...]
    V = M.getOrInsertGlobal(kRsGlobalSizes, SizeArrayTy);
    llvm::GlobalVariable *GlobalSizes =
        llvm::dyn_cast<llvm::GlobalVariable>(V);
    llvm::Constant *GlobalSizesInit;
    if (PointerSizeInBits == 32) {
      GlobalSizesInit = llvm::ConstantDataArray::get(M.getContext(), GVSizes32);
    } else {
      GlobalSizesInit = llvm::ConstantDataArray::get(M.getContext(), GVSizes64);
    }
    GlobalSizes->setInitializer(GlobalSizesInit);
    GlobalSizes->setConstant(true);

    // 5) @.rs.global_properties = constant i32 NumGlobals
    V = M.getOrInsertGlobal(kRsGlobalProperties, Int32ArrayTy);
    llvm::GlobalVariable *GlobalProperties =
        llvm::dyn_cast<llvm::GlobalVariable>(V);
    llvm::Constant *GlobalPropertiesInit =
        llvm::ConstantDataArray::get(M.getContext(), GVProperties);
    GlobalProperties->setInitializer(GlobalPropertiesInit);
    GlobalProperties->setConstant(true);

    if (kDebugGlobalInfo) {
      GlobalEntries->dump();
      GlobalNames->dump();
      GlobalAddresses->dump();
      GlobalSizes->dump();
      GlobalProperties->dump();
    }

    // Upon completion, this pass has always modified the Module.
    return true;
  }
};

}

char RSGlobalInfoPass::ID = 0;

static llvm::RegisterPass<RSGlobalInfoPass> X("embed-rs-global-info",
  "Embed additional information about RenderScript global variables");

namespace bcc {

llvm::ModulePass * createRSGlobalInfoPass(bool pSkipConstants) {
  return new RSGlobalInfoPass(pSkipConstants);
}

}
