@@ -306,51 +306,120 @@ void CIRGenFunction::buildInvariantStart([[maybe_unused]] CharUnits Size) {
306
306
assert (!MissingFeatures::createInvariantIntrinsic ());
307
307
}
308
308
309
- void CIRGenModule::codegenGlobalInitCxxStructor (const VarDecl *D,
310
- mlir::cir::GlobalOp Addr,
311
- bool NeedsCtor, bool NeedsDtor,
312
- bool isCstStorage) {
313
- assert (D && " Expected a global declaration!" );
314
- CIRGenFunction CGF{*this , builder, true };
315
- CurCGF = &CGF;
316
- CurCGF->CurFn = Addr;
317
- Addr.setAstAttr (mlir::cir::ASTVarDeclAttr::get (builder.getContext (), D));
309
+ void CIRGenModule::buildCXXGlobalVarDeclInit (const VarDecl *varDecl,
310
+ mlir::cir::GlobalOp addr,
311
+ bool performInit) {
312
+ const Expr *init = varDecl->getInit ();
313
+ QualType ty = varDecl->getType ();
314
+
315
+ // TODO: handle address space
316
+ // The address space of a static local variable (DeclPtr) may be different
317
+ // from the address space of the "this" argument of the constructor. In that
318
+ // case, we need an addrspacecast before calling the constructor.
319
+ //
320
+ // struct StructWithCtor {
321
+ // __device__ StructWithCtor() {...}
322
+ // };
323
+ // __device__ void foo() {
324
+ // __shared__ StructWithCtor s;
325
+ // ...
326
+ // }
327
+ //
328
+ // For example, in the above CUDA code, the static local variable s has a
329
+ // "shared" address space qualifier, but the constructor of StructWithCtor
330
+ // expects "this" in the "generic" address space.
331
+ assert (!MissingFeatures::addressSpace ());
332
+
333
+ if (getLangOpts ().OpenMP && !getLangOpts ().OpenMPSimd &&
334
+ varDecl->hasAttr <OMPThreadPrivateDeclAttr>()) {
335
+ llvm_unreachable (" NYI" );
336
+ }
318
337
319
- if (NeedsCtor) {
320
- mlir::OpBuilder::InsertionGuard guard (builder);
321
- auto block = builder.createBlock (&Addr.getCtorRegion ());
322
- CIRGenFunction::LexicalScope lexScope{*CurCGF, Addr.getLoc (),
323
- builder.getInsertionBlock ()};
324
- lexScope.setAsGlobalInit ();
338
+ assert (varDecl && " Expected a global declaration!" );
339
+ CIRGenFunction cgf{*this , builder, true };
340
+ CurCGF = &cgf;
341
+ CurCGF->CurFn = addr;
325
342
326
- builder.setInsertionPointToStart (block);
327
- Address DeclAddr (getAddrOfGlobalVar (D), getASTContext ().getDeclAlign (D));
328
- buildDeclInit (CGF, D, DeclAddr);
329
- builder.setInsertionPointToEnd (block);
330
- builder.create <mlir::cir::YieldOp>(Addr->getLoc ());
331
- }
343
+ CIRGenFunction::SourceLocRAIIObject fnLoc{cgf,
344
+ getLoc (varDecl->getLocation ())};
332
345
333
- if (isCstStorage) {
334
- // TODO: this leads to a missing feature in the moment, probably also need a
335
- // LexicalScope to be inserted here.
336
- buildDeclInvariant (CGF, D);
337
- } else {
338
- // If not constant storage we'll emit this regardless of NeedsDtor value.
346
+ addr.setAstAttr (
347
+ mlir::cir::ASTVarDeclAttr::get (builder.getContext (), varDecl));
348
+
349
+ if (ty->isReferenceType ()) {
339
350
mlir::OpBuilder::InsertionGuard guard (builder);
340
- auto block = builder.createBlock (&Addr. getDtorRegion ());
341
- CIRGenFunction::LexicalScope lexScope{*CurCGF, Addr .getLoc (),
351
+ auto * block = builder.createBlock (&addr. getCtorRegion ());
352
+ CIRGenFunction::LexicalScope lexScope{*CurCGF, addr .getLoc (),
342
353
builder.getInsertionBlock ()};
343
354
lexScope.setAsGlobalInit ();
344
-
345
355
builder.setInsertionPointToStart (block);
346
- buildDeclDestroy (CGF, D);
356
+ auto getGlobal = builder.createGetGlobal (addr);
357
+
358
+ Address declAddr (getGlobal, getGlobal.getType (),
359
+ getASTContext ().getDeclAlign (varDecl));
360
+ assert (performInit && " cannot have constant initializer which needs "
361
+ " destruction for reference" );
362
+ RValue rv = cgf.buildReferenceBindingToExpr (init);
363
+ {
364
+ mlir::OpBuilder::InsertionGuard guard (builder);
365
+ mlir::Operation *rvalueDefOp = rv.getScalarVal ().getDefiningOp ();
366
+ if (rvalueDefOp && rvalueDefOp->getBlock ()) {
367
+ mlir::Block *rvalSrcBlock = rvalueDefOp->getBlock ();
368
+ if (!rvalSrcBlock->empty () &&
369
+ isa<mlir::cir::YieldOp>(rvalSrcBlock->back ())) {
370
+ auto &front = rvalSrcBlock->front ();
371
+ getGlobal.getDefiningOp ()->moveBefore (&front);
372
+ auto yield = cast<mlir::cir::YieldOp>(rvalSrcBlock->back ());
373
+ builder.setInsertionPoint (yield);
374
+ }
375
+ }
376
+ cgf.buildStoreOfScalar (rv.getScalarVal (), declAddr, false , ty);
377
+ }
347
378
builder.setInsertionPointToEnd (block);
348
- if (block->empty ()) {
349
- block->erase ();
350
- // Don't confuse lexical cleanup.
351
- builder.clearInsertionPoint ();
352
- } else
353
- builder.create <mlir::cir::YieldOp>(Addr->getLoc ());
379
+ builder.create <mlir::cir::YieldOp>(addr->getLoc ());
380
+ } else {
381
+ bool needsDtor = varDecl->needsDestruction (getASTContext ()) ==
382
+ QualType::DK_cxx_destructor;
383
+ // PerformInit, constant store invariant / destroy handled below.
384
+ bool isConstantStorage =
385
+ varDecl->getType ().isConstantStorage (getASTContext (), true , !needsDtor);
386
+ if (performInit) {
387
+ mlir::OpBuilder::InsertionGuard guard (builder);
388
+ auto *block = builder.createBlock (&addr.getCtorRegion ());
389
+ CIRGenFunction::LexicalScope lexScope{*CurCGF, addr.getLoc (),
390
+ builder.getInsertionBlock ()};
391
+ lexScope.setAsGlobalInit ();
392
+
393
+ builder.setInsertionPointToStart (block);
394
+ Address declAddr (getAddrOfGlobalVar (varDecl),
395
+ getASTContext ().getDeclAlign (varDecl));
396
+ buildDeclInit (cgf, varDecl, declAddr);
397
+ builder.setInsertionPointToEnd (block);
398
+ builder.create <mlir::cir::YieldOp>(addr->getLoc ());
399
+ }
400
+
401
+ if (isConstantStorage) {
402
+ // TODO: this leads to a missing feature in the moment, probably also need
403
+ // a LexicalScope to be inserted here.
404
+ buildDeclInvariant (cgf, varDecl);
405
+ } else {
406
+ // If not constant storage we'll emit this regardless of NeedsDtor value.
407
+ mlir::OpBuilder::InsertionGuard guard (builder);
408
+ auto *block = builder.createBlock (&addr.getDtorRegion ());
409
+ CIRGenFunction::LexicalScope lexScope{*CurCGF, addr.getLoc (),
410
+ builder.getInsertionBlock ()};
411
+ lexScope.setAsGlobalInit ();
412
+
413
+ builder.setInsertionPointToStart (block);
414
+ buildDeclDestroy (cgf, varDecl);
415
+ builder.setInsertionPointToEnd (block);
416
+ if (block->empty ()) {
417
+ block->erase ();
418
+ // Don't confuse lexical cleanup.
419
+ builder.clearInsertionPoint ();
420
+ } else
421
+ builder.create <mlir::cir::YieldOp>(addr->getLoc ());
422
+ }
354
423
}
355
424
356
425
CurCGF = nullptr ;
0 commit comments