Index: llvm/docs/OpaquePointers.rst =================================================================== --- llvm/docs/OpaquePointers.rst +++ llvm/docs/OpaquePointers.rst @@ -276,27 +276,19 @@ Transition State ================ -As of January 2023: +As of July 2023: -Typed pointers are **not** supported on the ``main`` branch as a matter of -policy. Fixes for typed pointer support are not accepted. Typed pointer -support code may be removed without notice at any time. +Typed pointers are **not** supported on the ``main`` branch. -However, tests are still in the process of being converted to opaque pointers. -As such, care must be taken when actively removing typed pointer support, to -avoid breaking remaining tests. - -The following typed pointer functionality has already been removed: +The following typed pointer functionality has been removed: * The ``CLANG_ENABLE_OPAQUE_POINTERS`` cmake flag is no longer supported. * The ``-no-opaque-pointers`` cc1 clang flag is no longer supported. +* The ``-opaque-pointers`` opt flag is no longer supported. * The ``-plugin-opt=no-opaque-pointers`` LTO flag is no longer supported. * C APIs that do not support opaque pointers (like ``LLVMBuildLoad``) are no longer supported. -* Typed pointer IR and bitcode is implicitly upgraded to use opaque pointers, - unless ``-opaque-pointers=0`` is passed. The following typed pointer functionality is still to be removed: -* The ``-opaque-pointers=0`` opt flag. -* Support for typed pointers in LLVM libraries. +* Various APIs that are no longer relevant with opaque pointers. Index: llvm/docs/ReleaseNotes.rst =================================================================== --- llvm/docs/ReleaseNotes.rst +++ llvm/docs/ReleaseNotes.rst @@ -55,8 +55,9 @@ Changes to the LLVM IR ---------------------- -* Typed pointers are no longer supported. See the `opaque pointers - `__ documentation for migration instructions. +* Typed pointers are no longer supported and the ``-opaque-pointers`` option + has been removed. See the `opaque pointers `__ + documentation for migration instructions. * The ``nofpclass`` attribute was introduced. This allows more optimizations around special floating point value comparisons. Index: llvm/lib/IR/LLVMContext.cpp =================================================================== --- llvm/lib/IR/LLVMContext.cpp +++ llvm/lib/IR/LLVMContext.cpp @@ -374,9 +374,9 @@ } void LLVMContext::setOpaquePointers(bool Enable) const { - pImpl->setOpaquePointers(Enable); + assert(Enable && "Cannot disable opaque pointers"); } bool LLVMContext::supportsTypedPointers() const { - return !pImpl->getOpaquePointers(); + return false; } Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -1633,14 +1633,6 @@ /// The lifetime of the object must be guaranteed to extend as long as the /// LLVMContext is used by compilation. void setOptPassGate(OptPassGate &); - - // TODO: clean up the following after we no longer support non-opaque pointer - // types. - bool getOpaquePointers(); - void setOpaquePointers(bool OP); - -private: - std::optional OpaquePointers; }; } // end namespace llvm Index: llvm/lib/IR/LLVMContextImpl.cpp =================================================================== --- llvm/lib/IR/LLVMContextImpl.cpp +++ llvm/lib/IR/LLVMContextImpl.cpp @@ -33,10 +33,6 @@ using namespace llvm; -static cl::opt - OpaquePointersCL("opaque-pointers", cl::desc("Use opaque pointers"), - cl::init(true)); - LLVMContextImpl::LLVMContextImpl(LLVMContext &C) : DiagHandler(std::make_unique()), VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID), @@ -46,11 +42,7 @@ X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID), PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID), X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8), - Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) { - if (OpaquePointersCL.getNumOccurrences()) { - OpaquePointers = OpaquePointersCL; - } -} + Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {} LLVMContextImpl::~LLVMContextImpl() { // NOTE: We need to delete the contents of OwnedModules, but Module's dtor @@ -250,15 +242,3 @@ void LLVMContextImpl::setOptPassGate(OptPassGate& OPG) { this->OPG = &OPG; } - -bool LLVMContextImpl::getOpaquePointers() { - if (LLVM_UNLIKELY(!OpaquePointers)) - OpaquePointers = OpaquePointersCL; - return *OpaquePointers; -} - -void LLVMContextImpl::setOpaquePointers(bool OP) { - assert((!OpaquePointers || *OpaquePointers == OP) && - "Cannot change opaque pointers mode once set"); - OpaquePointers = OP; -} Index: llvm/lib/IR/Type.cpp =================================================================== --- llvm/lib/IR/Type.cpp +++ llvm/lib/IR/Type.cpp @@ -798,24 +798,12 @@ assert(EltTy && "Can't get a pointer to type!"); assert(isValidElementType(EltTy) && "Invalid type for pointer element!"); - LLVMContextImpl *CImpl = EltTy->getContext().pImpl; - // Automatically convert typed pointers to opaque pointers. - if (CImpl->getOpaquePointers()) - return get(EltTy->getContext(), AddressSpace); - - PointerType *&Entry = - CImpl->LegacyPointerTypes[std::make_pair(EltTy, AddressSpace)]; - - if (!Entry) - Entry = new (CImpl->Alloc) PointerType(EltTy, AddressSpace); - return Entry; + return get(EltTy->getContext(), AddressSpace); } PointerType *PointerType::get(LLVMContext &C, unsigned AddressSpace) { LLVMContextImpl *CImpl = C.pImpl; - assert(CImpl->getOpaquePointers() && - "Can only create opaque pointers in opaque pointer mode"); // Since AddressSpace #0 is the common case, we special case it. PointerType *&Entry = AddressSpace == 0 ? CImpl->AS0PointerType Index: llvm/test/Assembler/ptr-outside-opaque-pointers-mode.ll =================================================================== --- llvm/test/Assembler/ptr-outside-opaque-pointers-mode.ll +++ /dev/null @@ -1,7 +0,0 @@ -; RUN: not llvm-as < %s -disable-output --opaque-pointers=0 2>&1 | FileCheck %s - -; CHECK: warning: ptr type is only supported in -opaque-pointers mode -; CHECK: error: expected type -define void @f(ptr %a) { - ret void -} Index: llvm/test/Bitcode/opaque-ptr.ll =================================================================== --- llvm/test/Bitcode/opaque-ptr.ll +++ /dev/null @@ -1,10 +0,0 @@ -; RUN: llvm-as --opaque-pointers < %s | not llvm-dis --opaque-pointers=0 2>&1 | FileCheck %s - -; CHECK: error: Opaque pointers are only supported in -opaque-pointers mode - -@g = external global i16 - -define void @f(i32* %p) { - %a = alloca i17 - ret void -} Index: llvm/test/LTO/X86/Inputs/type-mapping-bug4_0.ll =================================================================== --- llvm/test/LTO/X86/Inputs/type-mapping-bug4_0.ll +++ /dev/null @@ -1,11 +0,0 @@ -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -%class.CWBD = type { float } -%"class.std::_Unique_ptr_base" = type { %class.CWBD* } - -%class.CB = type opaque - -!llvm.module.flags = !{!0, !1} -!0 = !{i32 1, !"ThinLTO", i32 0} -!1 = !{i32 2, !"Debug Info Version", i32 3} Index: llvm/test/LTO/X86/Inputs/type-mapping-bug4_1.ll =================================================================== --- llvm/test/LTO/X86/Inputs/type-mapping-bug4_1.ll +++ /dev/null @@ -1,55 +0,0 @@ -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -%class.CCSM = type opaque -%class.CWBD = type { float } - -%"class.std::_Unique_ptr_base" = type { %class.CWBD* } - -%class.CB = type { %"class.std::unique_ptr_base.1" } -; (stage1.1) -; %class.std::unique_ptr_base.1(t1.o) is mapped to %class.std::unique_ptr_base(t0.o) -; %class.CCSM(t1.o) is mapped to %class.CWBD(t0.o) -%"class.std::unique_ptr_base.1" = type { %class.CCSM* } - -; (stage1.2) -; %class.CCSM(t1.o) -> %class.CWBD(t0.o) mapping of stage1.1 maps this to -; "declare void @h(%class.CWBD*)" -declare void @h(%class.CCSM*) -define void @j() { - call void @h(%class.CCSM* undef) - ret void -} - -define void @a() { - ; Without the fix in D87001 to delay materialization of @d until its module is linked - ; (stage1.3) - ; mapping `%class.CB* undef` creates the first instance of %class.CB (%class.CB). - ; (stage2) - ; mapping `!6` starts the stage2, during which second instance of %class.CB (%class.CB.1) - ; is created for the mapped @d declaration. - ; define void @d(%class.CB.1*) - ; After this, %class.CB (t2.o) (aka %class.CB.1) and - ; %"class.std::unique_ptr_base.2" (t2.o) are added to DstStructTypesSet. - call void @llvm.dbg.value(metadata %class.CB* undef, metadata !6, metadata !DIExpression()), !dbg !4 - ret void -} - -declare void @llvm.dbg.value(metadata, metadata, metadata) - -!llvm.module.flags = !{!0, !1} -!llvm.dbg.cu = !{!2} -!0 = !{i32 1, !"ThinLTO", i32 0} -!1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3) -!3 = !DIFile(filename: "f2", directory: "") - -!4 = !DILocation(line: 117, column: 34, scope: !7) - -; This DICompositeType refers to !5 in type-mapping-bug4.ll -!5 = !DICompositeType(tag: DW_TAG_structure_type, flags: DIFlagFwdDecl, identifier: "SHARED") - -!6 = !DILocalVariable(name: "this", arg: 1, scope: !7, flags: DIFlagArtificial | DIFlagObjectPointer) -!7 = distinct !DISubprogram(name: "a", type: !8, unit: !2) -!8 = !DISubroutineType(types: !9) -!9 = !{null, !5} Index: llvm/test/LTO/X86/type-mapping-bug4.ll =================================================================== --- llvm/test/LTO/X86/type-mapping-bug4.ll +++ /dev/null @@ -1,76 +0,0 @@ -; RUN: opt -opaque-pointers=0 -module-summary -o %t0.o %S/Inputs/type-mapping-bug4_0.ll -; RUN: opt -opaque-pointers=0 -module-summary -o %t1.o %S/Inputs/type-mapping-bug4_1.ll -; RUN: opt -opaque-pointers=0 -module-summary -o %t2.o %s -; RUN: llvm-lto2 run -save-temps -o %t3 %t0.o %t1.o %t2.o -r %t1.o,a,px -r %t2.o,d,px -r %t1.o,h,x -r %t2.o,h,x -r %t1.o,j,px -; RUN: llvm-dis < %t3.0.0.preopt.bc | FileCheck %s - -; stage0: linking t0.o -; stage1: linking t1.o -; stage2: during linking t1.o, mapping @d -; stage3: linking t2.o - -; Stage0 is not described because it is not interesting for the purpose of this test. -; Stage1 and stage2 are described in type-mapping-bug4_1.ll. -; Stage3 is described in this file. - -; CHECK: %class.CB.1 = type { %"class.std::unique_ptr_base.2" } -; CHECK: %"class.std::unique_ptr_base.2" = type { ptr } - -; CHECK: define void @j() { -; CHECK: call void @h(ptr undef) -; CHECK: ret void -; CHECK: } - -; CHECK: declare void @h(ptr) - -; CHECK: define void @a() { -; CHECK: call void @llvm.dbg.value(metadata ptr undef, metadata !10, metadata !DIExpression()) -; CHECK: ret void -; CHECK: } - -; CHECK: declare void @llvm.dbg.value(metadata, metadata, metadata) #0 - -; CHECK: define void @d(ptr %0) { -; CHECK: %2 = getelementptr inbounds %class.CB.1, ptr undef, i64 0, i32 0, i32 0 -; CHECK: ret void -; CHECK: } - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -; (stage3) Remapping this type returns itself due to D47898 and stage1.3 -%class.CB = type { %"class.std::unique_ptr_base.2" } - -; (stage3) Remapping this type returns itself due to D47898 and stage2 -%"class.std::unique_ptr_base.2" = type { %class.CCSM* } - -%class.CCSM = type opaque - -; (stage3) computeTypeMapping add the mapping %class.CCSM -> %class.CWBD due to stage1.2 -declare void @h(%class.CCSM*) - -define void @d(%class.CB*) { - ; Without the fix in D87001 to delay materialization of @d until its module is linked - ; (stage3) - ; * SourceElementType of getelementptr is remapped to itself. - ; * ResultElementType of getelementptr is incorrectly remapped to %class.CWBD*. - ; Its type should be %class.CCSM*. - %2 = getelementptr inbounds %class.CB, %class.CB* undef, i64 0, i32 0, i32 0 - ret void -} - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!0, !1} -!0 = !{i32 1, !"ThinLTO", i32 0} -!1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, retainedTypes: !4) -!3 = !DIFile(filename: "f1", directory: "") -!4 = !{!5} - -; This DICompositeType is referenced by !5 in Inputs/type-mapping-bug4_1.ll -; causing the function type in !7 to be added to its module. -!5 = !DICompositeType(tag: DW_TAG_structure_type, templateParams: !6, identifier: "SHARED") -!6 = !{!7} - -; The reference to d and %class.CB that gets loaded into %t1.o -!7 = !DITemplateValueParameter(value: void (%class.CB*)* @d) Index: llvm/test/Linker/Inputs/type-unique-name.ll =================================================================== --- llvm/test/Linker/Inputs/type-unique-name.ll +++ /dev/null @@ -1,5 +0,0 @@ -%t = type { i8 } - -define %t* @f() { - ret %t* null -} Index: llvm/test/Linker/type-unique-name.ll =================================================================== --- llvm/test/Linker/type-unique-name.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: llvm-link -opaque-pointers=0 -S %s %p/Inputs/type-unique-name.ll | FileCheck %s - -; Test that we keep the type name -; CHECK: %abc = type { i8 } - -%abc = type opaque - -declare %abc* @f() - -define %abc* @g() { - %x = call %abc* @f() - ret %abc* %x -} Index: llvm/test/Other/mixed-opaque-ptrs.ll =================================================================== --- llvm/test/Other/mixed-opaque-ptrs.ll +++ /dev/null @@ -1,6 +0,0 @@ -; RUN: not llvm-as -opaque-pointers=0 -disable-output %s 2>&1 | FileCheck %s -; CHECK: ptr type is only supported in -opaque-pointers mode -define void @f(i32*) { - %a = alloca ptr - ret void -} Index: llvm/unittests/IR/ConstantsTest.cpp =================================================================== --- llvm/unittests/IR/ConstantsTest.cpp +++ llvm/unittests/IR/ConstantsTest.cpp @@ -467,9 +467,8 @@ } } -void bitcastToGEPHelper(bool useOpaquePointers) { +TEST(ConstantsTest, BitcastToGEP) { LLVMContext Context; - Context.setOpaquePointers(useOpaquePointers); std::unique_ptr M(new Module("MyModule", Context)); auto *i32 = Type::getInt32Ty(Context); @@ -481,17 +480,8 @@ new GlobalVariable(*M, S, false, GlobalValue::ExternalLinkage, nullptr); auto *PtrTy = PointerType::get(i32, 0); auto *C = ConstantExpr::getBitCast(G, PtrTy); - if (Context.supportsTypedPointers()) { - EXPECT_EQ(cast(C)->getOpcode(), Instruction::BitCast); - } else { - /* With opaque pointers, no cast is necessary. */ - EXPECT_EQ(C, G); - } -} - -TEST(ConstantsTest, BitcastToGEP) { - bitcastToGEPHelper(true); - bitcastToGEPHelper(false); + /* With opaque pointers, no cast is necessary. */ + EXPECT_EQ(C, G); } bool foldFuncPtrAndConstToNull(LLVMContext &Context, Module *TheModule, Index: llvm/unittests/IR/TypesTest.cpp =================================================================== --- llvm/unittests/IR/TypesTest.cpp +++ llvm/unittests/IR/TypesTest.cpp @@ -36,10 +36,9 @@ } TEST(TypesTest, CopyPointerType) { - LLVMContext COpaquePointers; - COpaquePointers.setOpaquePointers(true); + LLVMContext C; - PointerType *P1 = PointerType::get(COpaquePointers, 1); + PointerType *P1 = PointerType::get(C, 1); EXPECT_TRUE(P1->isOpaque()); PointerType *P1C = PointerType::getWithSamePointeeType(P1, 1); EXPECT_EQ(P1, P1C); @@ -47,18 +46,6 @@ PointerType *P1C0 = PointerType::getWithSamePointeeType(P1, 0); EXPECT_NE(P1, P1C0); EXPECT_TRUE(P1C0->isOpaque()); - - LLVMContext CTypedPointers; - CTypedPointers.setOpaquePointers(false); - Type *Int8 = Type::getInt8Ty(CTypedPointers); - PointerType *P2 = PointerType::get(Int8, 1); - EXPECT_FALSE(P2->isOpaque()); - PointerType *P2C = PointerType::getWithSamePointeeType(P2, 1); - EXPECT_EQ(P2, P2C); - EXPECT_FALSE(P2C->isOpaque()); - PointerType *P2C0 = PointerType::getWithSamePointeeType(P2, 0); - EXPECT_NE(P2, P2C0); - EXPECT_FALSE(P2C0->isOpaque()); } TEST(TypesTest, TargetExtType) {