Files
paddlepaddle--paddle/paddle/cinn/backends/llvm/llvm_util.cc
T
2026-07-13 12:40:42 +08:00

168 lines
5.0 KiB
C++

// Copyright (c) 2021 CINN Authors. All Rights Reserved.
//
// 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 "paddle/cinn/backends/llvm/llvm_util.h"
#include <glog/logging.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/Support/Alignment.h>
#include <atomic>
#include <mutex> //NOLINT
namespace cinn {
namespace backends {
using cinn::common::bfloat16;
using cinn::common::float16;
using cinn::common::float8e4m3;
llvm::Type *CinnTypeToLLVMType(cinn::common::Type type,
llvm::Module *m,
bool is_vec) {
llvm::Type *ir_type = nullptr;
if (type.is_cpp_const()) {
// TODO(fc500110) support it latter.
}
llvm::Type *v = llvm::Type::getVoidTy(m->getContext());
llvm::Type *i1 = llvm::Type::getInt1Ty(m->getContext());
llvm::Type *i8 = llvm::Type::getInt8Ty(m->getContext());
llvm::Type *i16 = llvm::Type::getInt16Ty(m->getContext());
llvm::Type *i32 = llvm::Type::getInt32Ty(m->getContext());
llvm::Type *i64 = llvm::Type::getInt64Ty(m->getContext());
llvm::Type *u8 = llvm::Type::getInt8Ty(m->getContext());
llvm::Type *u16 = llvm::Type::getInt16Ty(m->getContext());
llvm::Type *u32 = llvm::Type::getInt32Ty(m->getContext());
llvm::Type *u64 = llvm::Type::getInt64Ty(m->getContext());
llvm::Type *bf16 = llvm::Type::getBFloatTy(m->getContext());
llvm::Type *f16 = llvm::Type::getHalfTy(m->getContext());
llvm::Type *f32 = llvm::Type::getFloatTy(m->getContext());
llvm::Type *f64 = llvm::Type::getDoubleTy(m->getContext());
llvm::Type *f8e4m3 = llvm::Type::getInt8Ty(
m->getContext()); // TODO(YuhanXu) : llvm not support fp8
llvm::Type *arr =
llvm::Type::getPrimitiveType(m->getContext(), llvm::Type::ArrayTyID);
if (type.is_void() && type.is_cpp_handle()) {
return llvm::PointerType::getUnqual(i8);
}
if (type.is_void() && type.is_cpp_handle2()) {
return llvm::PointerType::getUnqual(llvm::PointerType::getUnqual(i8));
}
if (type.is_bool()) {
ir_type = i1;
} else if (type.is_int(8)) {
ir_type = i8;
} else if (type.is_int(16)) {
ir_type = i16;
} else if (type.is_int(32)) {
ir_type = i32;
} else if (type.is_int(64)) {
ir_type = i64;
} else if (type.is_uint(8)) {
ir_type = u8;
} else if (type.is_uint(16)) {
ir_type = u16;
} else if (type.is_uint(32)) {
ir_type = u32;
} else if (type.is_uint(64)) {
ir_type = u64;
} else if (type.is_float(32)) {
ir_type = f32;
} else if (type.is_float(64)) {
ir_type = f64;
} else if (type.is_bfloat16()) {
ir_type = bf16;
} else if (type.is_float16()) {
ir_type = f16;
} else if (type.is_float8e4m3()) {
PADDLE_ENFORCE_NOT_NULL(
ir_type,
::common::errors::InvalidArgument(
"LLVM can't convert type: f8e4m3.")); // TODO(YuhanXu) : llvm not
// support fp8
ir_type = f8e4m3;
} else if (type.is_void()) {
ir_type = v;
} else if (type.is_string()) {
ir_type = arr;
} else if (type.is_customized_type()) {
PADDLE_ENFORCE_EQ(!type.customized_type().empty(),
true,
::common::errors::InvalidArgument(
"Customized type name should not be empty."));
const std::string struct_type_name = "struct." + type.customized_type();
ir_type =
llvm::StructType::getTypeByName(m->getContext(), struct_type_name);
}
PADDLE_ENFORCE_NOT_NULL(
ir_type, ::common::errors::InvalidArgument("LLVM can't convert type."));
// C array / vector.
if (type.lanes() > 1) {
if (is_vec) {
ir_type = llvm::FixedVectorType::get(ir_type, type.lanes());
} else {
ir_type = llvm::ArrayType::get(ir_type, type.lanes());
}
}
if (type.is_cpp_handle()) {
ir_type = llvm::PointerType::getUnqual(ir_type);
}
if (type.is_cpp_handle2()) {
ir_type = llvm::PointerType::getUnqual(ir_type);
ir_type = llvm::PointerType::getUnqual(ir_type);
}
return ir_type;
}
#define __(ty__) \
template <> \
llvm::Type *llvm_type_of<ty__>(llvm::Module * m) { \
return CinnTypeToLLVMType(cinn::common::type_of<ty__>(), m); \
}
__(int8_t)
__(int16_t)
__(int32_t)
__(int64_t)
__(uint8_t)
__(uint16_t)
__(uint32_t)
__(uint64_t)
__(bfloat16)
__(float16)
__(float)
__(double)
__(float8e4m3)
__(cinn_buffer_t)
__(cinn_buffer_t *)
__(cinn_pod_value_t *)
__(cinn_pod_value_t)
__(void *)
__(void **)
#undef __
} // namespace backends
} // namespace cinn