Skip to content

Commit 62cf644

Browse files
committed
Merge apply_attrs_callsite into call and invoke
Some codegen backends are not able to apply callsite attrs after the fact.
1 parent a3cc67c commit 62cf644

File tree

13 files changed

+98
-52
lines changed

13 files changed

+98
-52
lines changed

compiler/rustc_codegen_gcc/src/abi.rs

-4
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ use crate::intrinsic::ArgAbiExt;
1111
use crate::type_of::LayoutGccExt;
1212

1313
impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
14-
fn apply_attrs_callsite(&mut self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _callsite: Self::Value) {
15-
// TODO(antoyo)
16-
}
17-
1814
fn get_param(&mut self, index: usize) -> Self::Value {
1915
let func = self.current_func();
2016
let param = func.get_param(index as i32);

compiler/rustc_codegen_gcc/src/asm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
498498
if options.contains(InlineAsmOptions::NORETURN) {
499499
let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable");
500500
let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) };
501-
self.call(self.type_void(), builtin_unreachable, &[], None);
501+
self.call(self.type_void(), None, builtin_unreachable, &[], None);
502502
}
503503

504504
// Write results to outputs.

compiler/rustc_codegen_gcc/src/builder.rs

+27-4
Original file line numberDiff line numberDiff line change
@@ -444,11 +444,23 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
444444
self.block.end_with_switch(None, value, default_block, &gcc_cases);
445445
}
446446

447-
fn invoke(&mut self, typ: Type<'gcc>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> {
447+
fn invoke(
448+
&mut self,
449+
typ: Type<'gcc>,
450+
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
451+
func: RValue<'gcc>,
452+
args: &[RValue<'gcc>],
453+
then: Block<'gcc>,
454+
catch: Block<'gcc>,
455+
_funclet: Option<&Funclet>,
456+
) -> RValue<'gcc> {
448457
// TODO(bjorn3): Properly implement unwinding.
449-
let call_site = self.call(typ, func, args, None);
458+
let call_site = self.call(typ, None, func, args, None);
450459
let condition = self.context.new_rvalue_from_int(self.bool_type, 1);
451460
self.llbb().end_with_conditional(None, condition, then, catch);
461+
if let Some(_fn_abi) = fn_abi {
462+
// TODO(bjorn3): Apply function attributes
463+
}
452464
call_site
453465
}
454466

@@ -1227,16 +1239,27 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
12271239
// TODO(antoyo)
12281240
}
12291241

