Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Enable opaque pointers mode in codegen #44334

Closed

Conversation

pchintalapudi
Copy link
Member

Opaque pointers are untyped pointers in LLVM IR. By giving up types, they also remove many redundant bitcasts between various pointer types and thus could potentially reduce LLVM optimization time. In addition, some of our optimization passes can benefit from opaque pointers (alloc-opt, remove-addrspaces) as they will only need to insert addrspacecast instructions rather than changing the types of pointers while optimizing.

This PR builds on top of #43827 as that PR defers construction of the global context until after command line options are parsed, which enables us to specify opaque pointers mode in the command line arguments.

Restrictions:

  1. Opaque pointers requires LLVM 14 or above.
    1. There have been many patches between LLVM 13 and LLVM 14 related to opaque pointers, and it is unlikely that most will be backported back two major versions.
  2. The sysimg currently fails to build due to an assert in loop access analysis
    1. This was fixed recently but after the 14.0.0-rc branch cut (Backport issue: Backport ff31020ee651d4867c5f1910fa0ded11cf8c2b13 llvm/llvm-project#54059)
    2. For now, it's easier to build the sysimg with opaque pointers turned off (comment out ctxt->enableOpaquePointers(); in codegen.cpp ~ line 8319) and then turn on opaque pointers with JULIA_LLVM_ARGS="--opaque-pointers" for experimentation purposes

More information on opaque pointers: https://llvm.org/docs/OpaquePointers.html


Make.user to force LLVM 14.0.0-rc version

#LLVM_DEBUG=2
LLVM_ASSERTIONS=1
USE_BINARYBUILDER_LLVM=0
FORCE_ASSERTIONS=1
LLVM_GIT_URL:=https://github.com/llvm/llvm-project.git
LLVM_VER=14.0.0
override LLVM_SHA1=f5f0bd8e3d972d040827c88adf1a9880ebcb821e

@pchintalapudi pchintalapudi added compiler:codegen Generation of LLVM IR and native code compiler:llvm For issues that relate to LLVM labels Feb 24, 2022
@pchintalapudi
Copy link
Member Author

Comparison of code with and without opaque pointers

Without opaque pointers

define i64 @julia_loopinc_149() #0 {
L46.preheader:
  br label %pass.2

L88:                                              ; preds = %idxend
  ret i64 %1

oob:                                              ; preds = %pass.2
  %0 = alloca i64, align 8
  store i64 2, i64* %0, align 8
  call void @ijl_bounds_error_ints({}* %5, i64* nonnull %0, i64 1)
  unreachable

idxend:                                           ; preds = %pass.2
  %1 = add i64 %3, %value_phi11
  %.not22 = icmp eq i64 %2, 10000000
  br i1 %.not22, label %L88, label %pass.2

pass.2:                                           ; preds = %idxend, %L46.preheader
  %2 = phi i64 [ %3, %idxend ], [ 1, %L46.preheader ]
  %value_phi11 = phi i64 [ %1, %idxend ], [ 0, %L46.preheader ]
  %3 = add nuw i64 %2, 1
  %4 = add nuw i64 %2, 2
  %5 = call nonnull {}* inttoptr (i64 140311113082576 to {}* ({}*, i64)*)({}* inttoptr (i64 140310780559104 to {}*), i64 3)
  %6 = bitcast {}* %5 to i64**
  %7 = load i64*, i64** %6, align 8
  store i64 %2, i64* %7, align 8
  %8 = getelementptr inbounds i64, i64* %7, i64 1
  store i64 %3, i64* %8, align 8
  %9 = getelementptr inbounds i64, i64* %7, i64 2
  store i64 %4, i64* %9, align 8
  %10 = bitcast {}* %5 to { i8*, i64, i16, i16, i32 }*
  %11 = getelementptr inbounds { i8*, i64, i16, i16, i32 }, { i8*, i64, i16, i16, i32 }* %10, i64 0, i32 1
  %12 = load i64, i64* %11, align 8
  %13 = icmp ugt i64 %12, 1
  br i1 %13, label %idxend, label %oob
}

With opaque pointers

define i64 @julia_loopinc_154() #0 {
L46.preheader:
  br label %pass.2

L89:                                              ; preds = %idxend
  ret i64 %12

pass.2:                                           ; preds = %idxend, %L46.preheader
  %0 = phi i64 [ %1, %idxend ], [ 1, %L46.preheader ]
  %value_phi11 = phi i64 [ %12, %idxend ], [ 0, %L46.preheader ]
  %1 = add nuw i64 %0, 1
  %2 = add nuw i64 %0, 2
  %3 = call nonnull ptr inttoptr (i64 140300694719328 to ptr)(ptr inttoptr (i64 140300327141888 to ptr), i64 3)
  %4 = getelementptr inbounds { ptr, i64, i16, i16, i32 }, ptr %3, i64 0, i32 0
  %5 = load ptr, ptr %4, align 8
  store i64 %0, ptr %5, align 8
  %6 = getelementptr inbounds i64, ptr %5, i64 1
  store i64 %1, ptr %6, align 8
  %7 = getelementptr inbounds i64, ptr %5, i64 2
  store i64 %2, ptr %7, align 8
  %8 = getelementptr inbounds { ptr, i64, i16, i16, i32 }, ptr %3, i64 0, i32 1
  %9 = load i64, ptr %8, align 8
  %10 = icmp ugt i64 %9, 1
  br i1 %10, label %idxend, label %oob

oob:                                              ; preds = %pass.2
  %11 = alloca i64, align 8
  store i64 2, ptr %11, align 8
  call void @ijl_bounds_error_ints(ptr %3, ptr nonnull %11, i64 1)
  unreachable

idxend:                                           ; preds = %pass.2
  %12 = add i64 %1, %value_phi11
  %.not22 = icmp eq i64 %0, 10000000
  br i1 %.not22, label %L89, label %pass.2
}

Keno added a commit that referenced this pull request Apr 17, 2022
Essentially a rebase of #44334 to current master. I would like to work on
some IR canonicalization improvements, but it doesn't make much sense
to that without opaque pointers, since canonical forms will change.

This bootstraps fine on LLVM master, though there are test failures
both with and without this change. I think we'll just have to address
those as part of the regular upgrade cycle as usual (though we should
probably do LLVM 14 first to catch any 13->14 regressions).
@pchintalapudi
Copy link
Member Author

LLVM 14 will not contain opaque pointer patches necessary for Julia to build/run, and enabling opaque pointer mode in LLVM 15 is handled in #45012.

Keno added a commit that referenced this pull request Apr 21, 2022
Essentially a rebase of #44334 to current master. I would like to work on
some IR canonicalization improvements, but it doesn't make much sense
to that without opaque pointers, since canonical forms will change.

This bootstraps fine on LLVM master, though there are test failures
both with and without this change. I think we'll just have to address
those as part of the regular upgrade cycle as usual (though we should
probably do LLVM 14 first to catch any 13->14 regressions).
@pchintalapudi pchintalapudi deleted the pc/opaque-pointers branch February 22, 2023 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:codegen Generation of LLVM IR and native code compiler:llvm For issues that relate to LLVM
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant