Skip to content

Commit

Permalink
Enforce opaque IR pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
kinke committed May 12, 2024
1 parent 94af2f8 commit 3067b7b
Show file tree
Hide file tree
Showing 11 changed files with 19 additions and 165 deletions.
11 changes: 1 addition & 10 deletions driver/cl_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,12 +710,6 @@ cl::opt<bool> dynamicCompileTlsWorkaround(
cl::Hidden);
#endif

#if LDC_LLVM_VER >= 1700
bool enableOpaqueIRPointers = true; // typed pointers are no longer supported from LLVM 17
#else
bool enableOpaqueIRPointers = false;
#endif

static cl::extrahelp
footer("\n"
"-d-debug can also be specified without options, in which case it "
Expand Down Expand Up @@ -775,9 +769,6 @@ void createClashingOptions() {
"Hardware floating-point ABI and instructions")));

renameAndHide("opaque-pointers", nullptr); // remove
new cl::opt<bool, true>(
"opaque-pointers", cl::ZeroOrMore, cl::location(enableOpaqueIRPointers),
cl::desc("Use opaque IR pointers (experimental!)"), cl::Hidden);
}

/// Hides command line options exposed from within LLVM that are unlikely
Expand Down Expand Up @@ -865,7 +856,7 @@ void hideLLVMOptions() {
"no-discriminators", "no-integrated-as", "no-type-check", "no-xray-index",
"nozero-initialized-in-bss", "nvptx-sched4reg",
"objc-arc-annotation-target-identifier",
"object-size-offset-visitor-max-visit-instructions", "opaque-pointers",
"object-size-offset-visitor-max-visit-instructions",
"pgo-block-coverage", "pgo-temporal-instrumentation",
"pgo-view-block-coverage-graph",
"pie-copy-relocations", "poison-checking-function-local",
Expand Down
2 changes: 0 additions & 2 deletions driver/cl_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,4 @@ extern cl::opt<bool> dynamicCompileTlsWorkaround;
#else
constexpr bool enableDynamicCompile = false;
#endif

extern bool enableOpaqueIRPointers;
}
22 changes: 5 additions & 17 deletions driver/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -558,15 +558,13 @@ void parseCommandLine(Strings &sourceFiles) {
global.params.dihdr.fullOutput = opts::hdrKeepAllBodies;
global.params.disableRedZone = opts::disableRedZone();

// enforce opaque IR pointers
#if LDC_LLVM_VER >= 1700
if (!opts::enableOpaqueIRPointers)
error(Loc(),
"LLVM version 17 or above only supports --opaque-pointers=true");
// supports opaque IR pointers only
#elif LDC_LLVM_VER >= 1500
getGlobalContext().setOpaquePointers(opts::enableOpaqueIRPointers);
#else
if (opts::enableOpaqueIRPointers)
getGlobalContext().enableOpaquePointers();
getGlobalContext().setOpaquePointers(true);
#else // LLVM 14
getGlobalContext().enableOpaquePointers();
#endif
}

Expand Down Expand Up @@ -1023,16 +1021,6 @@ void registerPredefinedVersions() {
VersionCondition::addPredefinedGlobalIdent("LDC_ThreadSanitizer");
}

// Set a version identifier for whether opaque pointers are enabled or not. (needed e.g. for intrinsic mangling)
#if LDC_LLVM_VER >= 1700
// Since LLVM 17, IR pointers are always opaque.
VersionCondition::addPredefinedGlobalIdent("LDC_LLVM_OpaquePointers");
#else
if (!getGlobalContext().supportsTypedPointers()) {
VersionCondition::addPredefinedGlobalIdent("LDC_LLVM_OpaquePointers");
}
#endif