1230-
fn call(&mut self, _typ: Type<'gcc>, func: RValue<'gcc>, args: &[RValue<'gcc>], funclet: Option<&Funclet>) -> RValue<'gcc> {
1242+
fn call(
1243+
&mut self,
1244+
_typ: Type<'gcc>,
1245+
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
1246+
func: RValue<'gcc>,
1247+
args: &[RValue<'gcc>],
1248+
funclet: Option<&Funclet>,
1249+
) -> RValue<'gcc> {
12311250
// FIXME(antoyo): remove when having a proper API.
12321251
let gcc_func = unsafe { std::mem::transmute(func) };
1233-
if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() {
1252+
let call = if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() {
12341253
self.function_call(func, args, funclet)
12351254
}
12361255
else {
12371256
// If it's a not function that was defined, it's a function pointer.
12381257
self.function_ptr_call(func, args, funclet)
1258+
};
1259+
if let Some(_fn_abi) = fn_abi {
1260+
// TODO(bjorn3): Apply function attributes
12391261
}
1262+
call
12401263
}
12411264

12421265
fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
100100
_ if simple.is_some() => {
101101
// FIXME(antoyo): remove this cast when the API supports function.
102102
let func = unsafe { std::mem::transmute(simple.expect("simple")) };
103-
self.call(self.type_void(), func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None)
103+
self.call(self.type_void(), None, func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None)
104104
},
105105
sym::likely => {
106106
self.expect(args[0].immediate(), true)
@@ -341,7 +341,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
341341
fn abort(&mut self) {
342342
let func = self.context.get_builtin_function("abort");
343343
let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
344-
self.call(self.type_void(), func, &[], None);
344+
self.call(self.type_void(), None, func, &[], None);
345345
}
346346

347347
fn assume(&mut self, value: Self::Value) {
@@ -1124,7 +1124,7 @@ fn try_intrinsic<'gcc, 'tcx>(bx: &mut Builder<'_, 'gcc, 'tcx>, try_func: RValue<
11241124
// NOTE: the `|| true` here is to use the panic=abort strategy with panic=unwind too
11251125
if bx.sess().panic_strategy() == PanicStrategy::Abort || true {
11261126
// TODO(bjorn3): Properly implement unwinding and remove the `|| true` once this is done.
1127-
bx.call(bx.type_void(), try_func, &[data], None);
1127+
bx.call(bx.type_void(), None, try_func, &[data], None);
11281128
// Return 0 unconditionally from the intrinsic call;
11291129
// we can never unwind.
11301130
let ret_align = bx.tcx.data_layout.i32_align.abi;

compiler/rustc_codegen_gcc/src/intrinsic/simd.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
461461
let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
462462
let function = intrinsic::llvm::intrinsic(llvm_name, &bx.cx);
463463
let function: RValue<'gcc> = unsafe { std::mem::transmute(function) };
464-
let c = bx.call(fn_ty, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
464+
let c = bx.call(fn_ty, None, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
465465
Ok(c)
466466
}
467467

compiler/rustc_codegen_llvm/src/abi.rs

-4
Original file line numberDiff line numberDiff line change
@@ -592,10 +592,6 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
592592
}
593593

594594
impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
595-
fn apply_attrs_callsite(&mut self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, callsite: Self::Value) {
596-
fn_abi.apply_attrs_callsite(self, callsite)
597-
}
598-
599595
fn get_param(&mut self, index: usize) -> Self::Value {
600596
llvm::get_param(self.llfn(), index as c_uint)
601597
}

compiler/rustc_codegen_llvm/src/asm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,9 @@ pub(crate) fn inline_asm_call<'ll>(
430430
);
431431

432432
let call = if let Some((dest, catch, funclet)) = dest_catch_funclet {
433-
bx.invoke(fty, v, inputs, dest, catch, funclet)
433+
bx.invoke(fty, None, v, inputs, dest, catch, funclet)
434434
} else {
435-
bx.call(fty, v, inputs, None)
435+
bx.call(fty, None, v, inputs, None)
436436
};
437437

438438
// Store mark in a metadata node so we can map LLVM errors

compiler/rustc_codegen_llvm/src/builder.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::abi::FnAbiLlvmExt;
12
use crate::attributes;
23
use crate::common::Funclet;
34
use crate::context::CodegenCx;
@@ -214,6 +215,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
214215
fn invoke(
215216
&mut self,
216217
llty: &'ll Type,
218+
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
217219
llfn: &'ll Value,
218220
args: &[&'ll Value],
219221
then: &'ll BasicBlock,
@@ -226,7 +228,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
226228
let bundle = funclet.map(|funclet| funclet.bundle());
227229
let bundle = bundle.as_ref().map(|b| &*b.raw);
228230

229-
unsafe {
231+
let invoke = unsafe {
230232
llvm::LLVMRustBuildInvoke(
231233
self.llbuilder,
232234
llty,
@@ -238,7 +240,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
238240
bundle,
239241
UNNAMED,
240242
)
243+
};
244+
if let Some(fn_abi) = fn_abi {
245+
fn_abi.apply_attrs_callsite(self, invoke);
241246
}
247+
invoke
242248
}
243249

244250
fn unreachable(&mut self) {
@@ -1145,6 +1151,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11451151
fn call(
11461152
&mut self,
11471153
llty: &'ll Type,
1154+
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
11481155
llfn: &'ll Value,
11491156
args: &[&'ll Value],
11501157
funclet: Option<&Funclet<'ll>>,
@@ -1155,7 +1162,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11551162
let bundle = funclet.map(|funclet| funclet.bundle());
11561163
let bundle = bundle.as_ref().map(|b| &*b.raw);
11571164

1158-
unsafe {
1165+
let call = unsafe {
11591166
llvm::LLVMRustBuildCall(
11601167
self.llbuilder,
11611168
llty,
@@ -1164,7 +1171,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11641171
args.len() as c_uint,
11651172
bundle,
11661173
)
1174+
};
1175+
if let Some(fn_abi) = fn_abi {
1176+
fn_abi.apply_attrs_callsite(self, call);
11671177
}
1178+
call
11681179
}
11691180

11701181
fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
@@ -1397,7 +1408,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
13971408

13981409
pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
13991410
let (ty, f) = self.cx.get_intrinsic(intrinsic);
1400-
self.call(ty, f, args, None)
1411+
self.call(ty, None, f, args, None)
14011412
}
14021413

14031414
fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
@@ -1459,7 +1470,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
14591470
format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width)
14601471
};
14611472
let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
1462-
self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None)
1473+
self.call(self.type_func(&[src_ty], dest_ty), None, f, &[val], None)
14631474
}
14641475

14651476
pub(crate) fn landing_pad(

compiler/rustc_codegen_llvm/src/intrinsic.rs

+34-18
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
108108
let (simple_ty, simple_fn) = simple.unwrap();
109109
self.call(
110110
simple_ty,
111+
None,
111112
simple_fn,
112113
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
113114
None,
@@ -435,7 +436,7 @@ fn try_intrinsic<'ll>(
435436
) {
436437
if bx.sess().panic_strategy() == PanicStrategy::Abort {
437438
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
438-
bx.call(try_func_ty, try_func, &[data], None);
439+
bx.call(try_func_ty, None, try_func, &[data], None);
439440
// Return 0 unconditionally from the intrinsic call;
440441
// we can never unwind.
441442
let ret_align = bx.tcx().data_layout.i32_align.abi;
@@ -534,7 +535,7 @@ fn codegen_msvc_try<'ll>(
534535
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
535536
let slot = bx.alloca(bx.type_i8p(), ptr_align);
536537
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
537-
bx.invoke(try_func_ty, try_func, &[data], normal, catchswitch, None);
538+
bx.invoke(try_func_ty, None, try_func, &[data], normal, catchswitch, None);
538539

539540
bx.switch_to_block(normal);
540541
bx.ret(bx.const_i32(0));
@@ -578,15 +579,15 @@ fn codegen_msvc_try<'ll>(
578579
let funclet = bx.catch_pad(cs, &[tydesc, flags, slot]);
579580
let ptr = bx.load(bx.type_i8p(), slot, ptr_align);
580581
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
581-
bx.call(catch_ty, catch_func, &[data, ptr], Some(&funclet));
582+
bx.call(catch_ty, None, catch_func, &[data, ptr], Some(&funclet));
582583
bx.catch_ret(&funclet, caught);
583584

584585
// The flag value of 64 indicates a "catch-all".
585586
bx.switch_to_block(catchpad_foreign);
586587
let flags = bx.const_i32(64);
587588
let null = bx.const_null(bx.type_i8p());
588589
let funclet = bx.catch_pad(cs, &[null, flags, null]);
589-
bx.call(catch_ty, catch_func, &[data, null], Some(&funclet));
590+
bx.call(catch_ty, None, catch_func, &[data, null], Some(&funclet));
590591
bx.catch_ret(&funclet, caught);
591592

592593
bx.switch_to_block(caught);
@@ -595,7 +596,7 @@ fn codegen_msvc_try<'ll>(
595596

596597
// Note that no invoke is used here because by definition this function
597598
// can't panic (that's what it's catching).
598-
let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None);
599+
let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None);
599600
let i32_align = bx.tcx().data_layout.i32_align.abi;
600601
bx.store(ret, dest, i32_align);
601602
}
@@ -638,7 +639,7 @@ fn codegen_gnu_try<'ll>(
638639
let data = llvm::get_param(bx.llfn(), 1);
639640
let catch_func = llvm::get_param(bx.llfn(), 2);
640641
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
641-
bx.invoke(try_func_ty, try_func, &[data], then, catch, None);
642+
bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None);
642643

643644
bx.switch_to_block(then);
644645
bx.ret(bx.const_i32(0));
@@ -656,13 +657,13 @@ fn codegen_gnu_try<'ll>(
656657
bx.add_clause(vals, tydesc);
657658
let ptr = bx.extract_value(vals, 0);
658659
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
659-
bx.call(catch_ty, catch_func, &[data, ptr], None);
660+
bx.call(catch_ty, None, catch_func, &[data, ptr], None);
660661
bx.ret(bx.const_i32(1));
661662
});
662663

663664
// Note that no invoke is used here because by definition this function
664665
// can't panic (that's what it's catching).
665-
let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None);
666+
let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None);
666667
let i32_align = bx.tcx().data_layout.i32_align.abi;
667668
bx.store(ret, dest, i32_align);
668669
}
@@ -702,7 +703,7 @@ fn codegen_emcc_try<'ll>(
702703
let data = llvm::get_param(bx.llfn(), 1);
703704
let catch_func = llvm::get_param(bx.llfn(), 2);
704705
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
705-
bx.invoke(try_func_ty, try_func, &[data], then, catch, None);
706+
bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None);
706707

