Skip to content

Commit d492d09

Browse files
committed
trans: Apply ZExt and StructRet attributes uniformly.
1 parent ac60318 commit d492d09

13 files changed

+67
-157
lines changed

src/librustc_trans/trans/abi.rs

+29-13
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010

1111
pub use self::ArgKind::*;
1212

13-
use llvm::{self, AttrHelper, ValueRef};
14-
use trans::attributes;
13+
use llvm;
1514
use trans::common::{return_type_is_void, type_is_fat_ptr};
1615
use trans::context::CrateContext;
1716
use trans::cabi_x86;
@@ -23,7 +22,7 @@ use trans::cabi_powerpc;
2322
use trans::cabi_powerpc64;
2423
use trans::cabi_mips;
2524
use trans::cabi_asmjs;
26-
use trans::machine::llsize_of_alloc;
25+
use trans::machine::{llsize_of_alloc, llsize_of_real};
2726
use trans::type_::Type;
2827
use trans::type_of;
2928

@@ -191,6 +190,13 @@ impl FnType {
191190
cconv: cconv
192191
};
193192

193+
// Add ZExt attributes to i1 arguments and returns.
194+
for arg in Some(&mut fty.ret).into_iter().chain(&mut fty.args) {
195+
if arg.ty == Type::i1(ccx) {
196+
arg.attr = Some(llvm::Attribute::ZExt);
197+
}
198+
}
199+
194200
if abi == Rust || abi == RustCall {
195201
let fixup = |arg: &mut ArgType| {
196202
if !arg.ty.is_aggregate() {
@@ -246,7 +252,7 @@ impl FnType {
246252
fty
247253
}
248254

249-
pub fn to_llvm(&self, ccx: &CrateContext) -> Type {
255+
pub fn llvm_type(&self, ccx: &CrateContext) -> Type {
250256
let mut llargument_tys = Vec::new();
251257

252258
let llreturn_ty = if self.ret.is_indirect() {
@@ -281,19 +287,29 @@ impl FnType {
281287
}
282288
}
283289

284-
pub fn add_attributes(&self, llfn: ValueRef) {
285-
let mut i = if self.ret.is_indirect() {
286-
1
287-
} else {
288-
0
290+
pub fn llvm_attrs(&self, ccx: &CrateContext) -> llvm::AttrBuilder {
291+
let mut attrs = llvm::AttrBuilder::new();
292+
let mut i = if self.ret.is_indirect() { 1 } else { 0 };
293+
294+
// Add attributes that are always applicable, independent of the concrete foreign ABI
295+
if self.ret.is_indirect() {
296+
let llret_sz = llsize_of_real(ccx, self.ret.ty);
297+
298+
// The outptr can be noalias and nocapture because it's entirely
299+
// invisible to the program. We also know it's nonnull as well
300+
// as how many bytes we can dereference
301+
attrs.arg(i, llvm::Attribute::StructRet)
302+
.arg(i, llvm::Attribute::NoAlias)
303+
.arg(i, llvm::Attribute::NoCapture)
304+
.arg(i, llvm::DereferenceableAttribute(llret_sz));
289305
};
290306

307+
// Add attributes that depend on the concrete foreign ABI
291308
if let Some(attr) = self.ret.attr {
292-
attr.apply_llfn(i, llfn);
309+
attrs.arg(i, attr);
293310
}
294311

295312
i += 1;
296-
297313
for arg in &self.args {
298314
if arg.is_ignore() {
299315
continue;
@@ -302,12 +318,12 @@ impl FnType {
302318
if arg.pad.is_some() { i += 1; }
303319

304320
if let Some(attr) = arg.attr {
305-
attr.apply_llfn(i, llfn);
321+
attrs.arg(i, attr);
306322
}
307323

308324
i += 1;
309325
}
310326

311-
attributes::unwind(llfn, false);
327+
attrs
312328
}
313329
}

src/librustc_trans/trans/cabi_aarch64.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#![allow(non_upper_case_globals)]
1212

13-
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector, Attribute};
13+
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
1414
use trans::abi::{FnType, ArgType, Indirect};
1515
use trans::context::CrateContext;
1616
use trans::type_::Type;
@@ -163,9 +163,6 @@ fn is_homogenous_aggregate_ty(ty: Type) -> Option<(Type, u64)> {
163163

164164
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
165165
if is_reg_ty(ret.ty) {
166-
if ret.ty == Type::i1(ccx) {
167-
ret.attr = Some(Attribute::ZExt)
168-
}
169166
return;
170167
}
171168
if let Some((base_ty, members)) = is_homogenous_aggregate_ty(ret.ty) {
@@ -189,14 +186,10 @@ fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
189186
return;
190187
}
191188
ret.kind = Indirect;
192-
ret.attr = Some(Attribute::StructRet);
193189
}
194190

195191
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType) {
196192
if is_reg_ty(arg.ty) {
197-
if arg.ty == Type::i1(ccx) {
198-
arg.attr = Some(Attribute::ZExt);
199-
}
200193
return;
201194
}
202195
if let Some((base_ty, members)) = is_homogenous_aggregate_ty(arg.ty) {

src/librustc_trans/trans/cabi_arm.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#![allow(non_upper_case_globals)]
1212

13-
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector, Attribute};
13+
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
1414
use trans::abi::{FnType, ArgType, Indirect};
1515
use trans::context::CrateContext;
1616
use trans::type_::Type;
@@ -131,9 +131,6 @@ fn ty_size(ty: Type, align_fn: TyAlignFn) -> usize {
131131

132132
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType, align_fn: TyAlignFn) {
133133
if is_reg_ty(ret.ty) {
134-
if ret.ty == Type::i1(ccx) {
135-
ret.attr = Some(Attribute::ZExt);
136-
}
137134
return;
138135
}
139136
let size = ty_size(ret.ty, align_fn);
@@ -149,14 +146,10 @@ fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType, align_fn: TyAlignFn) {
149146
return;
150147
}
151148
ret.kind = Indirect;
152-
ret.attr = Some(Attribute::StructRet);
153149
}
154150

155151
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, align_fn: TyAlignFn) {
156152
if is_reg_ty(arg.ty) {
157-
if arg.ty == Type::i1(ccx) {
158-
arg.attr = Some(Attribute::ZExt);
159-
}
160153
return;
161154
}
162155
let align = align_fn(arg.ty);

src/librustc_trans/trans/cabi_asmjs.rs

+6-16
Original file line numberDiff line numberDiff line change
@@ -20,46 +20,36 @@ use trans::type_::Type;
2020
// See the https://github.com/kripken/emscripten-fastcomp-clang repository.
2121
// The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions.
2222

23-
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
23+
fn classify_ret_ty(ret: &mut ArgType) {
2424
match ret.ty.kind() {
2525
Struct => {
2626
let field_types = ret.ty.field_types();
2727
if field_types.len() == 1 {
2828
ret.cast = Some(field_types[0]);
2929
} else {
3030
ret.kind = Indirect;
31-
ret.attr = Some(Attribute::StructRet);
3231
}
33-
},
32+
}
3433
Array => {
3534
ret.kind = Indirect;
36-
ret.attr = Some(Attribute::StructRet);
37-
},
38-
_ => {
39-
if ret.ty == Type::i1(ccx) {
40-
ret.attr = Some(Attribute::ZExt);
41-
}
4235
}
36+
_ => {}
4337
}
4438
}
4539

46-
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType) {
40+
fn classify_arg_ty(arg: &mut ArgType) {
4741
if arg.ty.is_aggregate() {
4842
arg.kind = Indirect;
4943
arg.attr = Some(Attribute::ByVal);
50-
} else {
51-
if arg.ty == Type::i1(ccx) {
52-
arg.attr = Some(Attribute::ZExt);
53-
}
5444
}
5545
}
5646

5747
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
5848
if fty.ret.ty != Type::void(ccx) {
59-
classify_ret_ty(ccx, &mut fty.ret);
49+
classify_ret_ty(&mut fty.ret);
6050
}
6151

6252
for arg in &mut fty.args {
63-
classify_arg_ty(ccx, arg);
53+
classify_arg_ty(arg);
6454
}
6555
}

src/librustc_trans/trans/cabi_mips.rs

+5-18
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use libc::c_uint;
1414
use std::cmp;
1515
use llvm;
16-
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector, Attribute};
16+
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
1717
use trans::abi::{ArgType, FnType, Indirect};
1818
use trans::context::CrateContext;
1919
use trans::type_::Type;
@@ -86,17 +86,6 @@ fn ty_size(ty: Type) -> usize {
8686
}
8787
}
8888

89-
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
90-
if is_reg_ty(ret.ty) {
91-
if ret.ty == Type::i1(ccx) {
92-
ret.attr = Some(Attribute::ZExt);
93-
}
94-
} else {
95-
ret.kind = Indirect;
96-
ret.attr = Some(Attribute::StructRet);
97-
}
98-
}
99-
10089
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut usize) {
10190
let orig_offset = *offset;
10291
let size = ty_size(arg.ty) * 8;
@@ -106,11 +95,7 @@ fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut usize) {
10695
*offset = align_up_to(*offset, align);
10796
*offset += align_up_to(size, align * 8) / 8;
10897

109-
if is_reg_ty(arg.ty) {
110-
if arg.ty == Type::i1(ccx) {
111-
arg.attr = Some(Attribute::ZExt);
112-
}
113-
} else {
98+
if !is_reg_ty(arg.ty) {
11499
arg.cast = Some(struct_ty(ccx, arg.ty));
115100
arg.pad = padding_ty(ccx, align, orig_offset);
116101
}
@@ -162,7 +147,9 @@ fn struct_ty(ccx: &CrateContext, ty: Type) -> Type {
162147

163148
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
164149
if fty.ret.ty != Type::void(ccx) {
165-
classify_ret_ty(ccx, &mut fty.ret);
150+
if !is_reg_ty(fty.ret.ty) {
151+
fty.ret.kind = Indirect;
152+
}
166153
}
167154

168155
let mut offset = if fty.ret.is_indirect() { 4 } else { 0 };

src/librustc_trans/trans/cabi_powerpc.rs

+5-18
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use libc::c_uint;
1212
use llvm;
13-
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Attribute};
13+
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
1414
use trans::abi::{FnType, ArgType, Indirect};
1515
use trans::context::CrateContext;
1616
use trans::type_::Type;
@@ -82,17 +82,6 @@ fn ty_size(ty: Type) -> usize {
8282
}
8383
}
8484

85-
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
86-
if is_reg_ty(ret.ty) {
87-
if ret.ty == Type::i1(ccx) {
88-
ret.attr = Some(Attribute::ZExt);
89-
}
90-
} else {
91-
ret.kind = Indirect;
92-
ret.attr = Some(Attribute::StructRet);
93-
}
94-
}
95-
9685
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut usize) {
9786
let orig_offset = *offset;
9887
let size = ty_size(arg.ty) * 8;
@@ -102,11 +91,7 @@ fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut usize) {
10291
*offset = align_up_to(*offset, align);
10392
*offset += align_up_to(size, align * 8) / 8;
10493

105-
if is_reg_ty(arg.ty) {
106-
if arg.ty == Type::i1(ccx) {
107-
arg.attr = Some(Attribute::ZExt);
108-
}
109-
} else {
94+
if !is_reg_ty(arg.ty) {
11095
arg.cast = Some(struct_ty(ccx, arg.ty));
11196
arg.pad = padding_ty(ccx, align, orig_offset);
11297
}
@@ -157,7 +142,9 @@ fn struct_ty(ccx: &CrateContext, ty: Type) -> Type {
157142

158143
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
159144
if fty.ret.ty != Type::void(ccx) {
160-
classify_ret_ty(ccx, &mut fty.ret);
145+
if !is_reg_ty(fty.ret.ty) {
146+
fty.ret.kind = Indirect;
147+
}
161148
}
162149

163150
let mut offset = if fty.ret.is_indirect() { 4 } else { 0 };

src/librustc_trans/trans/cabi_powerpc64.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// Alignment of 128 bit types is not currently handled, this will
1616
// need to be fixed when PowerPC vector support is added.
1717

18-
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Attribute};
18+
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
1919
use trans::abi::{FnType, ArgType, Indirect};
2020
use trans::context::CrateContext;
2121
use trans::type_::Type;
@@ -153,16 +153,12 @@ fn is_homogenous_aggregate_ty(ty: Type) -> Option<(Type, u64)> {
153153

154154
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
155155
if is_reg_ty(ret.ty) {
156-
if ret.ty == Type::i1(ccx) {
157-
ret.attr = Some(Attribute::ZExt);
158-
}
159156
return;
160157
}
161158

162159
// The PowerPC64 big endian ABI doesn't return aggregates in registers
163160
if ccx.sess().target.target.target_endian == "big" {
164161
ret.kind = Indirect;
165-
ret.attr = Some(Attribute::StructRet);
166162
}
167163

168164
if let Some((base_ty, members)) = is_homogenous_aggregate_ty(ret.ty) {
@@ -187,14 +183,10 @@ fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
187183
}
188184

189185
ret.kind = Indirect;
190-
ret.attr = Some(Attribute::StructRet);
191186
}
192187

193188
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType) {
194189
if is_reg_ty(arg.ty) {
195-
if arg.ty == Type::i1(ccx) {
196-
arg.attr = Some(Attribute::ZExt);
197-
}
198190
return;
199191
}
200192

src/librustc_trans/trans/cabi_x86.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,11 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
3030
2 => fty.ret.cast = Some(Type::i16(ccx)),
3131
4 => fty.ret.cast = Some(Type::i32(ccx)),
3232
8 => fty.ret.cast = Some(Type::i64(ccx)),
33-
_ => {
34-
fty.ret.kind = Indirect;
35-
fty.ret.attr = Some(Attribute::StructRet);
36-
}
33+
_ => fty.ret.kind = Indirect
3734
}
3835
} else {
3936
fty.ret.kind = Indirect;
40-
fty.ret.attr = Some(Attribute::StructRet);
4137
}
42-
} else if fty.ret.ty == Type::i1(ccx) {
43-
fty.ret.attr = Some(Attribute::ZExt);
4438
}
4539

4640
for arg in &mut fty.args {
@@ -51,8 +45,6 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
5145
arg.kind = Indirect;
5246
arg.attr = Some(Attribute::ByVal);
5347
}
54-
} else if arg.ty == Type::i1(ccx) {
55-
arg.attr = Some(Attribute::ZExt);
5648
}
5749
}
5850
}

0 commit comments

Comments
 (0)