Skip to content

Commit 30daedf

Browse files
author
Robin Kruppe
committedNov 17, 2016
Use llvm::Attribute API instead of "raw value" APIs, which will be removed 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.
1 parent 5887ee5 commit 30daedf

File tree

13 files changed

+261
-199
lines changed

13 files changed

+261
-199
lines changed
 

‎src/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/librustc_llvm/Cargo.toml

Lines changed: 0 additions & 3 deletions
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/ffi.rs

Lines changed: 38 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -82,59 +82,31 @@ pub enum DLLStorageClass {
8282
DllExport = 2, // Function to be accessible from DLL.
8383
}
8484

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

140112
/// LLVMIntPredicate
@@ -422,6 +394,9 @@ pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque;
422394
#[allow(missing_copy_implementations)]
423395
pub enum OperandBundleDef_opaque {}
424396
pub type OperandBundleDefRef = *mut OperandBundleDef_opaque;
397+
#[allow(missing_copy_implementations)]
398+
pub enum Attribute_opaque {}
399+
pub type AttributeRef = *mut Attribute_opaque;
425400

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

499+
/// See llvm::Value::getContext
500+
pub fn LLVMRustGetValueContext(V: ValueRef) -> ContextRef;
501+
524502
// Operations on integer types
525503
pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
526504
pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
@@ -783,6 +761,8 @@ extern "C" {
783761
Name: *const c_char)
784762
-> ValueRef;
785763

764+
pub fn LLVMRustCreateAttribute(C: ContextRef, kind: Attribute, val: u64) -> AttributeRef;
765+
786766
// Operations on functions
787767
pub fn LLVMAddFunction(M: ModuleRef, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef;
788768
pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
@@ -801,16 +781,12 @@ extern "C" {
801781
pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
802782
pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
803783
pub fn LLVMRustAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: u64);
804-
pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: u64);
805-
pub fn LLVMRustAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
784+
pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, attr: AttributeRef);
806785
pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef,
807786
index: c_uint,
808787
Name: *const c_char,
809788
Value: *const c_char);
810-
pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: u64);
811-
pub fn LLVMRustRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
812-
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_uint;
813-
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_uint);
789+
pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: AttributeRef);
814790

815791
// Operations on parameters
816792
pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
@@ -821,9 +797,8 @@ extern "C" {
821797
pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
822798
pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
823799
pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
824-
pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
825-
pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
826-
pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
800+
pub fn LLVMAddAttribute(Arg: ValueRef, attr: AttributeRef);
801+
pub fn LLVMRemoveAttribute(Arg: ValueRef, attr: AttributeRef);
827802
pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
828803

829804
// Operations on basic blocks
@@ -867,7 +842,7 @@ extern "C" {
867842
pub fn LLVMAddInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
868843
pub fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
869844
pub fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint, align: c_uint);
870-
pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, Val: u64);
845+
pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, attr: AttributeRef);
871846
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: ValueRef, index: c_uint, bytes: u64);
872847

873848
// Operations on call instructions (only)

‎src/librustc_llvm/lib.rs

Lines changed: 8 additions & 56 deletions
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

Lines changed: 1 addition & 0 deletions
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" }

‎src/librustc_trans/abi.rs

Lines changed: 105 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use llvm::{self, ValueRef, Integer, Pointer, Float, Double, Struct, Array, Vector};
11+
use llvm::{self, ValueRef, Integer, Pointer, Float, Double, Struct, Array, Vector, AttributePlace};
1212
use base;
1313
use build::AllocaFcx;
1414
use common::{type_is_fat_ptr, BlockAndBuilder, C_uint};
@@ -49,6 +49,93 @@ enum ArgKind {
4949
Ignore,
5050
}
5151

