Skip to content

Commit 0bd2ce6

Browse files
authored
Auto merge of #37831 - rkruppe:llvm-attr-fwdcompat, r=eddyb
[LLVM 4.0] Use llvm::Attribute APIs instead of "raw value" APIs The latter will be removed in LLVM 4.0 (see llvm-mirror/llvm@4a6fc8b). 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. cc #37609
2 parents bfa709a + 30daedf commit 0bd2ce6

File tree

14 files changed

+264
-199
lines changed

14 files changed

+264
-199
lines changed

src/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc_llvm/Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ crate-type = ["dylib"]
1212
[features]
1313
static-libstdcpp = []
1414

15-
[dependencies]
16-
rustc_bitflags = { path = "../librustc_bitflags" }
17-
1815
[build-dependencies]
1916
build_helper = { path = "../build_helper" }
2017
gcc = "0.3.27"

src/librustc_llvm/build.rs

+3
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ fn main() {
145145
cfg.flag("-DLLVM_RUSTLLVM");
146146
}
147147

148+
println!("cargo:rerun-if-changed=../rustllvm/PassWrapper.cpp");
149+
println!("cargo:rerun-if-changed=../rustllvm/RustWrapper.cpp");
150+
println!("cargo:rerun-if-changed=../rustllvm/ArchiveWrapper.cpp");
148151
cfg.file("../rustllvm/PassWrapper.cpp")
149152
.file("../rustllvm/RustWrapper.cpp")
150153
.file("../rustllvm/ArchiveWrapper.cpp")

src/librustc_llvm/ffi.rs

+38-63
Original file line numberDiff line numberDiff line change
@@ -83,59 +83,31 @@ pub enum DLLStorageClass {
8383
DllExport = 2, // Function to be accessible from DLL.
8484
}
8585

