diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 56e20ade88b2..6c26f7e631e7 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -162,6 +162,7 @@ struct MissingFeatures { static bool armComputeVolatileBitfields() { return false; } static bool insertBuiltinUnpredictable() { return false; } static bool createInvariantGroup() { return false; } + static bool createInvariantIntrinsic() { return false; } static bool addAutoInitAnnotation() { return false; } static bool addHeapAllocSiteMetadata() { return false; } static bool loopInfoStack() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp index 9b7032993399..85013189fd7e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp @@ -291,6 +291,21 @@ mlir::cir::FuncOp CIRGenModule::codegenCXXStructor(GlobalDecl GD) { return Fn; } +/// Emit code to cause the variable at the given address to be considered as +/// constant from this point onwards. +static void buildDeclInvariant(CIRGenFunction &CGF, const VarDecl *D) { + return CGF.buildInvariantStart( + CGF.getContext().getTypeSizeInChars(D->getType())); +} + +void CIRGenFunction::buildInvariantStart([[maybe_unused]] CharUnits Size) { + // Do not emit the intrinsic if we're not optimizing. + if (!CGM.getCodeGenOpts().OptimizationLevel) + return; + + assert(!MissingFeatures::createInvariantIntrinsic()); +} + void CIRGenModule::codegenGlobalInitCxxStructor(const VarDecl *D, mlir::cir::GlobalOp Addr, bool NeedsCtor, bool NeedsDtor, @@ -312,8 +327,7 @@ void CIRGenModule::codegenGlobalInitCxxStructor(const VarDecl *D, } if (isCstStorage) { - // buildDeclInvariant(CGF, D, DeclPtr); - llvm_unreachable("NYI"); + buildDeclInvariant(CGF, D); } else { // If not constant storage we'll emit this regardless of NeedsDtor value. mlir::OpBuilder::InsertionGuard guard(builder); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index c411b86ac067..7d665305a25c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -866,6 +866,8 @@ class CIRGenFunction : public CIRGenTypeCache { mlir::Value buildRuntimeCall(mlir::Location loc, mlir::cir::FuncOp callee, ArrayRef args = {}); + void buildInvariantStart(CharUnits Size); + /// Create a check for a function parameter that may potentially be /// declared as non-null. void buildNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 09de029444ce..ea0edea495dd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -2150,8 +2150,7 @@ void CIRGenItaniumCXXABI::registerGlobalDtor(CIRGenFunction &CGF, llvm_unreachable("NYI"); // The default behavior is to use atexit. This is handled in lowering - // prepare. For now just emit the body for the dtor. - // .... + // prepare. Nothing to be done for CIR here. } mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam( diff --git a/clang/test/CIR/CodeGen/global-new.cpp b/clang/test/CIR/CodeGen/global-new.cpp index 4e0f604e1291..d2130a877348 100644 --- a/clang/test/CIR/CodeGen/global-new.cpp +++ b/clang/test/CIR/CodeGen/global-new.cpp @@ -21,9 +21,17 @@ e *g = new e(0); // CIR_AFTER: {{%.*}} = cir.const #cir.int<1> : !u64i // CIR_AFTER: {{%.*}} = cir.call @_Znwm(%1) : (!u64i) -> !cir.ptr -// LLVM-DAG: @llvm.global_ctors = appending constant [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65536, ptr @__cxx_global_var_init, ptr null }] +// LLVM-DAG: @llvm.global_ctors = appending constant [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65536, ptr @__cxx_global_var_init, ptr null }, { i32, ptr, ptr } { i32 65536, ptr @__cxx_global_var_init.1, ptr null }] // LLVM: define internal void @__cxx_global_var_init() // LLVM: call ptr @_Znwm(i64 1) +// LLVM: define internal void @__cxx_global_var_init.1() +// LLVM: call ptr @_Znwm(i64 1) + // LLVM: define void @_GLOBAL__sub_I_global_new.cpp() // LLVM: call void @__cxx_global_var_init() +// LLVM: call void @__cxx_global_var_init.1() + +struct PackedStruct { +}; +PackedStruct*const packed_2 = new PackedStruct(); \ No newline at end of file