Skip to content

Commit

Permalink
Use llvm::Attribute API instead of "raw value" APIs, which will be re…
Browse files Browse the repository at this point in the history
…moved in LLVM 4.0.

The librustc_llvm API remains mostly unchanged, except that llvm::Attribute is no longer a bitflag but represents only a *single* attribute.
The ability to store many attributes in a small number of bits and modify them without interacting with LLVM is only used in rustc_trans::abi and closely related modules, and only attributes for function arguments are considered there.
Thus rustc_trans::abi now has its own bit-packed representation of argument attributes, which are translated to rustc_llvm::Attribute when applying the attributes.
  • Loading branch information
Robin Kruppe committed Nov 17, 2016
1 parent 5887ee5 commit 30daedf
Show file tree
Hide file tree
Showing 13 changed files with 261 additions and 199 deletions.
2 changes: 1 addition & 1 deletion src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions src/librustc_llvm/Cargo.toml
Expand Up @@ -12,9 +12,6 @@ crate-type = ["dylib"]
[features]
static-libstdcpp = []

[dependencies]
rustc_bitflags = { path = "../librustc_bitflags" }

[build-dependencies]
build_helper = { path = "../build_helper" }
gcc = "0.3.27"
101 changes: 38 additions & 63 deletions src/librustc_llvm/ffi.rs
Expand Up @@ -82,59 +82,31 @@ pub enum DLLStorageClass {
DllExport = 2, // Function to be accessible from DLL.
}

bitflags! {
#[derive(Default, Debug)]
flags Attribute : u64 {
const ZExt = 1 << 0,
const SExt = 1 << 1,
const NoReturn = 1 << 2,
const InReg = 1 << 3,
const StructRet = 1 << 4,
const NoUnwind = 1 << 5,
const NoAlias = 1 << 6,
const ByVal = 1 << 7,
const Nest = 1 << 8,
const ReadNone = 1 << 9,
const ReadOnly = 1 << 10,
const NoInline = 1 << 11,
const AlwaysInline = 1 << 12,
const OptimizeForSize = 1 << 13,
const StackProtect = 1 << 14,
const StackProtectReq = 1 << 15,
const NoCapture = 1 << 21,
const NoRedZone = 1 << 22,
const NoImplicitFloat = 1 << 23,
const Naked = 1 << 24,
const InlineHint = 1 << 25,
const ReturnsTwice = 1 << 29,
const UWTable = 1 << 30,
const NonLazyBind = 1 << 31,

// Some of these are missing from the LLVM C API, the rest are
// present, but commented out, and preceded by the following warning:
// FIXME: These attributes are currently not included in the C API as
// a temporary measure until the API/ABI impact to the C API is understood
// and the path forward agreed upon.
const SanitizeAddress = 1 << 32,
const MinSize = 1 << 33,
const NoDuplicate = 1 << 34,
const StackProtectStrong = 1 << 35,
const SanitizeThread = 1 << 36,
const SanitizeMemory = 1 << 37,
const NoBuiltin = 1 << 38,
const Returned = 1 << 39,
const Cold = 1 << 40,
const Builtin = 1 << 41,
const OptimizeNone = 1 << 42,
const InAlloca = 1 << 43,
const NonNull = 1 << 44,
const JumpTable = 1 << 45,
const Convergent = 1 << 46,
const SafeStack = 1 << 47,
const NoRecurse = 1 << 48,
const InaccessibleMemOnly = 1 << 49,
const InaccessibleMemOrArgMemOnly = 1 << 50,
}
/// Matches LLVMRustAttribute in rustllvm.h
/// Semantically a subset of the C++ enum llvm::Attribute::AttrKind,
/// though it is not ABI compatible (since it's a C++ enum)
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub enum Attribute {
AlwaysInline = 0,
ByVal = 1,
Cold = 2,
InlineHint = 3,
MinSize = 4,
Naked = 5,
NoAlias = 6,
NoCapture = 7,
NoInline = 8,
NonNull = 9,
NoRedZone = 10,
NoReturn = 11,
NoUnwind = 12,
OptimizeForSize = 13,
ReadOnly = 14,
SExt = 15,
StructRet = 16,
UWTable = 17,
ZExt = 18,
}

/// LLVMIntPredicate
Expand Down Expand Up @@ -422,6 +394,9 @@ pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque;
#[allow(missing_copy_implementations)]
pub enum OperandBundleDef_opaque {}
pub type OperandBundleDefRef = *mut OperandBundleDef_opaque;
#[allow(missing_copy_implementations)]
pub enum Attribute_opaque {}
pub type AttributeRef = *mut Attribute_opaque;

pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void);
pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint);
Expand Down Expand Up @@ -521,6 +496,9 @@ extern "C" {
/// See llvm::LLVMType::getContext.
pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;

/// See llvm::Value::getContext
pub fn LLVMRustGetValueContext(V: ValueRef) -> ContextRef;

// Operations on integer types
pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
Expand Down Expand Up @@ -783,6 +761,8 @@ extern "C" {
Name: *const c_char)
-> ValueRef;

pub fn LLVMRustCreateAttribute(C: ContextRef, kind: Attribute, val: u64) -> AttributeRef;

// Operations on functions
pub fn LLVMAddFunction(M: ModuleRef, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef;
pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
Expand All @@ -801,16 +781,12 @@ extern "C" {
pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
pub fn LLVMRustAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: u64);
pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: u64);
pub fn LLVMRustAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, attr: AttributeRef);
pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef,
index: c_uint,
Name: *const c_char,
Value: *const c_char);
pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: u64);
pub fn LLVMRustRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_uint;
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_uint);
pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: AttributeRef);