86-
bitflags! {
87-
#[derive(Default, Debug)]
88-
flags Attribute : u64 {
89-
const ZExt = 1 << 0,
90-
const SExt = 1 << 1,
91-
const NoReturn = 1 << 2,
92-
const InReg = 1 << 3,
93-
const StructRet = 1 << 4,
94-
const NoUnwind = 1 << 5,
95-
const NoAlias = 1 << 6,
96-
const ByVal = 1 << 7,
97-
const Nest = 1 << 8,
98-
const ReadNone = 1 << 9,
99-
const ReadOnly = 1 << 10,
100-
const NoInline = 1 << 11,
101-
const AlwaysInline = 1 << 12,
102-
const OptimizeForSize = 1 << 13,
103-
const StackProtect = 1 << 14,
104-
const StackProtectReq = 1 << 15,
105-
const NoCapture = 1 << 21,
106-
const NoRedZone = 1 << 22,
107-
const NoImplicitFloat = 1 << 23,
108-
const Naked = 1 << 24,
109-
const InlineHint = 1 << 25,
110-
const ReturnsTwice = 1 << 29,
111-
const UWTable = 1 << 30,
112-
const NonLazyBind = 1 << 31,
113-
114-
// Some of these are missing from the LLVM C API, the rest are
115-
// present, but commented out, and preceded by the following warning:
116-
// FIXME: These attributes are currently not included in the C API as
117-
// a temporary measure until the API/ABI impact to the C API is understood
118-
// and the path forward agreed upon.
119-
const SanitizeAddress = 1 << 32,
120-
const MinSize = 1 << 33,
121-
const NoDuplicate = 1 << 34,
122-
const StackProtectStrong = 1 << 35,
123-
const SanitizeThread = 1 << 36,
124-
const SanitizeMemory = 1 << 37,
125-
const NoBuiltin = 1 << 38,
126-
const Returned = 1 << 39,
127-
const Cold = 1 << 40,
128-
const Builtin = 1 << 41,
129-
const OptimizeNone = 1 << 42,
130-
const InAlloca = 1 << 43,
131-
const NonNull = 1 << 44,
132-
const JumpTable = 1 << 45,
133-
const Convergent = 1 << 46,
134-
const SafeStack = 1 << 47,
135-
const NoRecurse = 1 << 48,
136-
const InaccessibleMemOnly = 1 << 49,
137-
const InaccessibleMemOrArgMemOnly = 1 << 50,
138-
}
86+
/// Matches LLVMRustAttribute in rustllvm.h
87+
/// Semantically a subset of the C++ enum llvm::Attribute::AttrKind,
88+
/// though it is not ABI compatible (since it's a C++ enum)
89+
#[repr(C)]
90+
#[derive(Copy, Clone, Debug)]
91+
pub enum Attribute {
92+
AlwaysInline = 0,
93+
ByVal = 1,
94+
Cold = 2,
95+
InlineHint = 3,
96+
MinSize = 4,
97+
Naked = 5,
98+
NoAlias = 6,
99+
NoCapture = 7,
100+
NoInline = 8,
101+
NonNull = 9,
102+
NoRedZone = 10,
103+
NoReturn = 11,
104+
NoUnwind = 12,
105+
OptimizeForSize = 13,
106+
ReadOnly = 14,
107+
SExt = 15,
108+
StructRet = 16,
109+
UWTable = 17,
110+
ZExt = 18,
139111
}
140112

141113
/// LLVMIntPredicate
@@ -423,6 +395,9 @@ pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque;
423395
#[allow(missing_copy_implementations)]
424396
pub enum OperandBundleDef_opaque {}
425397
pub type OperandBundleDefRef = *mut OperandBundleDef_opaque;
398+
#[allow(missing_copy_implementations)]
399+
pub enum Attribute_opaque {}
400+
pub type AttributeRef = *mut Attribute_opaque;
426401

427402
pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void);
428403
pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint);
@@ -530,6 +505,9 @@ extern "C" {
530505
/// See llvm::LLVMType::getContext.
531506
pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
532507

508+
/// See llvm::Value::getContext
509+
pub fn LLVMRustGetValueContext(V: ValueRef) -> ContextRef;
510+
533511
// Operations on integer types
534512
pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
535513
pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
@@ -792,6 +770,8 @@ extern "C" {
792770
Name: *const c_char)
793771
-> ValueRef;
794772

773+
pub fn LLVMRustCreateAttribute(C: ContextRef, kind: Attribute, val: u64) -> AttributeRef;
774+
795775
// Operations on functions
796776
pub fn LLVMAddFunction(M: ModuleRef, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef;
797777
pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
@@ -810,16 +790,12 @@ extern "C" {
810790
pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
811791
pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
812792
pub fn LLVMRustAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: u64);
813-
pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: u64);
814-
pub fn LLVMRustAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
793+
pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, attr: AttributeRef);
815794
pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef,
816795
index: c_uint,
817796
Name: *const c_char,
818797
Value: *const c_char);
819-
pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: u64);
820-
pub fn LLVMRustRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
821-
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_uint;
822-
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_uint);
798+
pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: AttributeRef);
823799

824800
// Operations on parameters
825801
pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
@@ -830,9 +806,8 @@ extern "C" {
830806
pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
831807
pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
832808
pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
833-
pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
834-
pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
835-
pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
809+
pub fn LLVMAddAttribute(Arg: ValueRef, attr: AttributeRef);
810+
pub fn LLVMRemoveAttribute(Arg: ValueRef, attr: AttributeRef);
836811
pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
837812

838813
// Operations on basic blocks
@@ -876,7 +851,7 @@ extern "C" {
876851
pub fn LLVMAddInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
877852
pub fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
878853
pub fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint, align: c_uint);
879-
pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, Val: u64);
854+
pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, attr: AttributeRef);
880855
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: ValueRef, index: c_uint, bytes: u64);
881856

882857
// Operations on call instructions (only)

src/librustc_llvm/lib.rs

