Skip to content

Commit f6e9485

Browse files
committed
Auto merge of #55627 - sunfishcode:cg-llvm-gen, r=nikomatsakis
rustc_codegen_llvm: traitification of LLVM-specific CodegenCx and Builder methods This PR is the continuation of #54012 and earlier PRs, in the grand plan of #45274 to allow for multiple codegen backends. High-level summary: interpose a set of traits between Rust's codegen logic and the LLVM APIs, allowing another backend to implement the traits and share most of the codegen logic. These traits are currently somewhat LLVM-specific, but once this refactoring is in place, they can evolve to be more general. See [this README](https://github.com/rust-lang/rust/blob/756f84d7cef90b7364ae88ca707e59670dde4c92/src/librustc_codegen_ssa/README.md) for a writeup on the current trait organization.
2 parents ee82173 + 756f84d commit f6e9485

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+10107
-7653
lines changed

src/Cargo.lock

+11-2
Original file line numberDiff line numberDiff line change
@@ -2122,23 +2122,32 @@ dependencies = [
21222122
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
21232123
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
21242124
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
2125+
"rustc_codegen_ssa 0.0.0",
21252126
"rustc_llvm 0.0.0",
21262127
]
21272128

2129+
[[package]]
2130+
name = "rustc_codegen_ssa"
2131+
version = "0.0.0"
2132+
dependencies = [
2133+
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
2134+
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
2135+
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
2136+
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
2137+
]
2138+
21282139
[[package]]
21292140
name = "rustc_codegen_utils"
21302141
version = "0.0.0"
21312142
dependencies = [
21322143
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
21332144
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
21342145
"rustc 0.0.0",
2135-
"rustc_allocator 0.0.0",
21362146
"rustc_data_structures 0.0.0",
21372147
"rustc_incremental 0.0.0",
21382148
"rustc_metadata 0.0.0",
21392149
"rustc_mir 0.0.0",
21402150
"rustc_target 0.0.0",
2141-
"serialize 0.0.0",
21422151
"syntax 0.0.0",
21432152
"syntax_pos 0.0.0",
21442153
]

src/librustc_codegen_llvm/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ test = false
1313
cc = "1.0.1"
1414
num_cpus = "1.0"
1515
rustc-demangle = "0.1.4"
16+
rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
1617
rustc_llvm = { path = "../librustc_llvm" }
1718
memmap = "0.6"
1819

src/librustc_codegen_llvm/abi.rs

+108-38
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,20 @@
99
// except according to those terms.
1010

1111
use llvm::{self, AttributePlace};
12-
use base;
13-
use builder::{Builder, MemFlags};
14-
use common::C_usize;
12+
use rustc_codegen_ssa::MemFlags;
13+
use builder::Builder;
1514
use context::CodegenCx;
16-
use mir::place::PlaceRef;
17-
use mir::operand::OperandValue;
15+
use rustc_codegen_ssa::mir::place::PlaceRef;
16+
use rustc_codegen_ssa::mir::operand::OperandValue;
1817
use type_::Type;
1918
use type_of::{LayoutLlvmExt, PointerKind};
2019
use value::Value;
20+
use rustc_target::abi::call::ArgType;
21+
22+
use rustc_codegen_ssa::traits::*;
2123

2224
use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout, Abi as LayoutAbi};
23-
use rustc::ty::{self, Ty};
25+
use rustc::ty::{self, Ty, Instance};
2426
use rustc::ty::layout;
2527

2628
use libc::c_uint;
@@ -110,16 +112,16 @@ pub trait LlvmType {
110112
impl LlvmType for Reg {
111113
fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
112114
match self.kind {
113-
RegKind::Integer => Type::ix(cx, self.size.bits()),
115+
RegKind::Integer => cx.type_ix(self.size.bits()),
114116
RegKind::Float => {
115117
match self.size.bits() {
116-
32 => Type::f32(cx),
117-
64 => Type::f64(cx),
118+
32 => cx.type_f32(),
119+
64 => cx.type_f64(),
118120
_ => bug!("unsupported float: {:?}", self)
119121
}
120122
}
121123
RegKind::Vector => {
122-
Type::vector(Type::i8(cx), self.size.bytes())
124+
cx.type_vector(cx.type_i8(), self.size.bytes())
123125
}
124126
}
125127
}
@@ -143,7 +145,7 @@ impl LlvmType for CastTarget {
143145

144146
// Simplify to array when all chunks are the same size and type
145147
if rem_bytes == 0 {
146-
return Type::array(rest_ll_unit, rest_count);
148+
return cx.type_array(rest_ll_unit, rest_count);
147149
}
148150
}
149151

@@ -158,17 +160,27 @@ impl LlvmType for CastTarget {
158160
if rem_bytes != 0 {
159161
// Only integers can be really split further.
160162
assert_eq!(self.rest.unit.kind, RegKind::Integer);
161-
args.push(Type::ix(cx, rem_bytes * 8));
163+
args.push(cx.type_ix(rem_bytes * 8));
162164
}
163165

164-
Type::struct_(cx, &args, false)
166+
cx.type_struct(&args, false)
165167
}
166168
}
167169