52+
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
53+
// of this module
54+
pub use self::attr_impl::ArgAttribute;
55+
56+
#[allow(non_upper_case_globals)]
57+
mod attr_impl {
58+
// The subset of llvm::Attribute needed for arguments, packed into a bitfield.
59+
bitflags! {
60+
#[derive(Default, Debug)]
61+
flags ArgAttribute : u8 {
62+
const ByVal = 1 << 0,
63+
const NoAlias = 1 << 1,
64+
const NoCapture = 1 << 2,
65+
const NonNull = 1 << 3,
66+
const ReadOnly = 1 << 4,
67+
const SExt = 1 << 5,
68+
const StructRet = 1 << 6,
69+
const ZExt = 1 << 7,
70+
}
71+
}
72+
}
73+
74+
macro_rules! for_each_kind {
75+
($flags: ident, $f: ident, $($kind: ident),+) => ({
76+
$(if $flags.contains(ArgAttribute::$kind) { $f(llvm::Attribute::$kind) })+
77+
})
78+
}
79+
80+
impl ArgAttribute {
81+
fn for_each_kind<F>(&self, mut f: F) where F: FnMut(llvm::Attribute) {
82+
for_each_kind!(self, f,
83+
ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt)
84+
}
85+
}
86+
87+
/// A compact representation of LLVM attributes (at least those relevant for this module)
88+
/// that can be manipulated without interacting with LLVM's Attribute machinery.
89+
#[derive(Copy, Clone, Debug, Default)]
90+
pub struct ArgAttributes {
91+
regular: ArgAttribute,
92+
dereferenceable_bytes: u64,
93+
}
94+
95+
impl ArgAttributes {
96+
pub fn set(&mut self, attr: ArgAttribute) -> &mut Self {
97+
self.regular = self.regular | attr;
98+
self
99+
}
100+
101+
pub fn unset(&mut self, attr: ArgAttribute) -> &mut Self {
102+
self.regular = self.regular - attr;
103+
self
104+
}
105+
106+
pub fn set_dereferenceable(&mut self, bytes: u64) -> &mut Self {
107+
self.dereferenceable_bytes = bytes;
108+
self
109+
}
110+
111+
pub fn unset_dereferenceable(&mut self) -> &mut Self {
112+
self.dereferenceable_bytes = 0;
113+
self
114+
}
115+
116+
pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
117+
unsafe {
118+
self.regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn));
119+
if self.dereferenceable_bytes != 0 {
120+
llvm::LLVMRustAddDereferenceableAttr(llfn,
121+
idx.as_uint(),
122+
self.dereferenceable_bytes);
123+
}
124+
}
125+
}
126+
127+
pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
128+
unsafe {
129+
self.regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite));
130+
if self.dereferenceable_bytes != 0 {
131+
llvm::LLVMRustAddDereferenceableCallSiteAttr(callsite,
132+
idx.as_uint(),
133+
self.dereferenceable_bytes);
134+
}
135+
}
136+
}
137+
}
138+
52139
/// Information about how a specific C type
53140
/// should be passed to or returned from a function
54141
///
@@ -80,7 +167,7 @@ pub struct ArgType {
80167
/// Dummy argument, which is emitted before the real argument
81168
pub pad: Option<Type>,
82169
/// LLVM attributes of argument
83-
pub attrs: llvm::Attributes
170+
pub attrs: ArgAttributes
84171
}
85172

86173
impl ArgType {
@@ -92,23 +179,23 @@ impl ArgType {
92179
signedness: None,
93180
cast: None,
94181
pad: None,
95-
attrs: llvm::Attributes::default()
182+
attrs: ArgAttributes::default()
96183
}
97184
}
98185