+8-56
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,8 @@
2929
#![feature(staged_api)]
3030
#![feature(linked_from)]
3131
#![feature(concat_idents)]
32-
#![cfg_attr(not(stage0), feature(rustc_private))]
3332

3433
extern crate libc;
35-
#[macro_use]
36-
#[no_link]
37-
extern crate rustc_bitflags;
3834

3935
pub use self::IntPredicate::*;
4036
pub use self::RealPredicate::*;
@@ -68,54 +64,6 @@ impl LLVMRustResult {
6864
}
6965
}
7066

71-
#[derive(Copy, Clone, Default, Debug)]
72-
pub struct Attributes {
73-
regular: Attribute,
74-
dereferenceable_bytes: u64,
75-
}
76-
77-
impl Attributes {
78-
pub fn set(&mut self, attr: Attribute) -> &mut Self {
79-
self.regular = self.regular | attr;
80-
self
81-
}
82-
83-
pub fn unset(&mut self, attr: Attribute) -> &mut Self {
84-
self.regular = self.regular - attr;
85-
self
86-
}
87-
88-
pub fn set_dereferenceable(&mut self, bytes: u64) -> &mut Self {
89-
self.dereferenceable_bytes = bytes;
90-
self
91-
}
92-
93-
pub fn unset_dereferenceable(&mut self) -> &mut Self {
94-
self.dereferenceable_bytes = 0;
95-
self
96-
}
97-
98-
pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
99-
unsafe {
100-
self.regular.apply_llfn(idx, llfn);
101-
if self.dereferenceable_bytes != 0 {
102-
LLVMRustAddDereferenceableAttr(llfn, idx.as_uint(), self.dereferenceable_bytes);
103-
}
104-
}
105-
}
106-
107-
pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
108-
unsafe {
109-
self.regular.apply_callsite(idx, callsite);
110-
if self.dereferenceable_bytes != 0 {
111-
LLVMRustAddDereferenceableCallSiteAttr(callsite,
112-
idx.as_uint(),
113-
self.dereferenceable_bytes);
114-
}
115-
}
116-
}
117-
}
118-
11967
pub fn AddFunctionAttrStringValue(llfn: ValueRef,
12068
idx: AttributePlace,
12169
attr: &'static str,
@@ -140,7 +88,7 @@ impl AttributePlace {
14088
AttributePlace::Argument(0)
14189
}
14290

143-
fn as_uint(self) -> c_uint {
91+
pub fn as_uint(self) -> c_uint {
14492
match self {
14593
AttributePlace::Function => !0,
14694
AttributePlace::Argument(i) => i,
@@ -228,16 +176,20 @@ pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
228176
}
229177

230178
impl Attribute {
179+
fn as_object(&self, value: ValueRef) -> AttributeRef {
180+
unsafe { LLVMRustCreateAttribute(LLVMRustGetValueContext(value), *self, 0) }
181+
}
182+
231183
pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
232-
unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), self.bits()) }
184+
unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), self.as_object(llfn)) }
233185
}
234186

235187
pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
236-
unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), self.bits()) }
188+
unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), self.as_object(callsite)) }
237189
}
238190

239191
pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
240-
unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), self.bits()) }
192+
unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), self.as_object(llfn)) }
241193
}
242194

243195
pub fn toggle_llfn(&self, idx: AttributePlace, llfn: ValueRef, set: bool) {

src/librustc_trans/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ graphviz = { path = "../libgraphviz" }
1616
log = { path = "../liblog" }
1717
rustc = { path = "../librustc" }
1818
rustc_back = { path = "../librustc_back" }
19+
rustc_bitflags = { path = "../librustc_bitflags" }
1920
rustc_const_eval = { path = "../librustc_const_eval" }
2021
rustc_const_math = { path = "../librustc_const_math" }
2122
rustc_data_structures = { path = "../librustc_data_structures" }

0 commit comments

Comments
 (0)