|
10 | 10 | #define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
|
11 | 11 |
|
12 | 12 | #include "clang/AST/CharUnits.h"
|
13 |
| -#include "clang/AST/Type.h" |
14 | 13 | #include "clang/CIR/Dialect/IR/CIRAttrs.h"
|
15 | 14 | #include "clang/CIR/Dialect/IR/CIRDialect.h"
|
16 | 15 | #include "clang/CIR/Dialect/IR/CIRTypes.h"
|
| 16 | +#include "llvm/ADT/STLForwardCompat.h" |
17 | 17 | #include "llvm/Support/ErrorHandling.h"
|
18 | 18 |
|
19 | 19 | #include "mlir/IR/Builders.h"
|
20 | 20 | #include "mlir/IR/BuiltinTypes.h"
|
| 21 | +#include "mlir/IR/Location.h" |
21 | 22 | #include "mlir/IR/Types.h"
|
22 | 23 |
|
23 | 24 | namespace cir {
|
24 | 25 |
|
| 26 | +enum class OverflowBehavior { |
| 27 | + None = 0, |
| 28 | + NoSignedWrap = 1 << 0, |
| 29 | + NoUnsignedWrap = 1 << 1, |
| 30 | + Saturated = 1 << 2, |
| 31 | +}; |
| 32 | + |
| 33 | +constexpr OverflowBehavior operator|(OverflowBehavior a, OverflowBehavior b) { |
| 34 | + return static_cast<OverflowBehavior>(llvm::to_underlying(a) | |
| 35 | + llvm::to_underlying(b)); |
| 36 | +} |
| 37 | + |
| 38 | +constexpr OverflowBehavior operator&(OverflowBehavior a, OverflowBehavior b) { |
| 39 | + return static_cast<OverflowBehavior>(llvm::to_underlying(a) & |
| 40 | + llvm::to_underlying(b)); |
| 41 | +} |
| 42 | + |
| 43 | +constexpr OverflowBehavior &operator|=(OverflowBehavior &a, |
| 44 | + OverflowBehavior b) { |
| 45 | + a = a | b; |
| 46 | + return a; |
| 47 | +} |
| 48 | + |
| 49 | +constexpr OverflowBehavior &operator&=(OverflowBehavior &a, |
| 50 | + OverflowBehavior b) { |
| 51 | + a = a & b; |
| 52 | + return a; |
| 53 | +} |
| 54 | + |
25 | 55 | class CIRBaseBuilderTy : public mlir::OpBuilder {
|
26 | 56 |
|
27 | 57 | public:
|
28 | 58 | CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
|
29 | 59 | : mlir::OpBuilder(&mlirContext) {}
|
30 | 60 |
|
| 61 | + mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, |
| 62 | + const llvm::APInt &val) { |
| 63 | + return create<cir::ConstantOp>(loc, typ, getAttr<cir::IntAttr>(typ, val)); |
| 64 | + } |
| 65 | + |
31 | 66 | cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr) {
|
32 | 67 | return create<cir::ConstantOp>(loc, attr.getType(), attr);
|
33 | 68 | }
|
@@ -143,6 +178,93 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
|
143 | 178 | return createCast(loc, cir::CastKind::bitcast, src, newTy);
|
144 | 179 | }
|
145 | 180 |
|
| 181 | + //===--------------------------------------------------------------------===// |
| 182 | + // Binary Operators |
| 183 | + //===--------------------------------------------------------------------===// |
| 184 | + |
| 185 | + mlir::Value createBinop(mlir::Location loc, mlir::Value lhs, |
| 186 | + cir::BinOpKind kind, mlir::Value rhs) { |
| 187 | + return create<cir::BinOp>(loc, lhs.getType(), kind, lhs, rhs); |
| 188 | + } |
| 189 | + |
| 190 | + mlir::Value createLowBitsSet(mlir::Location loc, unsigned size, |
| 191 | + unsigned bits) { |
| 192 | + llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits); |
| 193 | + auto type = cir::IntType::get(getContext(), size, /*isSigned=*/false); |
| 194 | + return getConstAPInt(loc, type, val); |
| 195 | + } |
| 196 | + |
| 197 | + mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) { |
| 198 | + return createBinop(loc, lhs, cir::BinOpKind::And, rhs); |
| 199 | + } |
| 200 | + |
| 201 | + mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) { |
| 202 | + return createBinop(loc, lhs, cir::BinOpKind::Or, rhs); |
| 203 | + } |
| 204 | + |
| 205 | + mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, |
| 206 | + OverflowBehavior ob = OverflowBehavior::None) { |
| 207 | + auto op = |
| 208 | + create<cir::BinOp>(loc, lhs.getType(), cir::BinOpKind::Mul, lhs, rhs); |
| 209 | + op.setNoUnsignedWrap( |
| 210 | + llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap)); |
| 211 | + op.setNoSignedWrap( |
| 212 | + llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap)); |
| 213 | + return op; |
| 214 | + } |
| 215 | + mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs, |
| 216 | + mlir::Value rhs) { |
| 217 | + return createMul(loc, lhs, rhs, OverflowBehavior::NoSignedWrap); |
| 218 | + } |
| 219 | + mlir::Value createNUWAMul(mlir::Location loc, mlir::Value lhs, |
| 220 | + mlir::Value rhs) { |
| 221 | + return createMul(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap); |
| 222 | + } |
| 223 | + |
| 224 | + mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, |
| 225 | + OverflowBehavior ob = OverflowBehavior::Saturated) { |
| 226 | + auto op = |
| 227 | + create<cir::BinOp>(loc, lhs.getType(), cir::BinOpKind::Sub, lhs, rhs); |
| 228 | + op.setNoUnsignedWrap( |
| 229 | + llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap)); |
| 230 | + op.setNoSignedWrap( |
| 231 | + llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap)); |
| 232 | + op.setSaturated(llvm::to_underlying(ob & OverflowBehavior::Saturated)); |
| 233 | + return op; |
| 234 | + } |
| 235 | + |
| 236 | + mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs, |
| 237 | + mlir::Value rhs) { |
| 238 | + return createSub(loc, lhs, rhs, OverflowBehavior::NoSignedWrap); |
| 239 | + } |
| 240 | + |
| 241 | + mlir::Value createNUWSub(mlir::Location loc, mlir::Value lhs, |
| 242 | + mlir::Value rhs) { |
| 243 | + return createSub(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap); |
| 244 | + } |
| 245 | + |
| 246 | + mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, |
| 247 | + OverflowBehavior ob = OverflowBehavior::None) { |
| 248 | + auto op = |
| 249 | + create<cir::BinOp>(loc, lhs.getType(), cir::BinOpKind::Add, lhs, rhs); |
| 250 | + op.setNoUnsignedWrap( |
| 251 | + llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap)); |
| 252 | + op.setNoSignedWrap( |
| 253 | + llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap)); |
| 254 | + op.setSaturated(llvm::to_underlying(ob & OverflowBehavior::Saturated)); |
| 255 | + return op; |
| 256 | + } |
| 257 | + |
| 258 | + mlir::Value createNSWAdd(mlir::Location loc, mlir::Value lhs, |
| 259 | + mlir::Value rhs) { |
| 260 | + return createAdd(loc, lhs, rhs, OverflowBehavior::NoSignedWrap); |
| 261 | + } |
| 262 | + |
| 263 | + mlir::Value createNUWAdd(mlir::Location loc, mlir::Value lhs, |
| 264 | + mlir::Value rhs) { |
| 265 | + return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap); |
| 266 | + } |
| 267 | + |
146 | 268 | //
|
147 | 269 | // Block handling helpers
|
148 | 270 | // ----------------------
|
|
0 commit comments