// Operations on parameters
pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
Expand All @@ -821,9 +797,8 @@ extern "C" {
pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
pub fn LLVMAddAttribute(Arg: ValueRef, attr: AttributeRef);
pub fn LLVMRemoveAttribute(Arg: ValueRef, attr: AttributeRef);
pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);

// Operations on basic blocks
Expand Down Expand Up @@ -867,7 +842,7 @@ extern "C" {
pub fn LLVMAddInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
pub fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
pub fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint, align: c_uint);
pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, Val: u64);
pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, attr: AttributeRef);
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: ValueRef, index: c_uint, bytes: u64);

// Operations on call instructions (only)
Expand Down
64 changes: 8 additions & 56 deletions src/librustc_llvm/lib.rs
Expand Up @@ -29,12 +29,8 @@
#![feature(staged_api)]
#![feature(linked_from)]
#![feature(concat_idents)]
#![cfg_attr(not(stage0), feature(rustc_private))]

extern crate libc;
#[macro_use]
#[no_link]
extern crate rustc_bitflags;

pub use self::IntPredicate::*;
pub use self::RealPredicate::*;
Expand Down Expand Up @@ -68,54 +64,6 @@ impl LLVMRustResult {
}
}

#[derive(Copy, Clone, Default, Debug)]
pub struct Attributes {
regular: Attribute,
dereferenceable_bytes: u64,
}

impl Attributes {
pub fn set(&mut self, attr: Attribute) -> &mut Self {
self.regular = self.regular | attr;
self
}

pub fn unset(&mut self, attr: Attribute) -> &mut Self {
self.regular = self.regular - attr;
self
}

pub fn set_dereferenceable(&mut self, bytes: u64) -> &mut Self {
self.dereferenceable_bytes = bytes;
self
}

pub fn unset_dereferenceable(&mut self) -> &mut Self {
self.dereferenceable_bytes = 0;
self
}

pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
unsafe {
self.regular.apply_llfn(idx, llfn);
if self.dereferenceable_bytes != 0 {
LLVMRustAddDereferenceableAttr(llfn, idx.as_uint(), self.dereferenceable_bytes);
}
}
}

pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
unsafe {
self.regular.apply_callsite(idx, callsite);
if self.dereferenceable_bytes != 0 {
LLVMRustAddDereferenceableCallSiteAttr(callsite,
idx.as_uint(),
self.dereferenceable_bytes);
}
}
}
}

pub fn AddFunctionAttrStringValue(llfn: ValueRef,
idx: AttributePlace,
attr: &'static str,
Expand All @@ -140,7 +88,7 @@ impl AttributePlace {
AttributePlace::Argument(0)
}

fn as_uint(self) -> c_uint {
pub fn as_uint(self) -> c_uint {
match self {
AttributePlace::Function => !0,
AttributePlace::Argument(i) => i,
Expand Down Expand Up @@ -228,16 +176,20 @@ pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
}

impl Attribute {
fn as_object(&self, value: ValueRef) -> AttributeRef {
unsafe { LLVMRustCreateAttribute(LLVMRustGetValueContext(value), *self, 0) }
}

pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), self.bits()) }
unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), self.as_object(llfn)) }
}

pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), self.bits()) }
unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), self.as_object(callsite)) }
}

pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), self.bits()) }
unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), self.as_object(llfn)) }
}

pub fn toggle_llfn(&self, idx: AttributePlace, llfn: ValueRef, set: bool) {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/Cargo.toml
Expand Up @@ -16,6 +16,7 @@ graphviz = { path = "../libgraphviz" }
log = { path = "../liblog" }
rustc = { path = "../librustc" }
rustc_back = { path = "../librustc_back" }
rustc_bitflags = { path = "../librustc_bitflags" }
rustc_const_eval = { path = "../librustc_const_eval" }
rustc_const_math = { path = "../librustc_const_math" }
rustc_data_structures = { path = "../librustc_data_structures" }
Expand Down

0 comments on commit 30daedf

Please sign in to comment.