// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

#ifndef IMPALA_CODEGEN_CODEGEN_UTIL_H
#define IMPALA_CODEGEN_CODEGEN_UTIL_H

#include <vector>
#include <llvm/IR/IRBuilder.h>

#include "codegen/llvm-codegen.h"

namespace impala {

/// Miscellaneous codegen utility functions that don't depend on the rest of the Impala
/// codegen infrastructure.
class CodeGenUtil {
 public:
  /// Wrapper around IRBuilder::CreateCall() that automatically bitcasts arguments
  /// using CheckedBitCast(). This should be used instead of IRBuilder::CreateCall()
  /// when calling functions from a linked module because the LLVM linker may merge
  /// different struct types with the same memory layout during linking. E.g. if the
  /// IR UDF module has type TinyIntVal that has the same memory layout as BooleanVal:
  /// {i8, i8}, then the linker may substitute references to TinyIntVal with BooleanVal
  /// in the IR UDF. Calling a function which has a BooleanVal* argument with a TinyInt*
  /// argument without bitcasting then would result in hitting an internal LLVM assertion.
  static llvm::CallInst* CreateCallWithBitCasts(LlvmBuilder* builder,
      llvm::Function* callee, llvm::ArrayRef<llvm::Value*> args,
      const llvm::Twine& name="");

  /// Same as IRBuilder::CreateBitCast() except that it checks that the types are either
  /// exactly the same, or, if they are both struct types (or pointers to struct types),
  /// that they are structurally identical. Either returns 'value' if no conversion is
  /// necessary, or returns a bitcast instruction converting 'value' to 'dst_type'.
  static llvm::Value* CheckedBitCast(LlvmBuilder* builder,
      llvm::Value* value, llvm::Type* dst_type, const llvm::Twine& name);

  /// Return true if the two types are structurally identical.
  static bool TypesAreStructurallyIdentical(llvm::Type *t1, llvm::Type *t2);

  /// Returns the string representation of a llvm::Value* or llvm::Type*
  template <typename T> static std::string Print(T* value_or_type) {
    std::string str;
    llvm::raw_string_ostream stream(str);
    value_or_type->print(stream);
    return str;
  }

};
}

#endif