707708
bx.switch_to_block(then);
708709
bx.ret(bx.const_i32(0));
@@ -741,13 +742,13 @@ fn codegen_emcc_try<'ll>(
741742
let catch_data = bx.bitcast(catch_data, bx.type_i8p());
742743

743744
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
744-
bx.call(catch_ty, catch_func, &[data, catch_data], None);
745+
bx.call(catch_ty, None, catch_func, &[data, catch_data], None);
745746
bx.ret(bx.const_i32(1));
746747
});
747748

748749
// Note that no invoke is used here because by definition this function
749750
// can't panic (that's what it's catching).
750-
let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None);
751+
let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None);
751752
let i32_align = bx.tcx().data_layout.i32_align.abi;
752753
bx.store(ret, dest, i32_align);
753754
}
@@ -1217,8 +1218,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
12171218
};
12181219
let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
12191220
let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty);
1220-
let c =
1221-
bx.call(fn_ty, f, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
1221+
let c = bx.call(
1222+
fn_ty,
1223+
None,
1224+
f,
1225+
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
1226+
None,
1227+
);
12221228
Ok(c)
12231229
}
12241230

@@ -1417,8 +1423,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
14171423
llvm_elem_vec_ty,
14181424
);
14191425
let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
1420-
let v =
1421-
bx.call(fn_ty, f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None);
1426+
let v = bx.call(
1427+
fn_ty,
1428+
None,
1429+
f,
1430+
&[args[1].immediate(), alignment, mask, args[0].immediate()],
1431+
None,
1432+
);
14221433
return Ok(v);
14231434
}
14241435

