12
12
#include " mlir/IR/Region.h"
13
13
#include " clang/AST/ASTContext.h"
14
14
#include " clang/AST/CharUnits.h"
15
+ #include " clang/AST/Decl.h"
15
16
#include " clang/AST/Mangle.h"
16
17
#include " clang/Basic/Module.h"
17
18
#include " clang/Basic/TargetInfo.h"
18
19
#include " clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
19
20
#include " clang/CIR/Dialect/IR/CIRDataLayout.h"
20
21
#include " clang/CIR/Dialect/IR/CIRDialect.h"
22
+ #include " clang/CIR/Dialect/IR/CIROpsEnums.h"
23
+ #include " clang/CIR/Dialect/IR/CIRTypes.h"
21
24
#include " clang/CIR/Dialect/Passes.h"
22
25
#include " clang/CIR/Interfaces/ASTAttrInterfaces.h"
23
26
#include " llvm/ADT/APFloat.h"
27
+ #include " llvm/ADT/STLExtras.h"
24
28
#include " llvm/ADT/SmallVector.h"
25
29
#include " llvm/ADT/StringMap.h"
26
30
#include " llvm/ADT/StringRef.h"
@@ -85,6 +89,7 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
85
89
void lowerToMemCpy (StoreOp op);
86
90
void lowerArrayDtor (ArrayDtor op);
87
91
void lowerArrayCtor (ArrayCtor op);
92
+ void lowerStdInitializerListOp (StdInitializerListOp op);
88
93
89
94
// / Collect annotations of global values in the module
90
95
void addGlobalAnnotations (mlir::Operation *op, mlir::ArrayAttr annotations);
@@ -1120,6 +1125,79 @@ void LoweringPreparePass::lowerIterEndOp(IterEndOp op) {
1120
1125
op.erase ();
1121
1126
}
1122
1127
1128
+ // / lowering construction of std::initializer_list.
1129
+ // / 1. alloca array for arg list.
1130
+ // / 2. copy arg list to array.
1131
+ // / 3. construct std::initializer_list from array.
1132
+ void LoweringPreparePass::lowerStdInitializerListOp (StdInitializerListOp op) {
1133
+ auto loc = op.getLoc ();
1134
+ cir::CIRDataLayout dataLayout (theModule);
1135
+ auto args = op.getArgs ();
1136
+
1137
+ auto stdInitializerListType = mlir::cast<cir::StructType>(
1138
+ mlir::cast<cir::PointerType>(op.getInitList ().getType ()).getPointee ());
1139
+ clang::RecordDecl::field_range stdInitializerListFields =
1140
+ stdInitializerListType.getAst ().getRawDecl ()->fields ();
1141
+
1142
+ mlir::Type elementType =
1143
+ mlir::cast<cir::PointerType>(stdInitializerListType.getMembers ()[0 ])
1144
+ .getPointee ();
1145
+ auto tempArrayType =
1146
+ cir::ArrayType::get (&getContext (), elementType, args.size ());
1147
+
1148
+ CIRBaseBuilderTy builder (getContext ());
1149
+ builder.setInsertionPointAfter (op);
1150
+
1151
+ IntegerAttr alignment = builder.getI64IntegerAttr (
1152
+ dataLayout.getPrefTypeAlign (tempArrayType).value ());
1153
+ assert (!cir::MissingFeatures::addressSpace ());
1154
+ mlir::Value arrayPtr = builder.createAlloca (
1155
+ loc, cir::PointerType::get (tempArrayType), tempArrayType, " " , alignment);
1156
+ mlir::Value arrayStartPtr =
1157
+ builder.createCast (cir::CastKind::array_to_ptrdecay, arrayPtr,
1158
+ cir::PointerType::get (elementType));
1159
+ for (unsigned i = 0 ; i < args.size (); i++) {
1160
+ if (i == 0 ) {
1161
+ builder.createStore (loc, args[i], arrayStartPtr);
1162
+ } else {
1163
+ mlir::Value offset = builder.getUnsignedInt (loc, i, 64 );
1164
+ mlir::Value dest = builder.create <cir::PtrStrideOp>(
1165
+ loc, arrayStartPtr.getType (), arrayStartPtr, offset);
1166
+ builder.createStore (loc, args[i], dest);
1167
+ }
1168
+ }
1169
+
1170
+ // FIXME(cir): better handling according to different field type. [ptr ptr],
1171
+ // [ptr size], [size ptr].
1172
+
1173
+ clang::RecordDecl::field_iterator it = stdInitializerListFields.begin ();
1174
+ const clang::RecordDecl::field_iterator startField = it;
1175
+ const unsigned startIdx = 0U ;
1176
+ const clang::RecordDecl::field_iterator endOrSizeField = ++it;
1177
+ const unsigned endOrSizeIdx = 1U ;
1178
+ assert (llvm::range_size (stdInitializerListFields) == 2U );
1179
+
1180
+ mlir::Value startMemberPtr = builder.createGetMemberOp (
1181
+ loc, op.getInitList (), startField->getName ().data (), startIdx);
1182
+ builder.createStore (loc, arrayStartPtr, startMemberPtr);
1183
+
1184
+ mlir::Value size = builder.getUnsignedInt (loc, args.size (), 64 );
1185
+ if (endOrSizeField->getType ()->isPointerType ()) {
1186
+ mlir::Value arrayEndPtr = builder.create <cir::PtrStrideOp>(
1187
+ loc, arrayStartPtr.getType (), arrayStartPtr, size);
1188
+ mlir::Value endMemberPtr = builder.createGetMemberOp (
1189
+ loc, op.getInitList (), endOrSizeField->getName ().data (), endOrSizeIdx);
1190
+ builder.createStore (loc, arrayEndPtr, endMemberPtr);
1191
+ } else {
1192
+ assert (endOrSizeField->getType ()->isIntegerType ());
1193
+ mlir::Value sizeMemberPtr = builder.createGetMemberOp (
1194
+ loc, op.getInitList (), endOrSizeField->getName ().data (), endOrSizeIdx);
1195
+ builder.createStore (loc, size, sizeMemberPtr);
1196
+ }
1197
+
1198
+ op.erase ();
1199
+ }
1200
+
1123
1201
void LoweringPreparePass::addGlobalAnnotations (mlir::Operation *op,
1124
1202
mlir::ArrayAttr annotations) {
1125
1203
auto globalValue = cast<mlir::SymbolOpInterface>(op);
@@ -1180,6 +1258,8 @@ void LoweringPreparePass::runOnOp(Operation *op) {
1180
1258
}
1181
1259
if (std::optional<mlir::ArrayAttr> annotations = fnOp.getAnnotations ())
1182
1260
addGlobalAnnotations (fnOp, annotations.value ());
1261
+ } else if (auto stdInitializerListOp = dyn_cast<StdInitializerListOp>(op)) {
1262
+ lowerStdInitializerListOp (stdInitializerListOp);
1183
1263
}
1184
1264
}
1185
1265
@@ -1195,7 +1275,8 @@ void LoweringPreparePass::runOnOperation() {
1195
1275
op->walk ([&](Operation *op) {
1196
1276
if (isa<UnaryOp, BinOp, CastOp, ComplexBinOp, CmpThreeWayOp, VAArgOp,
1197
1277
GlobalOp, DynamicCastOp, StdFindOp, IterEndOp, IterBeginOp,
1198
- ArrayCtor, ArrayDtor, cir::FuncOp, StoreOp>(op))
1278
+ ArrayCtor, ArrayDtor, cir::FuncOp, StoreOp, StdInitializerListOp>(
1279
+ op))
1199
1280
opsToTransform.push_back (op);
1200
1281
});
1201
1282
0 commit comments