99186
pub fn make_indirect(&mut self, ccx: &CrateContext) {
100187
assert_eq!(self.kind, ArgKind::Direct);
101188

102189
// Wipe old attributes, likely not valid through indirection.
103-
self.attrs = llvm::Attributes::default();
190+
self.attrs = ArgAttributes::default();
104191

105192
let llarg_sz = llsize_of_alloc(ccx, self.ty);
106193

107194
// For non-immediate arguments the callee gets its own copy of
108195
// the value on the stack, so there are no aliases. It's also
109196
// program-invisible so can't possibly capture
110-
self.attrs.set(llvm::Attribute::NoAlias)
111-
.set(llvm::Attribute::NoCapture)
197+
self.attrs.set(ArgAttribute::NoAlias)
198+
.set(ArgAttribute::NoCapture)
112199
.set_dereferenceable(llarg_sz);
113200

114201
self.kind = ArgKind::Indirect;
@@ -124,9 +211,9 @@ impl ArgType {
124211
if let Some(signed) = self.signedness {
125212
if self.ty.int_width() < bits {
126213
self.attrs.set(if signed {
127-
llvm::Attribute::SExt
214+
ArgAttribute::SExt
128215
} else {
129-
llvm::Attribute::ZExt
216+
ArgAttribute::ZExt
130217
});
131218
}
132219
}
@@ -314,7 +401,7 @@ impl FnType {
314401
if ty.is_bool() {
315402
let llty = Type::i1(ccx);
316403
let mut arg = ArgType::new(llty, llty);
317-
arg.attrs.set(llvm::Attribute::ZExt);
404+
arg.attrs.set(ArgAttribute::ZExt);
318405
arg
319406
} else {
320407
let mut arg = ArgType::new(type_of::type_of(ccx, ty),
@@ -349,7 +436,7 @@ impl FnType {
349436
if let ty::TyBox(_) = ret_ty.sty {
350437
// `Box` pointer return values never alias because ownership
351438
// is transferred
352-
ret.attrs.set(llvm::Attribute::NoAlias);
439+
ret.attrs.set(ArgAttribute::NoAlias);
353440
}
354441

355442
// We can also mark the return value as `dereferenceable` in certain cases
@@ -371,7 +458,7 @@ impl FnType {
371458
let rust_ptr_attrs = |ty: Ty<'tcx>, arg: &mut ArgType| match ty.sty {
372459
// `Box` pointer parameters never alias because ownership is transferred
373460
ty::TyBox(inner) => {
374-
arg.attrs.set(llvm::Attribute::NoAlias);
461+
arg.attrs.set(ArgAttribute::NoAlias);
375462
Some(inner)
376463
}
377464

@@ -386,18 +473,18 @@ impl FnType {
386473
let interior_unsafe = mt.ty.type_contents(ccx.tcx()).interior_unsafe();
387474

388475
if mt.mutbl != hir::MutMutable && !interior_unsafe {
389-
arg.attrs.set(llvm::Attribute::NoAlias);
476+
arg.attrs.set(ArgAttribute::NoAlias);
390477
}
391478

392479
if mt.mutbl == hir::MutImmutable && !interior_unsafe {
393-
arg.attrs.set(llvm::Attribute::ReadOnly);
480+
arg.attrs.set(ArgAttribute::ReadOnly);
394481
}
395482

396483
// When a reference in an argument has no named lifetime, it's
397484
// impossible for that reference to escape this function
398485
// (returned or stored beyond the call by a closure).
399486
if let ReLateBound(_, BrAnon(_)) = *b {
400-
arg.attrs.set(llvm::Attribute::NoCapture);
487+
arg.attrs.set(ArgAttribute::NoCapture);
401488
}
402489

403490
Some(mt.ty)
@@ -417,9 +504,9 @@ impl FnType {
417504
let mut info = ArgType::new(original_tys[1], sizing_tys[1]);
418505

419506
if let Some(inner) = rust_ptr_attrs(ty, &mut data) {
420-
data.attrs.set(llvm::Attribute::NonNull);
507+
data.attrs.set(ArgAttribute::NonNull);
421508
if ccx.tcx().struct_tail(inner).is_trait() {
422-
info.attrs.set(llvm::Attribute::NonNull);
509+
info.attrs.set(ArgAttribute::NonNull);
423510
}
424511
}
425512
args.push(data);
@@ -490,7 +577,7 @@ impl FnType {
490577
fixup(arg);
491578
}
492579
if self.ret.is_indirect() {
493-
self.ret.attrs.set(llvm::Attribute::StructRet);
580+
self.ret.attrs.set(ArgAttribute::StructRet);
494581
}
495582
return;
496583
}
@@ -524,7 +611,7 @@ impl FnType {
524611
}
525612

526613
if self.ret.is_indirect() {
527-
self.ret.attrs.set(llvm::Attribute::StructRet);
614+
self.ret.attrs.set(ArgAttribute::StructRet);
528615
}
529616
}
530617

‎src/librustc_trans/attributes.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ pub fn inline(val: ValueRef, inline: InlineAttr) {
2424
Always => Attribute::AlwaysInline.apply_llfn(Function, val),
2525
Never => Attribute::NoInline.apply_llfn(Function, val),
2626
None => {
27-
let attr = Attribute::InlineHint |
28-
Attribute::AlwaysInline |
29-
Attribute::NoInline;
30-
attr.unapply_llfn(Function, val)
27+
Attribute::InlineHint.unapply_llfn(Function, val);
28+
Attribute::AlwaysInline.unapply_llfn(Function, val);
29+
Attribute::NoInline.unapply_llfn(Function, val);
3130
},
3231
};
3332
}

‎src/librustc_trans/cabi_asmjs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
#![allow(non_upper_case_globals)]
1212

13-
use llvm::{Struct, Array, Attribute};
14-
use abi::{FnType, ArgType};
13+
use llvm::{Struct, Array};
14+
use abi::{FnType, ArgType, ArgAttribute};
1515
use context::CrateContext;
1616

1717
// Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128
@@ -39,7 +39,7 @@ fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
3939
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType) {
4040
if arg.ty.is_aggregate() {
4141
arg.make_indirect(ccx);
42-
arg.attrs.set(Attribute::ByVal);
42+
arg.attrs.set(ArgAttribute::ByVal);
4343
}
4444
}
4545

‎src/librustc_trans/cabi_x86.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use llvm::*;
12-
use abi::FnType;
12+
use abi::{ArgAttribute, FnType};
1313
use type_::Type;
1414
use super::common::*;
1515
use super::machine::*;
@@ -45,7 +45,7 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
4545
if arg.is_ignore() { continue; }
4646
if arg.ty.kind() == Struct {
4747
arg.make_indirect(ccx);
48-
arg.attrs.set(Attribute::ByVal);
48+
arg.attrs.set(ArgAttribute::ByVal);
4949
} else {
5050
arg.extend_integer_width_to(32);
5151
}

‎src/librustc_trans/cabi_x86_64.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
use self::RegClass::*;
1616

1717
use llvm::{Integer, Pointer, Float, Double};
18-
use llvm::{Struct, Array, Attribute, Vector};
19-
use abi::{self, ArgType, FnType};
18+
use llvm::{Struct, Array, Vector};
19+
use abi::{self, ArgType, ArgAttribute, FnType};
2020
use context::CrateContext;
2121
use type_::Type;
2222

@@ -334,7 +334,7 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
334334
fn x86_64_ty<F>(ccx: &CrateContext,
335335
arg: &mut ArgType,
336336
is_mem_cls: F,
337-
ind_attr: Option<Attribute>)
337+
ind_attr: Option<ArgAttribute>)
338338
where F: FnOnce(&[RegClass]) -> bool
339339
{
340340
if !arg.ty.is_reg_ty() {
@@ -384,7 +384,7 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
384384
sse_regs -= needed_sse;
385385
}
386386
in_mem
387-
}, Some(Attribute::ByVal));
387+
}, Some(ArgAttribute::ByVal));
388388

389389
// An integer, pointer, double or float parameter
390390
// thus the above closure passed to `x86_64_ty` won't

‎src/librustc_trans/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
html_root_url = "https://doc.rust-lang.org/nightly/")]
2424
#![cfg_attr(not(stage0), deny(warnings))]
2525

