/*
 * 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/Renderscript/RSTransforms.h"
#include "bcc/Support/Log.h"

#include <cstdlib>

#include <llvm/IR/Instructions.h>
#include <llvm/IR/Metadata.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Function.h>
#include <llvm/Pass.h>

namespace { // anonymous namespace

// Create a Module pass that screens all the global functions in the module and
// check if any non-threadable function is callable.  If so, we mark the
// Module as non-threadable by adding a metadata flag '#rs_is_threadable'

class RSIsThreadablePass : public llvm::ModulePass {
private:
  static char ID;

  std::vector<std::string> nonThreadableFns = {
    "_Z22rsgBindProgramFragment19rs_program_fragment",
    "_Z19rsgBindProgramStore16rs_program_store",
    "_Z20rsgBindProgramVertex17rs_program_vertex",
    "_Z20rsgBindProgramRaster17rs_program_raster",
    "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler",
    "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation",
    "_Z15rsgBindConstant19rs_program_fragmentj13rs_allocation",
    "_Z15rsgBindConstant17rs_program_vertexj13rs_allocation",
    "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4",
    "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4",
    "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4",
    "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4",
    "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff",
    "_Z11rsgGetWidthv",
    "_Z12rsgGetHeightv",
    "_Z11rsgDrawRectfffff",
    "_Z11rsgDrawQuadffffffffffff",
    "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff",
    "_Z24rsgDrawSpriteScreenspacefffff",
    "_Z11rsgDrawMesh7rs_mesh",
    "_Z11rsgDrawMesh7rs_meshj",
    "_Z11rsgDrawMesh7rs_meshjjj",
    "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_",
    "_Z11rsgDrawPath7rs_path",
    "_Z13rsgClearColorffff",
    "_Z13rsgClearDepthf",
    "_Z11rsgDrawTextPKcii",
    "_Z11rsgDrawText13rs_allocationii",
    "_Z14rsgMeasureTextPKcPiS1_S1_S1_",
    "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_",
    "_Z11rsgBindFont7rs_font",
    "_Z12rsgFontColorffff",
    "_Z18rsgBindColorTarget13rs_allocationj",
    "_Z18rsgBindDepthTarget13rs_allocation",
    "_Z19rsgClearColorTargetj",
    "_Z19rsgClearDepthTargetv",
    "_Z24rsgClearAllRenderTargetsv",
    "_Z7rsGetDtv",
    "_Z5colorffff",
    "_Z9rsgFinishv",
  };

  bool isPresent(std::vector<std::string> &list, std::string name) {
    auto lower = std::lower_bound(list.begin(),
                                  list.end(),
                                  name);

    if (lower != list.end() && name.compare(*lower) == 0)
      return true;
    return false;
  }

public:
  RSIsThreadablePass()
    : ModulePass (ID) {
      std::sort(nonThreadableFns.begin(), nonThreadableFns.end());
  }

  virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
    AU.setPreservesAll();
  }

  bool runOnModule(llvm::Module &M) override {
    bool threadable = true;

    auto &FunctionList(M.getFunctionList());
    for (auto &F: FunctionList) {
      if (isPresent(nonThreadableFns, F.getName().str())) {
        threadable = false;
        break;
      }
    }

    llvm::LLVMContext &context = M.getContext();
    llvm::MDString *val =
      llvm::MDString::get(context, (threadable) ? "yes" : "no");
    llvm::NamedMDNode *node =
        M.getOrInsertNamedMetadata("#rs_is_threadable");
    node->addOperand(llvm::MDNode::get(context, val));

    return false;
  }

};

}

char RSIsThreadablePass::ID = 0;

namespace bcc {

llvm::ModulePass *
createRSIsThreadablePass () {
  return new RSIsThreadablePass();
}

}
