Skip to content

Commit 2b8164a

Browse files
gitoleglanza
authored andcommitted
[CIR][CodeGen] Introduce CIRBaseBuilder (#297)
As discussed in #279, we split `CIRGenBuilder` in two parts, which make some of the helpers usable outside of the `CodeGen` part. Basically, I placed casts and binary operations into a separate class, `CIRBaseBuilder`. Later, it can be extended with another helpers. But right now an idea to have a state less builder as a base one.
1 parent 9c63941 commit 2b8164a

File tree

2 files changed

+177
-128
lines changed

2 files changed

+177
-128
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
//===-- CIRBaseBuilder.h - CIRBuilder implementation -----------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_LIB_CIRBASEBUILDER_H
10+
#define LLVM_CLANG_LIB_CIRBASEBUILDER_H
11+
12+
#include "clang/AST/Decl.h"
13+
#include "clang/AST/Type.h"
14+
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
15+
#include "clang/CIR/Dialect/IR/CIRDialect.h"
16+
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
17+
#include "clang/CIR/Dialect/IR/CIRTypes.h"
18+
#include "clang/CIR/Dialect/IR/FPEnv.h"
19+
20+
#include "mlir/IR/Attributes.h"
21+
#include "mlir/IR/Builders.h"
22+
#include "mlir/IR/BuiltinAttributes.h"
23+
#include "mlir/IR/BuiltinOps.h"
24+
#include "mlir/IR/BuiltinTypes.h"
25+
#include "mlir/IR/Location.h"
26+
#include "mlir/IR/Types.h"
27+
#include "llvm/ADT/APSInt.h"
28+
#include "llvm/ADT/ArrayRef.h"
29+
#include "llvm/ADT/FloatingPointMode.h"
30+
#include "llvm/ADT/StringMap.h"
31+
#include "llvm/ADT/StringSet.h"
32+
#include "llvm/Support/ErrorHandling.h"
33+
#include <cassert>
34+
#include <optional>
35+
#include <string>
36+
37+
namespace cir {
38+
39+
class CIRBaseBuilderTy : public mlir::OpBuilder {
40+
41+
public:
42+
CIRBaseBuilderTy(mlir::MLIRContext &C) : mlir::OpBuilder(&C) {}
43+
44+
mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ,
45+
const llvm::APInt &val) {
46+
return create<mlir::cir::ConstantOp>(loc, typ,
47+
getAttr<mlir::cir::IntAttr>(typ, val));
48+
}
49+
50+
mlir::Value createNot(mlir::Value value) {
51+
return create<mlir::cir::UnaryOp>(value.getLoc(), value.getType(),
52+
mlir::cir::UnaryOpKind::Not, value);
53+
}
54+
55+
mlir::Value createBinop(mlir::Value lhs, mlir::cir::BinOpKind kind,
56+
const llvm::APInt &rhs) {
57+
return create<mlir::cir::BinOp>(
58+
lhs.getLoc(), lhs.getType(), kind, lhs,
59+
getConstAPInt(lhs.getLoc(), lhs.getType(), rhs));
60+
}
61+
62+
mlir::Value createBinop(mlir::Value lhs, mlir::cir::BinOpKind kind,
63+
mlir::Value rhs) {
64+
return create<mlir::cir::BinOp>(lhs.getLoc(), lhs.getType(), kind, lhs,
65+
rhs);
66+
}
67+
68+
mlir::Value createShift(mlir::Value lhs, const llvm::APInt &rhs,
69+
bool isShiftLeft) {
70+
return create<mlir::cir::ShiftOp>(
71+
lhs.getLoc(), lhs.getType(), lhs,
72+
getConstAPInt(lhs.getLoc(), lhs.getType(), rhs), isShiftLeft);
73+
}
74+
75+
mlir::Value createShift(mlir::Value lhs, unsigned bits, bool isShiftLeft) {
76+
auto width = lhs.getType().dyn_cast<mlir::cir::IntType>().getWidth();
77+
auto shift = llvm::APInt(width, bits);
78+
return createShift(lhs, shift, isShiftLeft);
79+
}
80+
81+
mlir::Value createShiftLeft(mlir::Value lhs, unsigned bits) {
82+
return createShift(lhs, bits, true);
83+
}
84+
85+
mlir::Value createShiftRight(mlir::Value lhs, unsigned bits) {
86+
return createShift(lhs, bits, false);
87+
}
88+
89+
mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
90+
unsigned bits) {
91+
auto val = llvm::APInt::getLowBitsSet(size, bits);
92+
auto typ = mlir::cir::IntType::get(getContext(), size, false);
93+
return getConstAPInt(loc, typ, val);
94+
}
95+
96+
mlir::Value createAnd(mlir::Value lhs, llvm::APInt rhs) {
97+
auto val = getConstAPInt(lhs.getLoc(), lhs.getType(), rhs);
98+
return createBinop(lhs, mlir::cir::BinOpKind::And, val);
99+
}
100+
101+
mlir::Value createAnd(mlir::Value lhs, mlir::Value rhs) {
102+
return createBinop(lhs, mlir::cir::BinOpKind::And, rhs);
103+
}
104+
105+
mlir::Value createOr(mlir::Value lhs, llvm::APInt rhs) {
106+
auto val = getConstAPInt(lhs.getLoc(), lhs.getType(), rhs);
107+
return createBinop(lhs, mlir::cir::BinOpKind::Or, val);
108+
}
109+
110+
mlir::Value createOr(mlir::Value lhs, mlir::Value rhs) {
111+
return createBinop(lhs, mlir::cir::BinOpKind::Or, rhs);
112+
}
113+
114+
//===--------------------------------------------------------------------===//
115+
// Cast/Conversion Operators
116+
//===--------------------------------------------------------------------===//
117+
118+
mlir::Value createCast(mlir::cir::CastKind kind, mlir::Value src,
119+
mlir::Type newTy) {
120+
if (newTy == src.getType())
121+
return src;
122+
return create<mlir::cir::CastOp>(src.getLoc(), newTy, kind, src);
123+
}
124+
125+
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) {
126+
return create<mlir::cir::CastOp>(src.getLoc(), newTy,
127+
mlir::cir::CastKind::integral, src);
128+
}
129+
130+
mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) {
131+
return create<mlir::cir::CastOp>(src.getLoc(), newTy,
132+
mlir::cir::CastKind::int_to_ptr, src);
133+
}
134+
135+
mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) {
136+
return create<mlir::cir::CastOp>(src.getLoc(), newTy,
137+
mlir::cir::CastKind::ptr_to_int, src);
138+
}
139+
140+
// TODO(cir): the following function was introduced to keep in sync with LLVM
141+
// codegen. CIR does not have "zext" operations. It should eventually be
142+
// renamed or removed. For now, we just add whatever cast is required here.
143+
mlir::Value createZExtOrBitCast(mlir::Location loc, mlir::Value src,
144+
mlir::Type newTy) {
145+
auto srcTy = src.getType();
146+
147+
if (srcTy == newTy)
148+
return src;
149+
150+
if (srcTy.isa<mlir::cir::BoolType>() && newTy.isa<mlir::cir::IntType>())
151+
return createBoolToInt(src, newTy);
152+
153+
llvm_unreachable("unhandled extension cast");
154+
}
155+
156+
mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) {
157+
return createCast(mlir::cir::CastKind::bool_to_int, src, newTy);
158+
}
159+
160+
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) {
161+
return createCast(mlir::cir::CastKind::bitcast, src, newTy);
162+
}
163+
164+
mlir::Value createBitcast(mlir::Location loc, mlir::Value src,
165+
mlir::Type newTy) {
166+
if (newTy == src.getType())
167+
return src;
168+
return create<mlir::cir::CastOp>(loc, newTy, mlir::cir::CastKind::bitcast,
169+
src);
170+
}
171+
};
172+
173+
} // namespace cir
174+
#endif

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 3 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "clang/AST/Decl.h"
1717
#include "clang/AST/Type.h"
18+
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
1819
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
1920
#include "clang/CIR/Dialect/IR/CIRDialect.h"
2021
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
@@ -42,7 +43,7 @@ namespace cir {
4243

4344
class CIRGenFunction;
4445

45-
class CIRGenBuilderTy : public mlir::OpBuilder {
46+
class CIRGenBuilderTy : public CIRBaseBuilderTy {
4647
const CIRGenTypeCache &typeCache;
4748
bool IsFPConstrained = false;
4849
fp::ExceptionBehavior DefaultConstrainedExcept = fp::ebStrict;
@@ -53,7 +54,7 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
5354

5455
public:
5556
CIRGenBuilderTy(mlir::MLIRContext &C, const CIRGenTypeCache &tc)
56-
: mlir::OpBuilder(&C), typeCache(tc) {}
57+
: CIRBaseBuilderTy(C), typeCache(tc) {}
5758

5859
std::string getUniqueAnonRecordName() {
5960
std::string name = "anon." + std::to_string(anonRecordNames.size());
@@ -468,11 +469,6 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
468469
return getConstInt(
469470
loc, t, isSigned ? intVal.getSExtValue() : intVal.getZExtValue());
470471
}
471-
mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ,
472-
const llvm::APInt &val) {
473-
return create<mlir::cir::ConstantOp>(loc, typ,
474-
getAttr<mlir::cir::IntAttr>(typ, val));
475-
}
476472
mlir::cir::ConstantOp getBool(bool state, mlir::Location loc) {
477473
return create<mlir::cir::ConstantOp>(loc, getBoolTy(),
478474
getCIRBoolAttr(state));
@@ -643,14 +639,6 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
643639
addr.getAlignment());
644640
}
645641

646-
mlir::Value createBitcast(mlir::Location loc, mlir::Value src,
647-
mlir::Type newTy) {
648-
if (newTy == src.getType())
649-
return src;
650-
return create<mlir::cir::CastOp>(loc, newTy, mlir::cir::CastKind::bitcast,
651-
src);
652-
}
653-
654642
mlir::Value createLoad(mlir::Location loc, Address addr) {
655643
return create<mlir::cir::LoadOp>(loc, addr.getElementType(),
656644
addr.getPointer());
@@ -687,119 +675,6 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
687675
return create<mlir::cir::StoreOp>(loc, flag, dst);
688676
}
689677

690-
mlir::Value createNot(mlir::Value value) {
691-
return create<mlir::cir::UnaryOp>(value.getLoc(), value.getType(),
692-
mlir::cir::UnaryOpKind::Not, value);
693-
}
694-
695-
mlir::Value createBinop(mlir::Value lhs, mlir::cir::BinOpKind kind,
696-
const llvm::APInt &rhs) {
697-
return create<mlir::cir::BinOp>(
698-
lhs.getLoc(), lhs.getType(), kind, lhs,
699-
getConstAPInt(lhs.getLoc(), lhs.getType(), rhs));
700-
}
701-
702-
mlir::Value createBinop(mlir::Value lhs, mlir::cir::BinOpKind kind,
703-
mlir::Value rhs) {
704-
return create<mlir::cir::BinOp>(lhs.getLoc(), lhs.getType(), kind, lhs,
705-
rhs);
706-
}
707-
708-
mlir::Value createShift(mlir::Value lhs, const llvm::APInt &rhs,
709-
bool isShiftLeft) {
710-
return create<mlir::cir::ShiftOp>(
711-
lhs.getLoc(), lhs.getType(), lhs,
712-
getConstAPInt(lhs.getLoc(), lhs.getType(), rhs), isShiftLeft);
713-
}
714-
715-
mlir::Value createShift(mlir::Value lhs, unsigned bits, bool isShiftLeft) {
716-
auto width = lhs.getType().dyn_cast<mlir::cir::IntType>().getWidth();
717-
auto shift = llvm::APInt(width, bits);
718-
return createShift(lhs, shift, isShiftLeft);
719-
}
720-
721-
mlir::Value createShiftLeft(mlir::Value lhs, unsigned bits) {
722-
return createShift(lhs, bits, true);
723-
}
724-
725-
mlir::Value createShiftRight(mlir::Value lhs, unsigned bits) {
726-
return createShift(lhs, bits, false);
727-
}
728-
729-
mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
730-
unsigned bits) {
731-
auto val = llvm::APInt::getLowBitsSet(size, bits);
732-
auto typ = mlir::cir::IntType::get(getContext(), size, false);
733-
return getConstAPInt(loc, typ, val);
734-
}
735-
736-
mlir::Value createAnd(mlir::Value lhs, llvm::APInt rhs) {
737-
auto val = getConstAPInt(lhs.getLoc(), lhs.getType(), rhs);
738-
return createBinop(lhs, mlir::cir::BinOpKind::And, val);
739-
}
740-
741-
mlir::Value createAnd(mlir::Value lhs, mlir::Value rhs) {
742-
return createBinop(lhs, mlir::cir::BinOpKind::And, rhs);
743-
}
744-
745-
mlir::Value createOr(mlir::Value lhs, llvm::APInt rhs) {
746-
auto val = getConstAPInt(lhs.getLoc(), lhs.getType(), rhs);
747-
return createBinop(lhs, mlir::cir::BinOpKind::Or, val);
748-
}
749-
750-
mlir::Value createOr(mlir::Value lhs, mlir::Value rhs) {
751-
return createBinop(lhs, mlir::cir::BinOpKind::Or, rhs);
752-
}
753-
754-
//===--------------------------------------------------------------------===//
755-
// Cast/Conversion Operators
756-
//===--------------------------------------------------------------------===//
757-
758-
mlir::Value createCast(mlir::cir::CastKind kind, mlir::Value src,
759-
mlir::Type newTy) {
760-
if (newTy == src.getType())
761-
return src;
762-
return create<mlir::cir::CastOp>(src.getLoc(), newTy, kind, src);
763-
}
764-
765-
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy) {
766-
return create<mlir::cir::CastOp>(src.getLoc(), newTy,
767-
mlir::cir::CastKind::integral, src);
768-
}
769-
770-
mlir::Value createIntToPtr(mlir::Value src, mlir::Type newTy) {
771-
return create<mlir::cir::CastOp>(src.getLoc(), newTy,
772-
mlir::cir::CastKind::int_to_ptr, src);
773-
}
774-
775-
mlir::Value createPtrToInt(mlir::Value src, mlir::Type newTy) {
776-
return create<mlir::cir::CastOp>(src.getLoc(), newTy,
777-
mlir::cir::CastKind::ptr_to_int, src);
778-
}
779-
780-
// TODO(cir): the following function was introduced to keep in sync with LLVM
781-
// codegen. CIR does not have "zext" operations. It should eventually be
782-
// renamed or removed. For now, we just add whatever cast is required here.
783-
mlir::Value createZExtOrBitCast(mlir::Location loc, mlir::Value src,
784-
mlir::Type newTy) {
785-
auto srcTy = src.getType();
786-
787-
if (srcTy == newTy)
788-
return src;
789-
790-
if (srcTy.isa<mlir::cir::BoolType>() && newTy.isa<mlir::cir::IntType>())
791-
return createBoolToInt(src, newTy);
792-
793-
llvm_unreachable("unhandled extension cast");
794-
}
795-
796-
mlir::Value createBoolToInt(mlir::Value src, mlir::Type newTy) {
797-
return createCast(mlir::cir::CastKind::bool_to_int, src, newTy);
798-
}
799-
800-
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy) {
801-
return createCast(mlir::cir::CastKind::bitcast, src, newTy);
802-
}
803678
};
804679

805680
} // namespace cir

0 commit comments

Comments
 (0)