diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h new file mode 100644 index 000000000000..7fe9d9991345 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -0,0 +1,174 @@ +//===-- CIRBaseBuilder.h - CIRBuilder implementation -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CIRBASEBUILDER_H +#define LLVM_CLANG_LIB_CIRBASEBUILDER_H + +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "clang/CIR/Dialect/IR/CIRAttrs.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIROpsEnums.h" +#include "clang/CIR/Dialect/IR/CIRTypes.h" +#include "clang/CIR/Dialect/IR/FPEnv.h" + +#include "mlir/IR/Attributes.h" +#include "mlir/IR/Builders.h" +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/BuiltinOps.h" +#include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/Location.h" +#include "mlir/IR/Types.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FloatingPointMode.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/ErrorHandling.h" +#include +#include +#include + +namespace cir { + +class CIRBaseBuilderTy : public mlir::OpBuilder { + +public: + CIRBaseBuilderTy(mlir::MLIRContext &C) : mlir::OpBuilder(&C) {} + + mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, + const llvm::APInt &val) { + return create(loc, typ, + getAttr(typ, val)); + } + + mlir::Value createNot(mlir::Value value) { + return create(value.getLoc(), value.getType(), + mlir::cir::UnaryOpKind::Not, value); + } + + mlir::Value createBinop(mlir::Value lhs, mlir::cir::BinOpKind kind, + const llvm::APInt &rhs) { + return create( + lhs.getLoc(), lhs.getType(), kind, lhs, + getConstAPInt(lhs.getLoc(), lhs.getType(), rhs)); + } + + mlir::Value createBinop(mlir::Value lhs, mlir::cir::BinOpKind kind, + mlir::Value rhs) { + return create(lhs.getLoc(), lhs.getType(), kind, lhs, + rhs); + } + + mlir::Value createShift(mlir::Value lhs, const llvm::APInt &rhs, + bool isShiftLeft) { + return create( + lhs.getLoc(), lhs.getType(), lhs, + getConstAPInt(lhs.getLoc(), lhs.getType(), rhs), isShiftLeft); + } + + mlir::Value createShift(mlir::Value lhs, unsigned bits, bool isShiftLeft) { + auto width = lhs.getType().dyn_cast().getWidth(); + auto shift = llvm::APInt(width, bits); + return createShift(lhs, shift, isShiftLeft); + } + + mlir::Value createShiftLeft(mlir::Value lhs, unsigned bits) { + return createShift(lhs, bits, true); + } + + mlir::Value createShiftRight(mlir::Value lhs, unsigned bits) { + return createShift(lhs, bits, false); + } + + mlir::Value createLowBitsSet(mlir::Location loc, unsigned size, + unsigned bits) { + auto val = llvm::APInt::getLowBitsSet(size, bits); + auto typ = mlir::cir::IntType::get(getContext(), size, false); + return getConstAPInt(loc, typ, val); + } + + mlir::Value createAnd(mlir::Value lhs, llvm::APInt rhs) { + auto val = getConstAPInt(lhs.getLoc(), lhs.getType(), rhs); + return createBinop(lhs, mlir::cir::BinOpKind::And, val); + } + + mlir::Value createAnd(mlir::Value lhs, mlir::Value rhs) { + return createBinop(lhs, mlir::cir::BinOpKind::And, rhs); + } + + mlir::Value createOr(mlir::Value lhs, llvm::APInt rhs) { + auto val = getConstAPInt(lhs.getLoc(), lhs.getType(), rhs); + return createBinop(lhs, mlir::cir::BinOpKind::Or, val); + } + + mlir::Value createOr(mlir::Value lhs, mlir::Value rhs) { + return createBinop(lhs, mlir::cir::BinOpKind::Or, rhs); + } + + //===--------------------------------------------------------------------===// + // Cast/Conversion Operators + //===--------------------------------------------------------------------===// + + mlir::Value createCast(mlir::cir::CastKind kind, mlir::Value src, + mlir::Type newTy) { + if (newTy == src.getType()) + return src; + return create(src.getLoc(), newTy, kind, src); + } + + mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) { + return create(src.getLoc(), newTy, + mlir::cir::CastKind::integral, src); + } + + mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) { + return create(src.getLoc(), newTy, + mlir::cir::CastKind::int_to_ptr, src); + } + + mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) { + return create(src.getLoc(), newTy, + mlir::cir::CastKind::ptr_to_int, src); + } + + // TODO(cir): the following function was introduced to keep in sync with LLVM + // codegen. CIR does not have "zext" operations. It should eventually be + // renamed or removed. For now, we just add whatever cast is required here. + mlir::Value createZExtOrBitCast(mlir::Location loc, mlir::Value src, + mlir::Type newTy) { + auto srcTy = src.getType(); + + if (srcTy == newTy) + return src; + + if (srcTy.isa() && newTy.isa()) + return createBoolToInt(src, newTy); + + llvm_unreachable("unhandled extension cast"); + } + + mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) { + return createCast(mlir::cir::CastKind::bool_to_int, src, newTy); + } + + mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) { + return createCast(mlir::cir::CastKind::bitcast, src, newTy); + } + + mlir::Value createBitcast(mlir::Location loc, mlir::Value src, + mlir::Type newTy) { + if (newTy == src.getType()) + return src; + return create(loc, newTy, mlir::cir::CastKind::bitcast, + src); + } +}; + +} // namespace cir +#endif diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index d451c40ae901..0ab675375c0d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -15,6 +15,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Type.h" +#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h" #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "clang/CIR/Dialect/IR/CIROpsEnums.h" @@ -42,7 +43,7 @@ namespace cir { class CIRGenFunction; -class CIRGenBuilderTy : public mlir::OpBuilder { +class CIRGenBuilderTy : public CIRBaseBuilderTy { const CIRGenTypeCache &typeCache; bool IsFPConstrained = false; fp::ExceptionBehavior DefaultConstrainedExcept = fp::ebStrict; @@ -53,7 +54,7 @@ class CIRGenBuilderTy : public mlir::OpBuilder { public: CIRGenBuilderTy(mlir::MLIRContext &C, const CIRGenTypeCache &tc) - : mlir::OpBuilder(&C), typeCache(tc) {} + : CIRBaseBuilderTy(C), typeCache(tc) {} std::string getUniqueAnonRecordName() { std::string name = "anon." + std::to_string(anonRecordNames.size()); @@ -468,11 +469,6 @@ class CIRGenBuilderTy : public mlir::OpBuilder { return getConstInt( loc, t, isSigned ? intVal.getSExtValue() : intVal.getZExtValue()); } - mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, - const llvm::APInt &val) { - return create(loc, typ, - getAttr(typ, val)); - } mlir::cir::ConstantOp getBool(bool state, mlir::Location loc) { return create(loc, getBoolTy(), getCIRBoolAttr(state)); @@ -643,14 +639,6 @@ class CIRGenBuilderTy : public mlir::OpBuilder { addr.getAlignment()); } - mlir::Value createBitcast(mlir::Location loc, mlir::Value src, - mlir::Type newTy) { - if (newTy == src.getType()) - return src; - return create(loc, newTy, mlir::cir::CastKind::bitcast, - src); - } - mlir::Value createLoad(mlir::Location loc, Address addr) { return create(loc, addr.getElementType(), addr.getPointer()); @@ -687,119 +675,6 @@ class CIRGenBuilderTy : public mlir::OpBuilder { return create(loc, flag, dst); } - mlir::Value createNot(mlir::Value value) { - return create(value.getLoc(), value.getType(), - mlir::cir::UnaryOpKind::Not, value); - } - - mlir::Value createBinop(mlir::Value lhs, mlir::cir::BinOpKind kind, - const llvm::APInt &rhs) { - return create( - lhs.getLoc(), lhs.getType(), kind, lhs, - getConstAPInt(lhs.getLoc(), lhs.getType(), rhs)); - } - - mlir::Value createBinop(mlir::Value lhs, mlir::cir::BinOpKind kind, - mlir::Value rhs) { - return create(lhs.getLoc(), lhs.getType(), kind, lhs, - rhs); - } - - mlir::Value createShift(mlir::Value lhs, const llvm::APInt &rhs, - bool isShiftLeft) { - return create( - lhs.getLoc(), lhs.getType(), lhs, - getConstAPInt(lhs.getLoc(), lhs.getType(), rhs), isShiftLeft); - } - - mlir::Value createShift(mlir::Value lhs, unsigned bits, bool isShiftLeft) { - auto width = lhs.getType().dyn_cast().getWidth(); - auto shift = llvm::APInt(width, bits); - return createShift(lhs, shift, isShiftLeft); - } - - mlir::Value createShiftLeft(mlir::Value lhs, unsigned bits) { - return createShift(lhs, bits, true); - } - - mlir::Value createShiftRight(mlir::Value lhs, unsigned bits) { - return createShift(lhs, bits, false); - } - - mlir::Value createLowBitsSet(mlir::Location loc, unsigned size, - unsigned bits) { - auto val = llvm::APInt::getLowBitsSet(size, bits); - auto typ = mlir::cir::IntType::get(getContext(), size, false); - return getConstAPInt(loc, typ, val); - } - - mlir::Value createAnd(mlir::Value lhs, llvm::APInt rhs) { - auto val = getConstAPInt(lhs.getLoc(), lhs.getType(), rhs); - return createBinop(lhs, mlir::cir::BinOpKind::And, val); - } - - mlir::Value createAnd(mlir::Value lhs, mlir::Value rhs) { - return createBinop(lhs, mlir::cir::BinOpKind::And, rhs); - } - - mlir::Value createOr(mlir::Value lhs, llvm::APInt rhs) { - auto val = getConstAPInt(lhs.getLoc(), lhs.getType(), rhs); - return createBinop(lhs, mlir::cir::BinOpKind::Or, val); - } - - mlir::Value createOr(mlir::Value lhs, mlir::Value rhs) { - return createBinop(lhs, mlir::cir::BinOpKind::Or, rhs); - } - - //===--------------------------------------------------------------------===// - // Cast/Conversion Operators - //===--------------------------------------------------------------------===// - - mlir::Value createCast(mlir::cir::CastKind kind, mlir::Value src, - mlir::Type newTy) { - if (newTy == src.getType()) - return src; - return create(src.getLoc(), newTy, kind, src); - } - - mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) { - return create(src.getLoc(), newTy, - mlir::cir::CastKind::integral, src); - } - - mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) { - return create(src.getLoc(), newTy, - mlir::cir::CastKind::int_to_ptr, src); - } - - mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) { - return create(src.getLoc(), newTy, - mlir::cir::CastKind::ptr_to_int, src); - } - - // TODO(cir): the following function was introduced to keep in sync with LLVM - // codegen. CIR does not have "zext" operations. It should eventually be - // renamed or removed. For now, we just add whatever cast is required here. - mlir::Value createZExtOrBitCast(mlir::Location loc, mlir::Value src, - mlir::Type newTy) { - auto srcTy = src.getType(); - - if (srcTy == newTy) - return src; - - if (srcTy.isa() && newTy.isa()) - return createBoolToInt(src, newTy); - - llvm_unreachable("unhandled extension cast"); - } - - mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) { - return createCast(mlir::cir::CastKind::bool_to_int, src, newTy); - } - - mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) { - return createCast(mlir::cir::CastKind::bitcast, src, newTy); - } }; } // namespace cir