168170
pub trait ArgTypeExt<'ll, 'tcx> {
169171
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
170-
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>);
171-
fn store_fn_arg(&self, bx: &Builder<'_, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>);
172+
fn store(
173+
&self,
174+
bx: &mut Builder<'_, 'll, 'tcx>,
175+
val: &'ll Value,
176+
dst: PlaceRef<'tcx, &'ll Value>,
177+
);
178+
fn store_fn_arg(
179+
&self,
180+
bx: &mut Builder<'_, 'll, 'tcx>,
181+
idx: &mut usize,
182+
dst: PlaceRef<'tcx, &'ll Value>,
183+
);
172184
}
173185

174186
impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
@@ -182,11 +194,15 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
182194
/// place for the original Rust type of this argument/return.
183195
/// Can be used for both storing formal arguments into Rust variables
184196
/// or results of call/invoke instructions into their destinations.
185-
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>) {
197+
fn store(
198+
&self,
199+
bx: &mut Builder<'_, 'll, 'tcx>,
200+
val: &'ll Value,
201+
dst: PlaceRef<'tcx, &'ll Value>,
202+
) {
186203
if self.is_ignore() {
187204
return;
188205
}
189-
let cx = bx.cx;
190206
if self.is_sized_indirect() {
191207
OperandValue::Ref(val, None, self.layout.align).store(bx, dst)
192208
} else if self.is_unsized_indirect() {
@@ -196,7 +212,8 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
196212
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
197213
let can_store_through_cast_ptr = false;
198214
if can_store_through_cast_ptr {
199-
let cast_dst = bx.pointercast(dst.llval, cast.llvm_type(cx).ptr_to());
215+
let cast_ptr_llty = bx.cx().type_ptr_to(cast.llvm_type(bx.cx()));
216+
let cast_dst = bx.pointercast(dst.llval, cast_ptr_llty);
200217
bx.store(val, cast_dst, self.layout.align);
201218
} else {
202219
// The actual return type is a struct, but the ABI
@@ -214,22 +231,23 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
214231
// bitcasting to the struct type yields invalid cast errors.
215232

216233
// We instead thus allocate some scratch space...
217-
let scratch_size = cast.size(cx);
218-
let scratch_align = cast.align(cx);
219-
let llscratch = bx.alloca(cast.llvm_type(cx), "abi_cast", scratch_align);
234+
let scratch_size = cast.size(bx.cx());
235+
let scratch_align = cast.align(bx.cx());
236+
let llscratch = bx.alloca(cast.llvm_type(bx.cx()), "abi_cast", scratch_align);
220237
bx.lifetime_start(llscratch, scratch_size);
221238

222239
// ...where we first store the value...
223240
bx.store(val, llscratch, scratch_align);
224241

225242
// ...and then memcpy it to the intended destination.
226-
base::call_memcpy(bx,
227-
bx.pointercast(dst.llval, Type::i8p(cx)),
228-
self.layout.align,
229-
bx.pointercast(llscratch, Type::i8p(cx)),
230-
scratch_align,
231-
C_usize(cx, self.layout.size.bytes()),
232-
MemFlags::empty());
243+
bx.memcpy(
244+
dst.llval,
245+
self.layout.align,
246+
llscratch,
247+
scratch_align,
248+
bx.cx().const_usize(self.layout.size.bytes()),
249+
MemFlags::empty()
250+
);
233251

234252
bx.lifetime_end(llscratch, scratch_size);
235253
}
@@ -238,7 +256,12 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
238256
}
239257
}
240258

241-
fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>) {
259+
fn store_fn_arg(
260+
&self,
261+
bx: &mut Builder<'a, 'll, 'tcx>,
262+
idx: &mut usize,
263+
dst: PlaceRef<'tcx, &'ll Value>,
264+
) {
242265
let mut next = || {
243266
let val = llvm::get_param(bx.llfn(), *idx as c_uint);
244267
*idx += 1;
@@ -259,6 +282,27 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
259282
}
260283
}
261284

285+
impl ArgTypeMethods<'tcx> for Builder<'a, 'll, 'tcx> {
286+
fn store_fn_arg(
287+
&mut self,
288+
ty: &ArgType<'tcx, Ty<'tcx>>,
289+
idx: &mut usize, dst: PlaceRef<'tcx, Self::Value>
290+
) {
291+
ty.store_fn_arg(self, idx, dst)
292+
}
293+
fn store_arg_ty(
294+
&mut self,
295+
ty: &ArgType<'tcx, Ty<'tcx>>,
296+
val: &'ll Value,
297+
dst: PlaceRef<'tcx, &'ll Value>
298+
) {
299+
ty.store(self, val, dst)
300+
}
301+
fn memory_ty(&self, ty: &ArgType<'tcx, Ty<'tcx>>) -> &'ll Type {
302+
ty.memory_ty(self.cx())
303+
}
304+
}
305+
262306
pub trait FnTypeExt<'tcx> {
263307
fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self;
264308
fn new(cx: &CodegenCx<'ll, 'tcx>,
@@ -280,7 +324,7 @@ pub trait FnTypeExt<'tcx> {
280324
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
281325
fn llvm_cconv(&self) -> llvm::CallConv;
282326
fn apply_attrs_llfn(&self, llfn: &'ll Value);
283-
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
327+
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
284328
}
285329

286330
impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
@@ -614,14 +658,14 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
614658
);
615659

