/*
 * Copyright (C) 2012 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 "ir_builder.h"

#include "base/stringprintf.h"

#include <llvm/Module.h>

namespace art {
namespace compiler_llvm {


//----------------------------------------------------------------------------
// General
//----------------------------------------------------------------------------

IRBuilder::IRBuilder(llvm::LLVMContext& context, llvm::Module& module,
                     IntrinsicHelper& intrinsic_helper)
    : LLVMIRBuilder(context), module_(&module), mdb_(context), java_object_type_(NULL),
      java_method_type_(NULL), java_thread_type_(NULL), intrinsic_helper_(intrinsic_helper) {
  // Get java object type from module
  llvm::Type* jobject_struct_type = module.getTypeByName("JavaObject");
  CHECK(jobject_struct_type != NULL);
  java_object_type_ = jobject_struct_type->getPointerTo();

  // If type of Method is not explicitly defined in the module, use JavaObject*
  llvm::Type* type = module.getTypeByName("Method");
  if (type != NULL) {
    java_method_type_ = type->getPointerTo();
  } else {
    java_method_type_ = java_object_type_;
  }

  // If type of Thread is not explicitly defined in the module, use JavaObject*
  type = module.getTypeByName("Thread");
  if (type != NULL) {
    java_thread_type_ = type->getPointerTo();
  } else {
    java_thread_type_ = java_object_type_;
  }

  // Create JEnv* type
  llvm::Type* jenv_struct_type = llvm::StructType::create(context, "JEnv");
  jenv_type_ = jenv_struct_type->getPointerTo();

  // Get Art shadow frame struct type from module
  art_frame_type_ = module.getTypeByName("ShadowFrame");
  CHECK(art_frame_type_ != NULL);

  runtime_support_ = NULL;
}


//----------------------------------------------------------------------------
// Type Helper Function
//----------------------------------------------------------------------------

llvm::Type* IRBuilder::getJType(JType jty) {
  switch (jty) {
  case kVoid:
    return getJVoidTy();

  case kBoolean:
    return getJBooleanTy();

  case kByte:
    return getJByteTy();

  case kChar:
    return getJCharTy();

  case kShort:
    return getJShortTy();

  case kInt:
    return getJIntTy();

  case kLong:
    return getJLongTy();

  case kFloat:
    return getJFloatTy();

  case kDouble:
    return getJDoubleTy();

  case kObject:
    return getJObjectTy();

  default:
    LOG(FATAL) << "Unknown java type: " << jty;
    return NULL;
  }
}

llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t vreg_size) {
  std::string name(StringPrintf("ShadowFrame%u", vreg_size));

  // Try to find the existing struct type definition
  if (llvm::Type* type = module_->getTypeByName(name)) {
    CHECK(llvm::isa<llvm::StructType>(type));
    return static_cast<llvm::StructType*>(type);
  }

  // Create new struct type definition
  llvm::Type* elem_types[] = {
    art_frame_type_,
    llvm::ArrayType::get(getInt32Ty(), vreg_size),
  };

  return llvm::StructType::create(elem_types, name);
}


} // namespace compiler_llvm
} // namespace art
