Skip to content

LLVM 16: Switch to using MemoryEffects #103977

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

Merged
merged 1 commit into from
Nov 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,13 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
let mut attrs = SmallVec::<[_; 2]>::new();
if options.contains(InlineAsmOptions::PURE) {
if options.contains(InlineAsmOptions::NOMEM) {
attrs.push(llvm::AttributeKind::ReadNone.create_attr(self.cx.llcx));
attrs.push(llvm::MemoryEffects::None.create_attr(self.cx.llcx));
} else if options.contains(InlineAsmOptions::READONLY) {
attrs.push(llvm::AttributeKind::ReadOnly.create_attr(self.cx.llcx));
attrs.push(llvm::MemoryEffects::ReadOnly.create_attr(self.cx.llcx));
}
attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
} else if options.contains(InlineAsmOptions::NOMEM) {
attrs.push(llvm::AttributeKind::InaccessibleMemOnly.create_attr(self.cx.llcx));
attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
} else {
// LLVM doesn't have an attribute to represent ReadOnly + SideEffect
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use smallvec::SmallVec;

use crate::attributes;
use crate::llvm::AttributePlace::Function;
use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace};
use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects};
use crate::llvm_util;
pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};

Expand Down Expand Up @@ -303,10 +303,10 @@ pub fn from_fn_attrs<'ll, 'tcx>(
to_add.push(AttributeKind::ReturnsTwice.create_attr(cx.llcx));
}
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_PURE) {
to_add.push(AttributeKind::ReadOnly.create_attr(cx.llcx));
to_add.push(MemoryEffects::ReadOnly.create_attr(cx.llcx));
}
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_CONST) {
to_add.push(AttributeKind::ReadNone.create_attr(cx.llcx));
to_add.push(MemoryEffects::None.create_attr(cx.llcx));
}
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ pub enum AttributeKind {
OptimizeNone = 24,
ReturnsTwice = 25,
ReadNone = 26,
InaccessibleMemOnly = 27,
SanitizeHWAddress = 28,
WillReturn = 29,
StackProtectReq = 30,
Expand Down Expand Up @@ -590,6 +589,15 @@ pub enum ChecksumKind {
SHA256,
}

/// LLVMRustMemoryEffects
#[derive(Copy, Clone)]
#[repr(C)]
pub enum MemoryEffects {
None,
ReadOnly,
InaccessibleMemOnly,
}

extern "C" {
type Opaque;
}
Expand Down Expand Up @@ -1175,6 +1183,7 @@ extern "C" {
pub fn LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute;
pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute;
pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute;
pub fn LLVMRustCreateMemoryEffectsAttr(C: &Context, effects: MemoryEffects) -> &Attribute;

// Operations on functions
pub fn LLVMRustGetOrInsertFunction<'a>(
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ impl AttributeKind {
}
}

impl MemoryEffects {
/// Create an LLVM Attribute with these memory effects.
pub fn create_attr(self, llcx: &Context) -> &Attribute {
unsafe { LLVMRustCreateMemoryEffectsAttr(llcx, self) }
}
}

pub fn set_section(llglobal: &Value, section_name: &str) {
let section_name_cstr = CString::new(section_name).expect("unexpected CString error");
unsafe {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ enum LLVMRustAttribute {
OptimizeNone = 24,
ReturnsTwice = 25,
ReadNone = 26,
InaccessibleMemOnly = 27,
SanitizeHWAddress = 28,
WillReturn = 29,
StackProtectReq = 30,
Expand Down
42 changes: 40 additions & 2 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/Mangler.h"
#if LLVM_VERSION_GE(16, 0)
#include "llvm/IR/ModRef.h"
#endif
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ObjectFile.h"
Expand Down Expand Up @@ -213,8 +216,6 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
return Attribute::ReturnsTwice;
case ReadNone:
return Attribute::ReadNone;
case InaccessibleMemOnly:
return Attribute::InaccessibleMemOnly;
case SanitizeHWAddress:
return Attribute::SanitizeHWAddress;
case WillReturn:
Expand Down Expand Up @@ -379,6 +380,43 @@ extern "C" LLVMAttributeRef LLVMRustCreateAllocKindAttr(LLVMContextRef C, uint64
#endif
}

// Simplified representation of `MemoryEffects` across the FFI boundary.
//
// Each variant corresponds to one of the static factory methods on `MemoryEffects`.
enum class LLVMRustMemoryEffects {
None,
ReadOnly,
InaccessibleMemOnly,
};

extern "C" LLVMAttributeRef LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C,
LLVMRustMemoryEffects Effects) {
#if LLVM_VERSION_GE(16, 0)
switch (Effects) {
case LLVMRustMemoryEffects::None:
return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::none()));
case LLVMRustMemoryEffects::ReadOnly:
return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::readOnly()));
case LLVMRustMemoryEffects::InaccessibleMemOnly:
return wrap(Attribute::getWithMemoryEffects(*unwrap(C),
MemoryEffects::inaccessibleMemOnly()));
default:
report_fatal_error("bad MemoryEffects.");
}
#else
switch (Effects) {
case LLVMRustMemoryEffects::None:
return wrap(Attribute::get(*unwrap(C), Attribute::ReadNone));
case LLVMRustMemoryEffects::ReadOnly:
return wrap(Attribute::get(*unwrap(C), Attribute::ReadOnly));
case LLVMRustMemoryEffects::InaccessibleMemOnly:
return wrap(Attribute::get(*unwrap(C), Attribute::InaccessibleMemOnly));
default:
report_fatal_error("bad MemoryEffects.");
}
#endif
}

// Enable a fast-math flag
//
// https://llvm.org/docs/LangRef.html#fast-math-flags
Expand Down
3 changes: 2 additions & 1 deletion src/test/codegen/ffi-const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } }
extern "C" {
// CHECK-LABEL: declare{{.*}}void @foo()
// CHECK-SAME: [[ATTRS:#[0-9]+]]
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} }
// The attribute changed from `readnone` to `memory(none)` with LLVM 16.0.
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} }
#[ffi_const] pub fn foo();
}
3 changes: 2 additions & 1 deletion src/test/codegen/ffi-pure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } }
extern "C" {
// CHECK-LABEL: declare{{.*}}void @foo()
// CHECK-SAME: [[ATTRS:#[0-9]+]]
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} }
// The attribute changed from `readonly` to `memory(read)` with LLVM 16.0.
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} }
#[ffi_pure] pub fn foo();
}