26+
#![feature(associated_consts)]
2627
#![feature(box_patterns)]
2728
#![feature(box_syntax)]
2829
#![feature(cell_extras)]
@@ -55,6 +56,9 @@ extern crate rustc_platform_intrinsics as intrinsics;
5556
extern crate serialize;
5657
extern crate rustc_const_math;
5758
extern crate rustc_const_eval;
59+
#[macro_use]
60+
#[no_link]
61+
extern crate rustc_bitflags;
5862

5963
#[macro_use] extern crate log;
6064
#[macro_use] extern crate syntax;

‎src/rustllvm/RustWrapper.cpp

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -109,37 +109,84 @@ extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
109109
return wrap(Type::getMetadataTy(*unwrap(C)));
110110
}
111111

112-
extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) {
112+
static Attribute::AttrKind
113+
from_rust(LLVMRustAttribute kind) {
114+
switch (kind) {
115+
case AlwaysInline:
116+
return Attribute::AlwaysInline;
117+
case ByVal:
118+
return Attribute::ByVal;
119+
case Cold:
120+
return Attribute::Cold;
121+
case InlineHint:
122+
return Attribute::InlineHint;
123+
case MinSize:
124+
return Attribute::MinSize;
125+
case Naked:
126+
return Attribute::Naked;
127+
case NoAlias:
128+
return Attribute::NoAlias;
129+
case NoCapture:
130+
return Attribute::NoCapture;
131+
case NoInline:
132+
return Attribute::NoInline;
133+
case NonNull:
134+
return Attribute::NonNull;
135+
case NoRedZone:
136+
return Attribute::NoRedZone;
137+
case NoReturn:
138+
return Attribute::NoReturn;
139+
case NoUnwind:
140+
return Attribute::NoUnwind;
141+
case OptimizeForSize:
142+
return Attribute::OptimizeForSize;
143+
case ReadOnly:
144+
return Attribute::ReadOnly;
145+
case SExt:
146+
return Attribute::SExt;
147+
case StructRet:
148+
return Attribute::StructRet;
149+
case UWTable:
150+
return Attribute::UWTable;
151+
case ZExt:
152+
return Attribute::ZExt;
153+
default:
154+
llvm_unreachable("bad AttributeKind");
155+
}
156+
}
157+
158+
extern "C" LLVMAttributeRef LLVMRustCreateAttribute(LLVMContextRef C, LLVMRustAttribute Kind, uint64_t Val) {
159+
return wrap(Attribute::get(*unwrap(C), from_rust(Kind), Val));
160+
}
161+
162+
extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, LLVMAttributeRef attr) {
113163
CallSite Call = CallSite(unwrap<Instruction>(Instr));
114-
AttrBuilder B;
115-
B.addRawValue(Val);
164+
AttrBuilder B(unwrap(attr));
116165
Call.setAttributes(
117166
Call.getAttributes().addAttributes(Call->getContext(), index,
118167
AttributeSet::get(Call->getContext(),
119168
index, B)));
120169
}
121170