// Expose LLVM version to runtime
#define STR(x) #x
#define XSTR(x) STR(x)
Expand Down
5 changes: 0 additions & 5 deletions gen/dvalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,7 @@ DRValue *DLValue::getRVal() {
////////////////////////////////////////////////////////////////////////////////

DSpecialRefValue::DSpecialRefValue(Type *t, LLValue *v) : DLValue(v, t) {
#if LDC_LLVM_VER >= 1700 // LLVM >= 17 uses opaque pointers, type check boils
// down to pointer check only.
assert(v->getType()->isPointerTy());
#else
assert(v->getType() == DtoPtrToType(t)->getPointerTo());
#endif
}

DRValue *DSpecialRefValue::getRVal() {
Expand Down
5 changes: 0 additions & 5 deletions gen/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -808,12 +808,7 @@ void defineParameters(IrFuncTy &irFty, VarDeclarations &parameters) {
if (irparam->arg->byref) {
// The argument is an appropriate lvalue passed by reference.
// Use the passed pointer as parameter storage.
#if LDC_LLVM_VER >= 1700 // LLVM >= 17 uses opaque pointers, type check boils
// down to pointer check only.
assert(irparam->value->getType()->isPointerTy());
#else
assert(irparam->value->getType() == DtoPtrToType(paramType));
#endif
} else {
// Let the ABI transform the parameter back to an lvalue.
irparam->value =
Expand Down
26 changes: 2 additions & 24 deletions gen/llvmhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1927,31 +1927,9 @@ DValue *makeVarDValue(Type *type, VarDeclaration *vd, llvm::Value *storage) {
val = getIrValue(vd);
}

// We might need to cast.
llvm::Type *expectedType = DtoPtrToType(type);
const bool isSpecialRef = isSpecialRefVar(vd);
if (isSpecialRef)
expectedType = expectedType->getPointerTo();

if (val->getType() != expectedType) {
#if LDC_LLVM_VER < 1500
// The type of globals is determined by their initializer, and the front-end
// may inject implicit casts for class references and static arrays.
assert(vd->isDataseg() || (vd->storage_class & STCextern) ||
type->toBasetype()->ty == TY::Tclass ||
type->toBasetype()->ty == TY::Tsarray);
llvm::Type *pointeeType = val->getType()->getPointerElementType();
if (isSpecialRef)
pointeeType = pointeeType->getPointerElementType();
// Make sure that the type sizes fit - '==' instead of '<=' should probably
// work as well.
assert(getTypeAllocSize(DtoType(type)) <= getTypeAllocSize(pointeeType) &&
"LValue type mismatch, encountered type too small.");
#endif
val = DtoBitCast(val, expectedType);
}
assert(val->getType()->isPointerTy());

if (isSpecialRef)
if (isSpecialRefVar(vd))
return new DSpecialRefValue(type, val);

return new DLValue(type, val);
Expand Down
20 changes: 0 additions & 20 deletions gen/tollvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,27 +595,7 @@ LLType *stripAddrSpaces(LLType *t)
if (!pt)
return t;

#if LDC_LLVM_VER >= 1700
return getVoidPtrType();
#else
if (pt->isOpaque())
return getVoidPtrType();
else {
int indirections = 0;
while (t->isPointerTy()) {
indirections++;
// Disable [[deprecated]] warning on getPointerElementType. We solved the
// deprecation for versions >= LLVM 16 above (8 lines up).
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
t = t->getPointerElementType();
#pragma GCC diagnostic pop
}
while (indirections-- != 0)
t = t->getPointerTo(0);
}
return t;
#endif
}

LLValue *DtoBitCast(LLValue *v, LLType *t, const llvm::Twine &name) {
Expand Down
15 changes: 5 additions & 10 deletions runtime/druntime/src/ldc/intrinsics.di
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ enum LLVM_atleast(int major) = (LLVM_version >= major * 100);
nothrow:
@nogc:

version(LDC_LLVM_OpaquePointers)
private enum p0i8 = "p0";
else
private enum p0i8 = "p0i8";

//
// CODE GENERATOR INTRINSICS
//
Expand All @@ -53,7 +48,7 @@ pragma(LDC_intrinsic, "llvm.returnaddress")

/// The 'llvm.frameaddress' intrinsic attempts to return the target-specific
/// frame pointer value for the specified stack frame.
pragma(LDC_intrinsic, "llvm.frameaddress."~p0i8)
pragma(LDC_intrinsic, "llvm.frameaddress.p0")
void* llvm_frameaddress(uint level);

/// The 'llvm.stacksave' intrinsic is used to remember the current state of the
Expand All @@ -80,7 +75,7 @@ pragma(LDC_intrinsic, "llvm.stackrestore")
/// keep in cache. The cache type specifies whether the prefetch is performed on
/// the data (1) or instruction (0) cache. The rw, locality and cache type
/// arguments must be constant integers.
pragma(LDC_intrinsic, "llvm.prefetch."~p0i8)
pragma(LDC_intrinsic, "llvm.prefetch.p0")
void llvm_prefetch(const(void)* ptr, uint rw, uint locality, uint cachetype) pure @safe;

/// The 'llvm.pcmarker' intrinsic is a method to export a Program Counter (PC)
Expand Down Expand Up @@ -144,7 +139,7 @@ pure:
/// location to the destination location.
/// Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do
/// not return a value.
pragma(LDC_intrinsic, "llvm.memcpy."~p0i8~"."~p0i8~".i#")
pragma(LDC_intrinsic, "llvm.memcpy.p0.p0.i#")
void llvm_memcpy(T)(void* dst, const(void)* src, T len, bool volatile_ = false)
if (__traits(isIntegral, T));

Expand All @@ -154,15 +149,15 @@ pragma(LDC_intrinsic, "llvm.memcpy."~p0i8~"."~p0i8~".i#")
/// intrinsic but allows the two memory locations to overlap.
/// Note that, unlike the standard libc function, the llvm.memmove.* intrinsics
/// do not return a value.
pragma(LDC_intrinsic, "llvm.memmove."~p0i8~"."~p0i8~".i#")
pragma(LDC_intrinsic, "llvm.memmove.p0.p0.i#")
void llvm_memmove(T)(void* dst, const(void)* src, T len, bool volatile_ = false)
if (__traits(isIntegral, T));

/// The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte
/// value.
/// Note that, unlike the standard libc function, the llvm.memset intrinsic does
/// not return a value.
pragma(LDC_intrinsic, "llvm.memset."~p0i8~".i#")
pragma(LDC_intrinsic, "llvm.memset.p0.i#")
void llvm_memset(T)(void* dst, ubyte val, T len, bool volatile_ = false)
if (__traits(isIntegral, T));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
// UNSUPPORTED: atleast_llvm1800 && atmost_llvm1809

// REQUIRES: target_SPIRV && atleast_llvm1600
// RUN: %ldc -c -opaque-pointers -mdcompute-targets=ocl-220 -m64 -mdcompute-file-prefix=addrspace_new -output-ll -output-o %s && FileCheck %s --check-prefix=LL < addrspace_new_ocl220_64.ll \
// RUN: %ldc -c -mdcompute-targets=ocl-220 -m64 -mdcompute-file-prefix=addrspace_new -output-ll -output-o %s && FileCheck %s --check-prefix=LL < addrspace_new_ocl220_64.ll \
// RUN: && %llc addrspace_new_ocl220_64.ll -mtriple=spirv64-unknown-unknown -O0 -o - | FileCheck %s --check-prefix=SPT
@compute(CompileFor.deviceOnly) module dcompute_cl_addrspaces_new;
@compute(CompileFor.deviceOnly) module dcompute_cl_addrspaces;
import ldc.dcompute;

// LL: %"ldc.dcompute.Pointer!(AddrSpace.Private, float).Pointer" = type { ptr }
Expand Down
60 changes: 0 additions & 60 deletions tests/codegen/dcompute_cl_addrspaces_old.d

This file was deleted.

14 changes: 4 additions & 10 deletions tests/codegen/inline_ir.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,10 @@

import ldc.llvmasm;
import ldc.intrinsics;
version (LDC_LLVM_OpaquePointers)
{
alias __irEx!("", "store i32 %1, ptr %0, !nontemporal !0", "!0 = !{i32 1}", void, int*, int) nontemporalStore;
alias __irEx!("!0 = !{i32 1}", "%i = load i32, ptr %0, !nontemporal !0\nret i32 %i", "", int, const int*) nontemporalLoad;
}
else
{
alias __irEx!("", "store i32 %1, i32* %0, !nontemporal !0", "!0 = !{i32 1}", void, int*, int) nontemporalStore;
alias __irEx!("!0 = !{i32 1}", "%i = load i32, i32* %0, !nontemporal !0\nret i32 %i", "", int, const int*) nontemporalLoad;
}

alias __irEx!("", "store i32 %1, ptr %0, !nontemporal !0", "!0 = !{i32 1}", void, int*, int) nontemporalStore;
alias __irEx!("!0 = !{i32 1}", "%i = load i32, ptr %0, !nontemporal !0\nret i32 %i", "", int, const int*) nontemporalLoad;

int foo(const int* src)
{
// CHECK: %{{.*}} = load i32, {{i32\*|ptr}} {{.*}} !nontemporal ![[METADATA:[0-9]+]]
Expand Down

0 comments on commit 3067b7b

Please sign in to comment.