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.
Changes to the LLVM IR
----------------------
-* Typed pointers are no longer supported. See the `opaque pointers
- <OpaquePointers.html>`__ documentation for migration instructions.
+* Typed pointers are no longer supported and the ``-opaque-pointers`` option
+ has been removed. See the `opaque pointers <OpaquePointers.html>`__
+ documentation for migration instructions.
* The ``nofpclass`` attribute was introduced. This allows more
optimizations around special floating point value comparisons.
}
void LLVMContext::setOpaquePointers(bool Enable) const {
- pImpl->setOpaquePointers(Enable);
+ assert(Enable && "Cannot disable opaque pointers");
}
bool LLVMContext::supportsTypedPointers() const {
- return !pImpl->getOpaquePointers();
+ return false;
}
using namespace llvm;
-static cl::opt<bool>
- OpaquePointersCL("opaque-pointers", cl::desc("Use opaque pointers"),
- cl::init(true));
-
LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
: DiagHandler(std::make_unique<DiagnosticHandler>()),
VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID),
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
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;
-}
/// 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<bool> OpaquePointers;
};
} // end namespace llvm
assert(EltTy && "Can't get a pointer to <null> 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
+++ /dev/null
-; 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
-}
+++ /dev/null
-; 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
-}
+++ /dev/null
-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}
+++ /dev/null
-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}
+++ /dev/null
-; 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)
+++ /dev/null
-%t = type { i8 }
-
-define %t* @f() {
- ret %t* null
-}
+++ /dev/null
-; 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
-}
+++ /dev/null
-; 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
-}