Skip to content

Commit b70bb5e

Browse files
authored
Merge branch 'main' into cir_complex_lvalue_to_rvalue_bc
2 parents c3fe763 + d3ee486 commit b70bb5e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2047
-330
lines changed

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,60 @@ def CIR_GlobalDtorAttr : CIR_GlobalCtorDtor<"Dtor", "dtor"> {
12711271
}];
12721272
}
12731273

1274+
def CIR_CtorKind : CIR_I32EnumAttr<"CtorKind", "CXX Constructor Kind", [
1275+
I32EnumAttrCase<"Custom", 0, "custom">,
1276+
I32EnumAttrCase<"Default", 1, "default">,
1277+
I32EnumAttrCase<"Copy", 2, "copy">,
1278+
]> {
1279+
let genSpecializedAttr = 0;
1280+
}
1281+
1282+
def CIR_CXXCtorAttr : CIR_Attr<"CXXCtor", "cxx_ctor"> {
1283+
let summary = "Marks a function as a CXX constructor";
1284+
let description = [{
1285+
Functions with this attribute are CXX constructors.
1286+
The `custom` kind is used if the constructor is a custom constructor.
1287+
The `default` kind is used if the constructor is a default constructor.
1288+
The `copy` kind is used if the constructor is a copy constructor.
1289+
}];
1290+
let parameters = (ins "mlir::Type":$type,
1291+
EnumParameter<CIR_CtorKind>:$ctorKind);
1292+
1293+
let assemblyFormat = [{
1294+
`<` $type `,` $ctorKind `>`
1295+
}];
1296+
1297+
let builders = [
1298+
AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
1299+
CArg<"CtorKind", "cir::CtorKind::Custom">:$ctorKind), [{
1300+
return $_get(type.getContext(), type, ctorKind);
1301+
}]>
1302+
];
1303+
}
1304+
1305+
def CIR_CXXDtorAttr : CIR_Attr<"CXXDtor", "cxx_dtor"> {
1306+
let summary = "Marks a function as a CXX destructor";
1307+
let description = [{
1308+
Functions with this attribute are CXX destructors
1309+
}];
1310+
let parameters = (ins "mlir::Type":$type);
1311+
1312+
let assemblyFormat = [{
1313+
`<` $type `>`
1314+
}];
1315+
1316+
let builders = [
1317+
AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{
1318+
return $_get(type.getContext(), type);
1319+
}]>
1320+
];
1321+
}
1322+
1323+
def CIR_CXXSpecialMemberAttr : AnyAttrOf<[
1324+
CIR_CXXCtorAttr,
1325+
CIR_CXXDtorAttr
1326+
]>;
1327+
12741328
def CIR_BitfieldInfoAttr : CIR_Attr<"BitfieldInfo", "bitfield_info"> {
12751329
let summary = "Represents a bit field info";
12761330
let description = [{

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,6 +3132,58 @@ def CIR_GetMethodOp : CIR_Op<"get_method"> {
31323132
let hasVerifier = 1;
31333133
}
31343134

3135+
//===----------------------------------------------------------------------===//
3136+
// GetElementOp
3137+
//===----------------------------------------------------------------------===//
3138+
3139+
def CIR_GetElementOp : CIR_Op<"get_element"> {
3140+
let summary = "Get the address of an array element";
3141+
let description = [{
3142+
The `cir.get_element` operation gets the address of a particular element
3143+
from the `base` array.
3144+
3145+
It expects a pointer to the `base` array and the `index` of the element.
3146+
3147+
Example:
3148+
```mlir
3149+
// Suppose we have a array.
3150+
!s32i = !cir.int<s, 32>
3151+
!arr_ty = !cir.array<!s32i x 4>
3152+
3153+
// Get the address of the element at index 1.
3154+
%elem_1 = cir.get_element %0[1] : (!cir.ptr<!array_ty>, !s32i) -> !cir.ptr<!s32i>
3155+
3156+
// Get the address of the element at index %i.
3157+
%i = ...
3158+
%elem_i = cir.get_element %0[%i] : (!cir.ptr<!array_ty>, !s32i) -> !cir.ptr<!s32i>
3159+
```
3160+
}];
3161+
3162+
let arguments = (ins
3163+
Arg<CIR_PtrToArray, "the base address of the array ">:$base,
3164+
Arg<CIR_AnyFundamentalIntType, "the index of the element">:$index
3165+
);
3166+
3167+
let results = (outs CIR_PointerType:$result);
3168+
3169+
let assemblyFormat = [{
3170+
$base `[` $index `]` `:` `(` qualified(type($base)) `,` qualified(type($index)) `)`
3171+
`->` qualified(type($result)) attr-dict
3172+
}];
3173+
3174+
let extraClassDeclaration = [{
3175+
// Get the type of the element.
3176+
mlir::Type getElementType() {
3177+
return getType().getPointee();
3178+
}
3179+
cir::PointerType getBaseType() {
3180+
return mlir::cast<cir::PointerType>(getBase().getType());
3181+
}
3182+
}];
3183+
3184+
let hasVerifier = 1;
3185+
}
3186+
31353187
//===----------------------------------------------------------------------===//
31363188
// VecInsertOp
31373189
//===----------------------------------------------------------------------===//
@@ -3724,6 +3776,7 @@ def FuncOp : CIR_Op<"func", [
37243776
CIR_OptionalPriorityAttr:$global_ctor_priority,
37253777
CIR_OptionalPriorityAttr:$global_dtor_priority,
37263778
OptionalAttr<ArrayAttr>:$annotations,
3779+
OptionalAttr<CIR_CXXSpecialMemberAttr>:$cxx_special_member,
37273780
OptionalAttr<AnyASTFunctionDeclAttr>:$ast
37283781
);
37293782

clang/lib/CIR/CodeGen/CIRGenBuilder.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,48 @@ mlir::Value CIRGenBuilderTy::maybeBuildArrayDecay(mlir::Location loc,
2828
return arrayPtr;
2929
}
3030

31-
mlir::Value CIRGenBuilderTy::getArrayElement(mlir::Location arrayLocBegin,
31+
mlir::Value CIRGenBuilderTy::promoteArrayIndex(const clang::TargetInfo &ti,
32+
mlir::Location loc,
33+
mlir::Value index) {
34+
// Get the array index type.
35+
auto arrayIndexWidth = ti.getTypeWidth(clang::TargetInfo::IntType::SignedInt);
36+
mlir::Type arrayIndexType = getSIntNTy(arrayIndexWidth);
37+
38+
// If this is a boolean, zero-extend it to the array index type.
39+
if (auto boolTy = mlir::dyn_cast<cir::BoolType>(index.getType()))
40+
return create<cir::CastOp>(loc, arrayIndexType, cir::CastKind::bool_to_int,
41+
index);
42+
43+
// If this an integer, ensure that it is at least as width as the array index
44+
// type.
45+
if (auto intTy = mlir::dyn_cast<cir::IntType>(index.getType())) {
46+
if (intTy.getWidth() < arrayIndexWidth)
47+
return create<cir::CastOp>(loc, arrayIndexType, cir::CastKind::integral,
48+
index);
49+
}
50+
51+
return index;
52+
}
53+
54+
mlir::Value CIRGenBuilderTy::getArrayElement(const clang::TargetInfo &ti,
55+
mlir::Location arrayLocBegin,
3256
mlir::Location arrayLocEnd,
3357
mlir::Value arrayPtr,
3458
mlir::Type eltTy, mlir::Value idx,
3559
bool shouldDecay) {
60+
auto arrayPtrTy = mlir::dyn_cast<cir::PointerType>(arrayPtr.getType());
61+
assert(arrayPtrTy && "expected pointer type");
62+
63+
// If the array pointer is not decayed, emit a GetElementOp.
64+
auto arrayTy = mlir::dyn_cast<cir::ArrayType>(arrayPtrTy.getPointee());
65+
if (shouldDecay && arrayTy && arrayTy == eltTy) {
66+
auto eltPtrTy =
67+
getPointerTo(arrayTy.getElementType(), arrayPtrTy.getAddrSpace());
68+
return create<cir::GetElementOp>(arrayLocEnd, eltPtrTy, arrayPtr,
69+
promoteArrayIndex(ti, arrayLocBegin, idx));
70+
}
71+
72+
// If we don't have sufficient type information, emit a PtrStrideOp.
3673
mlir::Value basePtr = arrayPtr;
3774
if (shouldDecay)
3875
basePtr = maybeBuildArrayDecay(arrayLocBegin, arrayPtr, eltTy);

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "clang/AST/Decl.h"
1818
#include "clang/AST/Type.h"
19+
#include "clang/Basic/TargetInfo.h"
1920
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
2021
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
2122
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
@@ -1030,10 +1031,15 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
10301031
return create<cir::GetRuntimeMemberOp>(loc, resultTy, objectPtr, memberPtr);
10311032
}
10321033

1034+
/// Promote a value for use as an array index.
1035+
mlir::Value promoteArrayIndex(const clang::TargetInfo &TargetInfo,
1036+
mlir::Location loc, mlir::Value index);
1037+
10331038
/// Create a cir.ptr_stride operation to get access to an array element.
10341039
/// idx is the index of the element to access, shouldDecay is true if the
10351040
/// result should decay to a pointer to the element type.
1036-
mlir::Value getArrayElement(mlir::Location arrayLocBegin,
1041+
mlir::Value getArrayElement(const clang::TargetInfo &targetInfo,
1042+
mlir::Location arrayLocBegin,
10371043
mlir::Location arrayLocEnd, mlir::Value arrayPtr,
10381044
mlir::Type eltTy, mlir::Value idx,
10391045
bool shouldDecay);

0 commit comments

Comments
 (0)