122-
123171
extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
124-
unsigned idx,
125-
uint64_t b)
172+
unsigned index,
173+
uint64_t bytes)
126174
{
127175
CallSite Call = CallSite(unwrap<Instruction>(Instr));
128176
AttrBuilder B;
129-
B.addDereferenceableAttr(b);
177+
B.addDereferenceableAttr(bytes);
130178
Call.setAttributes(
131-
Call.getAttributes().addAttributes(Call->getContext(), idx,
179+
Call.getAttributes().addAttributes(Call->getContext(), index,
132180
AttributeSet::get(Call->getContext(),
133-
idx, B)));
181+
index, B)));
134182
}
135183

136184
extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn,
137185
unsigned index,
138-
uint64_t Val)
186+
LLVMAttributeRef attr)
139187
{
140188
Function *A = unwrap<Function>(Fn);
141-
AttrBuilder B;
142-
B.addRawValue(Val);
189+
AttrBuilder B(unwrap(attr));
143190
A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
144191
}
145192

@@ -153,16 +200,6 @@ extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn,
153200
A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
154201
}
155202

156-
extern "C" void LLVMRustAddFunctionAttrString(LLVMValueRef Fn,
157-
unsigned index,
158-
const char *Name)
159-
{
160-
Function *F = unwrap<Function>(Fn);
161-
AttrBuilder B;
162-
B.addAttribute(Name);
163-
F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
164-
}
165-
166203
extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
167204
unsigned index,
168205
const char *Name,
@@ -175,31 +212,15 @@ extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
175212