616660
let llreturn_ty = match self.ret.mode {
617-
PassMode::Ignore => Type::void(cx),
661+
PassMode::Ignore => cx.type_void(),
618662
PassMode::Direct(_) | PassMode::Pair(..) => {
619663
self.ret.layout.immediate_llvm_type(cx)
620664
}
621665
PassMode::Cast(cast) => cast.llvm_type(cx),
622666
PassMode::Indirect(..) => {
623-
llargument_tys.push(self.ret.memory_ty(cx).ptr_to());
624-
Type::void(cx)
667+
llargument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
668+
cx.type_void()
625669
}
626670
};
627671

@@ -647,15 +691,15 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
647691
continue;
648692
}
649693
PassMode::Cast(cast) => cast.llvm_type(cx),
650-
PassMode::Indirect(_, None) => arg.memory_ty(cx).ptr_to(),
694+
PassMode::Indirect(_, None) => cx.type_ptr_to(arg.memory_ty(cx)),
651695
};
652696
llargument_tys.push(llarg_ty);
653697
}
654698

655699
if self.variadic {
656-
Type::variadic_func(&llargument_tys, llreturn_ty)
700+
cx.type_variadic_func(&llargument_tys, llreturn_ty)
657701
} else {
658-
Type::func(&llargument_tys, llreturn_ty)
702+
cx.type_func(&llargument_tys, llreturn_ty)
659703
}
660704
}
661705

@@ -717,7 +761,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
717761
}
718762
}
719763

720-
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
764+
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
721765
let mut i = 0;
722766
let mut apply = |attrs: &ArgAttributes| {
723767
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
@@ -736,7 +780,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
736780
// by the LLVM verifier.
737781
if let layout::Int(..) = scalar.value {
738782
if !scalar.is_bool() {
739-
let range = scalar.valid_range_exclusive(bx.cx);
783+
let range = scalar.valid_range_exclusive(bx.cx());
740784
if range.start != range.end {
741785
bx.range_metadata(callsite, range);
742786
}
@@ -769,3 +813,29 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
769813
}
770814
}
771815
}
816+
817+
impl AbiMethods<'tcx> for CodegenCx<'ll, 'tcx> {
818+
fn new_fn_type(&self, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>> {
819+
FnType::new(&self, sig, extra_args)
820+
}
821+
fn new_vtable(
822+
&self,
823+
sig: ty::FnSig<'tcx>,
824+
extra_args: &[Ty<'tcx>]
825+
) -> FnType<'tcx, Ty<'tcx>> {
826+
FnType::new_vtable(&self, sig, extra_args)
827+
}
828+
fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>> {
829+
FnType::of_instance(&self, instance)
830+
}
831+
}
832+
833+
impl AbiBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
834+
fn apply_attrs_callsite(
835+
&mut self,
836+
ty: &FnType<'tcx, Ty<'tcx>>,
837+
callsite: Self::Value
838+
) {
839+
ty.apply_attrs_callsite(self, callsite)
840+
}
841+
}

0 commit comments

Comments
 (0)