Skip to content

Commit 8c7235c

Browse files
committed
add CXXCtorDtor attribute
1 parent 32e3971 commit 8c7235c

29 files changed

+714
-142
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,9 +1138,9 @@ def ASTCallExprAttr : AST<"CallExpr", "call.expr",
11381138
//===----------------------------------------------------------------------===//
11391139

11401140
def CIR_VisibilityKind : CIR_I32EnumAttr<"VisibilityKind", "C/C++ visibility", [
1141-
I32EnumAttrCase<"Default", 1, "default">,
1142-
I32EnumAttrCase<"Hidden", 2, "hidden">,
1143-
I32EnumAttrCase<"Protected", 3, "protected">
1141+
I32EnumAttrCase<"Default", 0, "default">,
1142+
I32EnumAttrCase<"Hidden", 1, "hidden">,
1143+
I32EnumAttrCase<"Protected", 2, "protected">
11441144
]> {
11451145
let genSpecializedAttr = 0;
11461146
}
@@ -1155,7 +1155,8 @@ def CIR_VisibilityAttr : CIR_EnumAttr<CIR_VisibilityKind, "visibility"> {
11551155

11561156
let skipDefaultBuilders = 1;
11571157
let builders = [
1158-
AttrBuilder<(ins CArg<"VisibilityKind", "cir::VisibilityKind::Default">:$value), [{
1158+
AttrBuilder<(ins CArg<"VisibilityKind",
1159+
"cir::VisibilityKind::Default">:$value), [{
11591160
return $_get($_ctxt, value);
11601161
}]>
11611162
];
@@ -1300,6 +1301,59 @@ def GlobalDtorAttr : CIR_GlobalCtorDtor<"Dtor", "dtor",
13001301
"A function with this attribute excutes before module unloading"
13011302
>;
13021303

1304+
class CIR_CXXSpecialMember<string name, string attrMnemonic, string sum,
1305+
string desc> : CIR_Attr<name, attrMnemonic> {
1306+
let summary = sum;
1307+
let description = desc;
1308+
let skipDefaultBuilders = 1;
1309+
}
1310+
1311+
def CXXCtorAttr
1312+
: CIR_CXXSpecialMember<
1313+
"CXXCtor", "cxx_ctor", "Marks a function as a CXX constructor",
1314+
"Functions with this attribute are CXX constructors"> {
1315+
let parameters = (ins "mlir::Type":$type,
1316+
"bool":$is_default_constructor,
1317+
"bool":$is_copy_constructor);
1318+
let assemblyFormat = [{
1319+
`<`
1320+
$type `,` $is_default_constructor `,` $is_copy_constructor
1321+
`>`
1322+
}];
1323+
let builders =
1324+
[AttrBuilder<(ins "mlir::Type":$type,
1325+
"bool":$is_default_constructor,
1326+
"bool":$is_copy_constructor), [{
1327+
return $_get($_ctxt, type, is_default_constructor,
1328+
is_copy_constructor);
1329+
}]>,
1330+
AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
1331+
"bool":$is_default_constructor,
1332+
"bool":$is_copy_constructor), [{
1333+
return $_get(type.getContext(), type,
1334+
is_default_constructor, is_copy_constructor);
1335+
}]>];
1336+
}
1337+
1338+
def CXXDtorAttr
1339+
: CIR_CXXSpecialMember<
1340+
"CXXDtor", "cxx_dtor", "Marks a function as a CXX destructor",
1341+
"Functions with this attribute are CXX destructors"> {
1342+
let parameters = (ins "mlir::Type":$type);
1343+
let assemblyFormat = [{
1344+
`<`
1345+
$type
1346+
`>`
1347+
}];
1348+
let builders =
1349+
[AttrBuilder<(ins "mlir::Type":$type), [{
1350+
return $_get($_ctxt, type);
1351+
}]>,
1352+
AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{
1353+
return $_get(type.getContext(), type);
1354+
}]>];
1355+
}
1356+
13031357
def BitfieldInfoAttr : CIR_Attr<"BitfieldInfo", "bitfield_info"> {
13041358
let summary = "Represents a bit field info";
13051359
let description = [{

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 116 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -87,32 +87,78 @@ class CIR_Op<string mnemonic, list<Trait> traits = []> :
8787
//===----------------------------------------------------------------------===//
8888

8989
def CIR_CastKind : CIR_I32EnumAttr<"CastKind", "cast kind", [
90-
// The enumaration value isn't in sync with clang.
91-
I32EnumAttrCase<"int_to_bool", 0>,
92-
I32EnumAttrCase<"array_to_ptrdecay", 1>,
93-
I32EnumAttrCase<"integral", 2>,
94-
I32EnumAttrCase<"bitcast", 3>,
95-
I32EnumAttrCase<"floating", 4>,
96-
I32EnumAttrCase<"ptr_to_bool", 5>,
97-
I32EnumAttrCase<"float_to_int", 6>,
98-
I32EnumAttrCase<"int_to_ptr", 7>,
99-
I32EnumAttrCase<"ptr_to_int", 8>,
100-
I32EnumAttrCase<"float_to_bool", 9>,
101-
I32EnumAttrCase<"bool_to_int", 10>,
102-
I32EnumAttrCase<"int_to_float", 11>,
103-
I32EnumAttrCase<"bool_to_float", 12>,
104-
I32EnumAttrCase<"address_space", 13>,
105-
I32EnumAttrCase<"float_to_complex", 14>,
106-
I32EnumAttrCase<"int_to_complex", 15>,
107-
I32EnumAttrCase<"float_complex_to_real", 16>,
108-
I32EnumAttrCase<"int_complex_to_real", 17>,
109-
I32EnumAttrCase<"float_complex_to_bool", 18>,
110-
I32EnumAttrCase<"int_complex_to_bool", 19>,
111-
I32EnumAttrCase<"float_complex", 20>,
112-
I32EnumAttrCase<"float_complex_to_int_complex", 21>,
113-
I32EnumAttrCase<"int_complex", 22>,
114-
I32EnumAttrCase<"int_complex_to_float_complex", 23>,
115-
I32EnumAttrCase<"member_ptr_to_bool", 24>
90+
I32EnumAttrCase<"bitcast", 1>,
91+
// CK_LValueBitCast
92+
// CK_LValueToRValueBitCast
93+
// CK_LValueToRValue
94+
// CK_NoOp
95+
// CK_BaseToDerived
96+
// CK_DerivedToBase
97+
// CK_UncheckedDerivedToBase
98+
// CK_Dynamic
99+
// CK_ToUnion
100+
I32EnumAttrCase<"array_to_ptrdecay", 11>,
101+
// CK_FunctionToPointerDecay
102+
// CK_NullToPointer
103+
// CK_NullToMemberPointer
104+
// CK_BaseToDerivedMemberPointer
105+
// CK_DerivedToBaseMemberPointer
106+
I32EnumAttrCase<"member_ptr_to_bool", 17>,
107+
// CK_ReinterpretMemberPointer
108+
// CK_UserDefinedConversion
109+
// CK_ConstructorConversion
110+
I32EnumAttrCase<"int_to_ptr", 21>,
111+
I32EnumAttrCase<"ptr_to_int", 22>,
112+
I32EnumAttrCase<"ptr_to_bool", 23>,
113+
// CK_ToVoid
114+
// CK_MatrixCast
115+
// CK_VectorSplat
116+
I32EnumAttrCase<"integral", 27>,
117+
I32EnumAttrCase<"int_to_bool", 28>,
118+
I32EnumAttrCase<"int_to_float", 29>,
119+
// CK_FloatingToFixedPoint
120+
// CK_FixedPointToFloating
121+
// CK_FixedPointCast
122+
// CK_FixedPointToIntegral
123+
// CK_IntegralToFixedPoint
124+
// CK_FixedPointToBoolean
125+
I32EnumAttrCase<"float_to_int", 36>,
126+
I32EnumAttrCase<"float_to_bool", 37>,
127+
I32EnumAttrCase<"bool_to_int", 38>,
128+
I32EnumAttrCase<"floating", 39>,
129+
// CK_CPointerToObjCPointerCast
130+
// CK_BlockPointerToObjCPointerCast
131+
// CK_AnyPointerToBlockPointerCast
132+
// CK_ObjCObjectLValueCast
133+
I32EnumAttrCase<"float_to_complex", 44>,
134+
I32EnumAttrCase<"float_complex_to_real", 45>,
135+
I32EnumAttrCase<"float_complex_to_bool", 46>,
136+
I32EnumAttrCase<"float_complex", 47>,
137+
I32EnumAttrCase<"float_complex_to_int_complex", 48>,
138+
I32EnumAttrCase<"int_to_complex", 49>,
139+
I32EnumAttrCase<"int_complex_to_real", 50>,
140+
I32EnumAttrCase<"int_complex_to_bool", 51>,
141+
I32EnumAttrCase<"int_complex", 52>,
142+
I32EnumAttrCase<"int_complex_to_float_complex", 53>,
143+
// CK_ARCProduceObject
144+
// CK_ARCConsumeObject
145+
// CK_ARCReclaimReturnedObject
146+
// CK_ARCExtendBlockObject
147+
// CK_AtomicToNonAtomic
148+
// CK_NonAtomicToAtomic
149+
// CK_CopyAndAutoreleaseBlockObject
150+
// CK_BuiltinFnToFnPtr
151+
// CK_ZeroToOCLOpaqueType
152+
I32EnumAttrCase<"address_space", 63>,
153+
// CK_IntToOCLSampler
154+
// CK_HLSLVectorTruncation
155+
// CK_HLSLArrayRValue
156+
// CK_HLSLElementwiseCast
157+
// CK_HLSLAggregateSplatCast
158+
159+
// Enums below are specific to CIR and don't have a correspondence to classic
160+
// codegen:
161+
I32EnumAttrCase<"bool_to_float", 1000>,
116162
]>;
117163

118164
def CastOp : CIR_Op<"cast",
@@ -121,39 +167,48 @@ def CastOp : CIR_Op<"cast",
121167
// FIXME: not all conversions are free of side effects.
122168
let summary = "Conversion between values of different types";
123169
let description = [{
124-
Apply C/C++ usual conversions rules between values. Currently supported kinds:
170+
Apply the usual C/C++ conversion rules between values. This operation models
171+
a subset of conversions as defined in Clang's `OperationKinds.def`
172+
(`llvm-project/clang/include/clang/AST/OperationKinds.def`).
173+
174+
Note: not all conversions are implemented using `cir.cast`. For instance,
175+
lvalue-to-rvalue conversion is modeled as a `cir.load` instead. Currently
176+
supported kinds:
125177

126-
- `array_to_ptrdecay`
127178
- `bitcast`
179+
- `array_to_ptrdecay`
180+
- `member_ptr_to_bool
181+
- `int_to_ptr`
182+
- `ptr_to_int`
183+
- `ptr_to_bool`
128184
- `integral`
129185
- `int_to_bool`
130186
- `int_to_float`
131-
- `floating`
132187
- `float_to_int`
133188
- `float_to_bool`
134-
- `ptr_to_int`
135-
- `ptr_to_bool`
136189
- `bool_to_int`
137-
- `bool_to_float`
138-
- `address_space`
190+
- `floating`
139191
- `float_to_complex`
140-
- `int_to_complex`
141192
- `float_complex_to_real`
142-
- `int_complex_to_real`
143193
- `float_complex_to_bool`
144-
- `int_complex_to_bool`
145194
- `float_complex`
146195
- `float_complex_to_int_complex`
196+
- `int_to_complex`
197+
- `int_complex_to_real`
198+
- `int_complex_to_bool`
147199
- `int_complex`
148200
- `int_complex_to_float_complex`
201+
- `address_space`
202+
203+
CIR also supports some additional conversions that are not part of the classic
204+
Clang codegen:
205+
206+
- `bool_to_float`
149207

150-
This is effectively a subset of the rules from
151-
`llvm-project/clang/include/clang/AST/OperationKinds.def`; but note that some
152-
of the conversions aren't implemented in terms of `cir.cast`, `lvalue-to-rvalue`
153-
for instance is modeled as a regular `cir.load`.
208+
Example:
154209

155210
```mlir
156-
%4 = cir.cast (int_to_bool, %3 : i32), !cir.bool
211+
%4 = cir.cast(int_to_bool, %3 : i32), !cir.bool
157212
...
158213
%x = cir.cast(array_to_ptrdecay, %0 : !cir.ptr<!cir.array<i32 x 10>>), !cir.ptr<i32>
159214
```
@@ -1846,10 +1901,10 @@ def CmpThreeWayOp : CIR_Op<"cmp3way", [Pure, SameTypeOperands]> {
18461901
//===----------------------------------------------------------------------===//
18471902

18481903
def CIR_CaseOpKind : CIR_I32EnumAttr<"CaseOpKind", "case kind", [
1849-
I32EnumAttrCase<"Default", 1, "default">,
1850-
I32EnumAttrCase<"Equal", 2, "equal">,
1851-
I32EnumAttrCase<"Anyof", 3, "anyof">,
1852-
I32EnumAttrCase<"Range", 4, "range">
1904+
I32EnumAttrCase<"Default", 0, "default">,
1905+
I32EnumAttrCase<"Equal", 1, "equal">,
1906+
I32EnumAttrCase<"Anyof", 2, "anyof">,
1907+
I32EnumAttrCase<"Range", 3, "range">
18531908
]>;
18541909

18551910
def CaseOp : CIR_Op<"case", [
@@ -3107,6 +3162,7 @@ def VecCreateOp : CIR_Op<"vec.create", [Pure]> {
31073162
}];
31083163

31093164
let hasVerifier = 1;
3165+
let hasFolder = 1;
31103166
}
31113167

31123168
//===----------------------------------------------------------------------===//
@@ -3169,7 +3225,7 @@ def VecCmpOp : CIR_Op<"vec.cmp", [Pure, SameTypeOperands]> {
31693225
//===----------------------------------------------------------------------===//
31703226

31713227
def VecTernaryOp : CIR_Op<"vec.ternary",
3172-
[Pure, AllTypesMatch<["result", "vec1", "vec2"]>]> {
3228+
[Pure, AllTypesMatch<["result", "lhs", "rhs"]>]> {
31733229
let summary = "The `cond ? a : b` ternary operator for vector types";
31743230
let description = [{
31753231
The `cir.vec.ternary` operation represents the C/C++ ternary operator,
@@ -3188,16 +3244,18 @@ def VecTernaryOp : CIR_Op<"vec.ternary",
31883244

31893245
let arguments = (ins
31903246
CIR_VectorOfIntType:$cond,
3191-
CIR_VectorType:$vec1,
3192-
CIR_VectorType:$vec2
3247+
CIR_VectorType:$lhs,
3248+
CIR_VectorType:$rhs
31933249
);
31943250

31953251
let results = (outs CIR_VectorType:$result);
31963252
let assemblyFormat = [{
3197-
`(` $cond `,` $vec1 `,` $vec2 `)` `:` qualified(type($cond)) `,`
3198-
qualified(type($vec1)) attr-dict
3253+
`(` $cond `,` $lhs `,` $rhs `)` `:` qualified(type($cond)) `,`
3254+
qualified(type($lhs)) attr-dict
31993255
}];
3256+
32003257
let hasVerifier = 1;
3258+
let hasFolder = 1;
32013259
}
32023260

32033261
//===----------------------------------------------------------------------===//
@@ -3595,7 +3653,9 @@ def FuncOp : CIR_Op<"func", [
35953653
OptionalAttr<GlobalCtorAttr>:$global_ctor,
35963654
OptionalAttr<GlobalDtorAttr>:$global_dtor,
35973655
OptionalAttr<ArrayAttr>:$annotations,
3598-
OptionalAttr<AnyASTFunctionDeclAttr>:$ast
3656+
OptionalAttr<AnyASTFunctionDeclAttr>:$ast,
3657+
OptionalAttr<CXXCtorAttr>:$cxx_ctor,
3658+
OptionalAttr<CXXDtorAttr>:$cxx_dtor
35993659
);
36003660

36013661
let regions = (region AnyRegion:$body);
@@ -3765,11 +3825,11 @@ def DeleteArrayOp : CIR_Op<"delete.array">,
37653825
//===----------------------------------------------------------------------===//
37663826

37673827
def CIR_SideEffect : CIR_I32EnumAttr<
3768-
"SideEffect", "allowed side effects of a function",[
3769-
I32EnumAttrCase<"All", 1, "all">,
3770-
I32EnumAttrCase<"Pure", 2, "pure">,
3771-
I32EnumAttrCase<"Const", 3, "const">
3772-
]> {
3828+
"SideEffect", "allowed side effects of a function", [
3829+
I32EnumAttrCase<"All", 0, "all">,
3830+
I32EnumAttrCase<"Pure", 1, "pure">,
3831+
I32EnumAttrCase<"Const", 2, "const">
3832+
]> {
37733833
let description = [{
37743834
The side effect attribute specifies the possible side effects of the callee
37753835
of a call operation. This is an enumeration attribute and all possible

clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,46 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID,
145145
.getResult();
146146
}
147147
case X86::BI__builtin_ia32_rdtscp: {
148-
llvm_unreachable("__rdtscp NYI");
148+
// For rdtscp, we need to create a proper struct type to hold {i64, i32}
149+
cir::RecordType resTy = builder.getAnonRecordTy(
150+
{builder.getUInt64Ty(), builder.getUInt32Ty()}, false, false);
151+
152+
auto call = builder
153+
.create<cir::LLVMIntrinsicCallOp>(
154+
getLoc(E->getExprLoc()),
155+
builder.getStringAttr("x86.rdtscp"), resTy)
156+
.getResult();
157+
158+
// Store processor ID in address param
159+
mlir::Value pID = builder.create<cir::ExtractMemberOp>(
160+
getLoc(E->getExprLoc()), builder.getUInt32Ty(), call, 1);
161+
builder.create<cir::StoreOp>(getLoc(E->getExprLoc()), pID, Ops[0]);
162+
163+
// Return the timestamp at index 0
164+
return builder.create<cir::ExtractMemberOp>(getLoc(E->getExprLoc()),
165+
builder.getUInt64Ty(), call, 0);
149166
}
150167
case X86::BI__builtin_ia32_lzcnt_u16:
151168
case X86::BI__builtin_ia32_lzcnt_u32:
152169
case X86::BI__builtin_ia32_lzcnt_u64: {
153170
mlir::Value V = builder.create<cir::ConstantOp>(
154171
getLoc(E->getExprLoc()), cir::BoolAttr::get(&getMLIRContext(), false));
155-
156172
return builder
157173
.create<cir::LLVMIntrinsicCallOp>(
158174
getLoc(E->getExprLoc()), builder.getStringAttr("ctlz"),
159175
Ops[0].getType(), mlir::ValueRange{Ops[0], V})
160176
.getResult();
161177
}
178+
case X86::BI__builtin_ia32_tzcnt_u16:
179+
case X86::BI__builtin_ia32_tzcnt_u32:
180+
case X86::BI__builtin_ia32_tzcnt_u64: {
181+
mlir::Value V = builder.create<cir::ConstantOp>(
182+
getLoc(E->getExprLoc()), cir::BoolAttr::get(&getMLIRContext(), false));
183+
return builder
184+
.create<cir::LLVMIntrinsicCallOp>(
185+
getLoc(E->getExprLoc()), builder.getStringAttr("cttz"),
186+
Ops[0].getType(), mlir::ValueRange{Ops[0], V})
187+
.getResult();
188+
}
162189
}
163190
}

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,10 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
313313
VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO) {
314314
llvm_unreachable("NYI");
315315
}
316-
mlir::Value VisitChooseExpr(ChooseExpr *CE) { llvm_unreachable("NYI"); }
316+
317+
mlir::Value VisitChooseExpr(ChooseExpr *CE) {
318+
return Visit(CE->getChosenSubExpr());
319+
}
317320

318321
mlir::Value VisitInitListExpr(InitListExpr *E);
319322

0 commit comments

Comments
 (0)