176213
extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
177214
unsigned index,
178-
uint64_t Val)
215+
LLVMAttributeRef attr)
179216
{
180-
Function *A = unwrap<Function>(Fn);
181-
const AttributeSet PAL = A->getAttributes();
182-
AttrBuilder B(Val);
217+
Function *F = unwrap<Function>(Fn);
218+
const AttributeSet PAL = F->getAttributes();
219+
AttrBuilder B(unwrap(attr));
183220
const AttributeSet PALnew =
184-
PAL.removeAttributes(A->getContext(), index,
185-
AttributeSet::get(A->getContext(), index, B));
186-
A->setAttributes(PALnew);
187-
}
188-
189-
extern "C" void LLVMRustRemoveFunctionAttrString(LLVMValueRef fn,
190-
unsigned index,
191-
const char *Name)
192-
{
193-
Function *f = unwrap<Function>(fn);
194-
LLVMContext &C = f->getContext();
195-
AttrBuilder B;
196-
B.addAttribute(Name);
197-
AttributeSet to_remove = AttributeSet::get(C, index, B);
198-
199-
AttributeSet attrs = f->getAttributes();
200-
f->setAttributes(attrs.removeAttributes(f->getContext(),
201-
index,
202-
to_remove));
221+
PAL.removeAttributes(F->getContext(), index,
222+
AttributeSet::get(F->getContext(), index, B));
223+
F->setAttributes(PALnew);
203224
}
204225

205226
// enable fpmath flag UnsafeAlgebra
@@ -1293,3 +1314,7 @@ extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
12931314
extern "C" void LLVMRustSetLinkage(LLVMValueRef V, LLVMRustLinkage RustLinkage) {
12941315
LLVMSetLinkage(V, from_rust(RustLinkage));
12951316
}
1317+
1318+
extern "C" LLVMContextRef LLVMRustGetValueContext(LLVMValueRef V) {
1319+
return wrap(&unwrap(V)->getContext());
1320+
}

‎src/rustllvm/rustllvm.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,28 @@ enum class LLVMRustResult {
7272
Failure
7373
};
7474

75+
enum LLVMRustAttribute {
76+
AlwaysInline = 0,
77+
ByVal = 1,
78+
Cold = 2,
79+
InlineHint = 3,
80+
MinSize = 4,
81+
Naked = 5,
82+
NoAlias = 6,
83+
NoCapture = 7,
84+
NoInline = 8,
85+
NonNull = 9,
86+
NoRedZone = 10,
87+
NoReturn = 11,
88+
NoUnwind = 12,
89+
OptimizeForSize = 13,
90+
ReadOnly = 14,
91+
SExt = 15,
92+
StructRet = 16,
93+
UWTable = 17,
94+
ZExt = 18,
95+
};
96+
7597
typedef struct OpaqueRustString *RustStringRef;
7698
typedef struct LLVMOpaqueTwine *LLVMTwineRef;
7799
typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;

0 commit comments

Comments
 (0)
Please sign in to comment.