@@ -1543,8 +1554,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15431554
let fn_ty =
15441555
bx.type_func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, mask_ty], ret_t);
15451556
let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
1546-
let v =
1547-
bx.call(fn_ty, f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None);
1557+
let v = bx.call(
1558+
fn_ty,
1559+
None,
1560+
f,
1561+
&[args[0].immediate(), args[1].immediate(), alignment, mask],
1562+
None,
1563+
);
15481564
return Ok(v);
15491565
}
15501566

@@ -1992,7 +2008,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
19922008

19932009
let fn_ty = bx.type_func(&[vec_ty, vec_ty], vec_ty);
19942010
let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
1995-
let v = bx.call(fn_ty, f, &[lhs, rhs], None);
2011+
let v = bx.call(fn_ty, None, f, &[lhs, rhs], None);
19962012
return Ok(v);
19972013
}
19982014

compiler/rustc_codegen_ssa/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
474474
(rust_main, start_ty, vec![arg_argc, arg_argv])
475475
};
476476

477-
let result = bx.call(start_ty, start_fn, &args, None);
477+
let result = bx.call(start_ty, None, start_fn, &args, None);
478478
let cast = bx.intcast(result, cx.type_int(), true);
479479
bx.ret(cast);
480480

0 commit comments

Comments
 (0)