Skip to content

Commit eb33822

Browse files
committed
Pass type to byval attributes
1 parent 04304fc commit eb33822

File tree

4 files changed

+60
-30
lines changed

4 files changed

+60
-30
lines changed

src/librustc_codegen_llvm/abi.rs

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ trait ArgAttributeExt {
3434
impl ArgAttributeExt for ArgAttribute {
3535
fn for_each_kind<F>(&self, mut f: F) where F: FnMut(llvm::Attribute) {
3636
for_each_kind!(self, f,
37-
ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg)
37+
NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg)
3838
}
3939
}
4040

4141
pub trait ArgAttributesExt {
42-
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value);
43-
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value);
42+
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>);
43+
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>);
4444
}
4545

4646
impl ArgAttributesExt for ArgAttributes {
47-
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) {
47+
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>) {
4848
let mut regular = self.regular;
4949
unsafe {
5050
let deref = self.pointee_size.bytes();
@@ -65,11 +65,14 @@ impl ArgAttributesExt for ArgAttributes {
6565
idx.as_uint(),
6666
align.bytes() as u32);
6767
}
68+
if regular.contains(ArgAttribute::ByVal) {
69+
llvm::LLVMRustAddByValAttr(llfn, idx.as_uint(), ty.unwrap());
70+
}
6871
regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn));
6972
}
7073
}
7174

72-
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) {
75+
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>) {
7376
let mut regular = self.regular;
7477
unsafe {
7578
let deref = self.pointee_size.bytes();
@@ -90,6 +93,9 @@ impl ArgAttributesExt for ArgAttributes {
9093
idx.as_uint(),
9194
align.bytes() as u32);
9295
}
96+
if regular.contains(ArgAttribute::ByVal) {
97+
llvm::LLVMRustAddByValCallSiteAttr(callsite, idx.as_uint(), ty.unwrap());
98+
}
9399
regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite));
94100
}
95101
}
@@ -298,7 +304,7 @@ pub trait FnTypeLlvmExt<'tcx> {
298304
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
299305
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
300306
fn llvm_cconv(&self) -> llvm::CallConv;
301-
fn apply_attrs_llfn(&self, llfn: &'ll Value);
307+
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value);
302308
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
303309
}
304310

@@ -384,51 +390,51 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
384390
}
385391
}
386392

387-
fn apply_attrs_llfn(&self, llfn: &'ll Value) {
393+
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
388394
let mut i = 0;
389-
let mut apply = |attrs: &ArgAttributes| {
390-
attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
395+
let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
396+
attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty);
391397
i += 1;
392398
};
393399
match self.ret.mode {
394400
PassMode::Direct(ref attrs) => {
395-
attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn);
401+
attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn, None);
396402
}
397-
PassMode::Indirect(ref attrs, _) => apply(attrs),
403+
PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(cx))),
398404
_ => {}
399405
}
400406
for arg in &self.args {
401407
if arg.pad.is_some() {
402-
apply(&ArgAttributes::new());
408+
apply(&ArgAttributes::new(), None);
403409
}
404410
match arg.mode {
405411
PassMode::Ignore(_) => {}
406412
PassMode::Direct(ref attrs) |
407-
PassMode::Indirect(ref attrs, None) => apply(attrs),
413+
PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(cx))),
408414
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
409-
apply(attrs);
410-
apply(extra_attrs);
415+
apply(attrs, None);
416+
apply(extra_attrs, None);
411417
}
412418
PassMode::Pair(ref a, ref b) => {
413-
apply(a);
414-
apply(b);
419+
apply(a, None);
420+
apply(b, None);
415421
}
416-
PassMode::Cast(_) => apply(&ArgAttributes::new()),
422+
PassMode::Cast(_) => apply(&ArgAttributes::new(), None),
417423
}
418424
}
419425
}
420426

421427
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
422428
let mut i = 0;
423-
let mut apply = |attrs: &ArgAttributes| {
424-
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
429+
let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
430+
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty);
425431
i += 1;
426432
};
427433
match self.ret.mode {
428434
PassMode::Direct(ref attrs) => {
429-
attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite);
435+
attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite, None);
430436
}
431-
PassMode::Indirect(ref attrs, _) => apply(attrs),
437+
PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(bx))),
432438
_ => {}
433439
}
434440
if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi {
@@ -446,21 +452,21 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
446452
}
447453
for arg in &self.args {
448454
if arg.pad.is_some() {
449-
apply(&ArgAttributes::new());
455+
apply(&ArgAttributes::new(), None);
450456
}
451457
match arg.mode {
452458
PassMode::Ignore(_) => {}
453459
PassMode::Direct(ref attrs) |
454-
PassMode::Indirect(ref attrs, None) => apply(attrs),
460+
PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(bx))),
455461
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
456-
apply(attrs);
457-
apply(extra_attrs);
462+
apply(attrs, None);
463+
apply(extra_attrs, None);
458464
}
459465
PassMode::Pair(ref a, ref b) => {
460-
apply(a);
461-
apply(b);
466+
apply(a, None);
467+
apply(b, None);
462468
}
463-
PassMode::Cast(_) => apply(&ArgAttributes::new()),
469+
PassMode::Cast(_) => apply(&ArgAttributes::new(), None),
464470
}
465471
}
466472

src/librustc_codegen_llvm/declare.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
107107
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
108108
}
109109

110-
fty.apply_attrs_llfn(llfn);
110+
fty.apply_attrs_llfn(self, llfn);
111111

112112
llfn
113113
}

src/librustc_codegen_llvm/llvm/ffi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ extern "C" {
794794
pub fn LLVMRustAddAlignmentAttr(Fn: &Value, index: c_uint, bytes: u32);
795795
pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64);
796796
pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64);
797+
pub fn LLVMRustAddByValAttr(Fn: &Value, index: c_uint, ty: &Type);
797798
pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute);
798799
pub fn LLVMRustAddFunctionAttrStringValue(Fn: &Value,
799800
index: c_uint,
@@ -824,6 +825,7 @@ extern "C" {
824825
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value,
825826
index: c_uint,
826827
bytes: u64);
828+
pub fn LLVMRustAddByValCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type);
827829

828830
// Operations on load/store instructions (only)
829831
pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool);

src/rustllvm/RustWrapper.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,17 @@ extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
237237
Call->getContext(), Index, B));
238238
}
239239

240+
extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
241+
LLVMTypeRef Ty) {
242+
CallSite Call = CallSite(unwrap<Instruction>(Instr));
243+
#if LLVM_VERSION_GE(9, 0)
244+
Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
245+
#else
246+
Attribute Attr = Attribute::get(Call->getContext(), Attribute::ByVal);
247+
#endif
248+
Call.addAttribute(Index, Attr);
249+
}
250+
240251
extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
241252
LLVMRustAttribute RustAttr) {
242253
Function *A = unwrap<Function>(Fn);
@@ -271,6 +282,17 @@ extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
271282
A->addAttributes(Index, B);
272283
}
273284

285+
extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
286+
LLVMTypeRef Ty) {
287+
Function *F = unwrap<Function>(Fn);
288+
#if LLVM_VERSION_GE(9, 0)
289+
Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
290+
#else
291+
Attribute Attr = Attribute::get(F->getContext(), Attribute::ByVal);
292+
#endif
293+
F->addAttribute(Index, Attr);
294+
}
295+
274296
extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
275297
unsigned Index,
276298
const char *Name,

0 commit comments

Comments
 (0)