diff --git a/llvm/docs/OpaquePointers.rst b/llvm/docs/OpaquePointers.rst --- a/llvm/docs/OpaquePointers.rst +++ b/llvm/docs/OpaquePointers.rst @@ -65,9 +65,9 @@ mode (currently still the default) all pointer types have a pointee type and opaque pointers cannot be used. In opaque pointers mode, all pointers are opaque. The opaque pointer mode can be enabled using ``-opaque-pointers`` in -LLVM tools like ``opt``, or ``-Xclang -opaque-pointers`` in clang. Additionally, -opaque pointer mode is automatically enabled for IR and bitcode files that use -the ``ptr`` type. +LLVM tools like ``opt``, or ``-Xclang -opaque-pointers`` in clang, +``-Wl,-plugin-opt=-opaque-pointers`` for LTO. Additionally, opaque pointer mode +is automatically enabled for IR and bitcode files that use the ``ptr`` type. In opaque pointer mode, all typed pointers used in IR, bitcode, or created using ``PointerType::get()`` and similar APIs are automatically converted into diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -177,6 +177,10 @@ /// Add FSAFDO discriminators. bool AddFSDiscriminator = false; + /// Use opaque pointer types. Used to call LLVMContext::setOpaquePointers + /// unless already set by the `-opaque-pointers` commandline option. + bool OpaquePointers = false; + /// If this field is set, LTO will write input file paths and symbol /// resolutions here in llvm-lto2 command line flag format. This can be /// used for testing and for running the LTO pipeline outside of the linker @@ -288,6 +292,8 @@ enableDebugTypeODRUniquing(); setDiagnosticHandler( std::make_unique(&DiagHandler), true); + if (!hasSetOpaquePointersValue()) + setOpaquePointers(C.OpaquePointers); } DiagnosticHandlerFunction DiagHandler; }; diff --git a/llvm/test/LTO/X86/Inputs/opaque-pointers.ll b/llvm/test/LTO/X86/Inputs/opaque-pointers.ll new file mode 100644 --- /dev/null +++ b/llvm/test/LTO/X86/Inputs/opaque-pointers.ll @@ -0,0 +1,7 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i64 @foo(ptr %p) { + %t = load i64, ptr %p + ret i64 %t +} diff --git a/llvm/test/LTO/X86/mix-opaque-typed.ll b/llvm/test/LTO/X86/mix-opaque-typed.ll new file mode 100644 --- /dev/null +++ b/llvm/test/LTO/X86/mix-opaque-typed.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as -opaque-pointers=0 %s -o %t-typed.bc +; RUN: llvm-as -opaque-pointers=1 %S/Inputs/opaque-pointers.ll -o %t-opaque.bc +; RUN: llvm-lto2 run -o %t-lto.bc %t-typed.bc %t-opaque.bc -save-temps \ +; RUN: -lto-opaque-pointers \ +; RUN: -r %t-typed.bc,call_foo,px -r %t-typed.bc,foo,l \ +; RUN: -r %t-opaque.bc,foo,px +; RUN: opt -S -o - %t-lto.bc.0.4.opt.bc | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare i64 @foo(i64* %p); + +define i64 @call_foo(i64* %p) { + ; CHECK-LABEL: define i64 @call_foo(ptr nocapture readonly %p) local_unnamed_addr #0 { + ; CHECK-NEXT: %t.i = load i64, ptr %p, align 8 + %t = call i64 @foo(i64* %p) + ret i64 %t +} diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -208,6 +208,8 @@ static std::string stats_file; // Asserts that LTO link has whole program visibility static bool whole_program_visibility = false; + // Use opaque pointer types. + static bool opaque_pointers = false; // Optimization remarks filename, accepted passes and hotness options static std::string RemarksFilename; @@ -308,6 +310,10 @@ RemarksFormat = std::string(opt); } else if (opt.consume_front("stats-file=")) { stats_file = std::string(opt); + } else if (opt == "opaque-pointers") { + opaque_pointers = true; + } else if (opt == "no-opaque-pointers") { + opaque_pointers = false; } else { // Save this option to pass to the code generator. // ParseCommandLineOptions() expects argv[0] to be program name. Lazily @@ -957,6 +963,8 @@ Conf.HasWholeProgramVisibility = options::whole_program_visibility; + Config.OpaquePointers = options.opaque_pointers; + Conf.StatsFile = options::stats_file; return std::make_unique(std::move(Conf), Backend, options::ParallelCodeGenParallelismLevel); diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp --- a/llvm/tools/llvm-lto2/llvm-lto2.cpp +++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -143,6 +143,10 @@ cl::desc("Run PGO context sensitive IR instrumentation"), cl::init(false), cl::Hidden); +static cl::opt LtoOpaquePointers("lto-opaque-pointers", + cl::desc("Enable opaque pointer types"), + cl::Hidden); + static cl::opt DebugPassManager("debug-pass-manager", cl::init(false), cl::Hidden, cl::desc("Print pass management debugging information")); @@ -291,6 +295,7 @@ Conf.StatsFile = StatsFile; Conf.PTO.LoopVectorization = Conf.OptLevel > 1; Conf.PTO.SLPVectorization = Conf.OptLevel > 1; + Conf.OpaquePointers = LtoOpaquePointers; ThinBackend Backend; if (ThinLTODistributedIndexes)