From: Denis Merigoux Date: Thu, 4 Oct 2018 13:23:10 +0000 (+0200) Subject: Added some docs + start to &mut self builder methods X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=1ebdfbb02641676fb4f8efb1f87cfe8d0d29d2b3;p=rust.git Added some docs + start to &mut self builder methods --- diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 144ee3dd260..b013545d390 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -95,7 +95,7 @@ fn new_block<'b>( llfn: &'ll Value, name: &'b str ) -> Self { - let bx = Builder::with_cx(cx); + let mut bx = Builder::with_cx(cx); let llbb = unsafe { let name = SmallCStr::new(name); llvm::LLVMAppendBasicBlockInContext( @@ -148,40 +148,40 @@ fn count_insn(&self, category: &str) { } } - fn set_value_name(&self, value: &'ll Value, name: &str) { + fn set_value_name(&mut self, value: &'ll Value, name: &str) { let cname = SmallCStr::new(name); unsafe { llvm::LLVMSetValueName(value, cname.as_ptr()); } } - fn position_at_end(&self, llbb: &'ll BasicBlock) { + fn position_at_end(&mut self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb); } } - fn position_at_start(&self, llbb: &'ll BasicBlock) { + fn position_at_start(&mut self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb); } } - fn ret_void(&self) { + fn ret_void(&mut self) { self.count_insn("retvoid"); unsafe { llvm::LLVMBuildRetVoid(self.llbuilder); } } - fn ret(&self, v: &'ll Value) { + fn ret(&mut self, v: &'ll Value) { self.count_insn("ret"); unsafe { llvm::LLVMBuildRet(self.llbuilder, v); } } - fn br(&self, dest: &'ll BasicBlock) { + fn br(&mut self, dest: &'ll BasicBlock) { self.count_insn("br"); unsafe { llvm::LLVMBuildBr(self.llbuilder, dest); @@ -189,7 +189,7 @@ fn br(&self, dest: &'ll BasicBlock) { } fn cond_br( - &self, + &mut self, cond: &'ll Value, then_llbb: &'ll BasicBlock, else_llbb: &'ll BasicBlock, @@ -457,7 +457,7 @@ fn not(&self, v: &'ll Value) -> &'ll Value { } fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { - let bx = Builder::with_cx(self.cx); + let mut bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 86a41fb05d1..7ea14055c3a 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -832,10 +832,10 @@ fn codegen_msvc_try( bx.set_personality_fn(bx.cx().eh_personality()); - let normal = bx.build_sibling_block("normal"); + let mut normal = bx.build_sibling_block("normal"); let catchswitch = bx.build_sibling_block("catchswitch"); let catchpad = bx.build_sibling_block("catchpad"); - let caught = bx.build_sibling_block("caught"); + let mut caught = bx.build_sibling_block("caught"); let func = llvm::get_param(bx.llfn(), 0); let data = llvm::get_param(bx.llfn(), 1); @@ -956,8 +956,8 @@ fn codegen_gnu_try( // expected to be `*mut *mut u8` for this to actually work, but that's // managed by the standard library. - let then = bx.build_sibling_block("then"); - let catch = bx.build_sibling_block("catch"); + let mut then = bx.build_sibling_block("then"); + let mut catch = bx.build_sibling_block("catch"); let func = llvm::get_param(bx.llfn(), 0); let data = llvm::get_param(bx.llfn(), 1); diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 560d266e926..85a9e551abb 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -129,7 +129,7 @@ mod back { pub struct LlvmCodegenBackend(()); -impl BackendMethods for LlvmCodegenBackend { +impl ExtraBackendMethods for LlvmCodegenBackend { type Module = ModuleLlvm; type OngoingCodegen = OngoingCodegen; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 71ad46ac9b3..8b8ea3f9ff5 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -524,7 +524,7 @@ fn create_entry_fn<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( cx.set_frame_pointer_elimination(llfn); cx.apply_target_cpu_attr(llfn); - let bx = Bx::new_block(&cx, llfn, "top"); + let mut bx = Bx::new_block(&cx, llfn, "top"); bx.insert_reference_to_gdb_debug_scripts_section_global(); @@ -560,7 +560,7 @@ fn create_entry_fn<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( time_graph::WorkPackageKind(&["#DE9597", "#FED1D3", "#FDC5C7", "#B46668", "#88494B"]); -pub fn codegen_crate( +pub fn codegen_crate( backend: B, tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver> @@ -785,15 +785,15 @@ pub fn codegen_crate( /// If you see this comment in the code, then it means that this workaround /// worked! We may yet one day track down the mysterious cause of that /// segfault... -struct AbortCodegenOnDrop(Option); +struct AbortCodegenOnDrop(Option); -impl AbortCodegenOnDrop { +impl AbortCodegenOnDrop { fn into_inner(mut self) -> B::OngoingCodegen { self.0.take().unwrap() } } -impl Deref for AbortCodegenOnDrop { +impl Deref for AbortCodegenOnDrop { type Target = B::OngoingCodegen; fn deref(&self) -> &B::OngoingCodegen { @@ -801,13 +801,13 @@ fn deref(&self) -> &B::OngoingCodegen { } } -impl DerefMut for AbortCodegenOnDrop { +impl DerefMut for AbortCodegenOnDrop { fn deref_mut(&mut self) -> &mut B::OngoingCodegen { self.0.as_mut().unwrap() } } -impl Drop for AbortCodegenOnDrop { +impl Drop for AbortCodegenOnDrop { fn drop(&mut self) { if let Some(codegen) = self.0.take() { B::codegen_aborted(codegen); diff --git a/src/librustc_codegen_ssa/interfaces/backend.rs b/src/librustc_codegen_ssa/interfaces/backend.rs index 6cc7d66a207..aeaedda0b88 100644 --- a/src/librustc_codegen_ssa/interfaces/backend.rs +++ b/src/librustc_codegen_ssa/interfaces/backend.rs @@ -18,6 +18,7 @@ use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::util::time_graph::TimeGraph; +use rustc_codegen_utils::codegen_backend::CodegenBackend; use std::any::Any; use std::sync::mpsc::Receiver; use syntax_pos::symbol::InternedString; @@ -42,7 +43,7 @@ impl<'tcx, T> Backend<'tcx> for T where Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf, TyLayout = TyLayout<'tcx>> {} -pub trait BackendMethods { +pub trait ExtraBackendMethods: CodegenBackend { type Module; type OngoingCodegen; diff --git a/src/librustc_codegen_ssa/interfaces/builder.rs b/src/librustc_codegen_ssa/interfaces/builder.rs index 953152534d3..38ab019343a 100644 --- a/src/librustc_codegen_ssa/interfaces/builder.rs +++ b/src/librustc_codegen_ssa/interfaces/builder.rs @@ -41,13 +41,18 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn llbb(&self) -> Self::BasicBlock; fn count_insn(&self, category: &str); - fn set_value_name(&self, value: Self::Value, name: &str); - fn position_at_end(&self, llbb: Self::BasicBlock); - fn position_at_start(&self, llbb: Self::BasicBlock); - fn ret_void(&self); - fn ret(&self, v: Self::Value); - fn br(&self, dest: Self::BasicBlock); - fn cond_br(&self, cond: Self::Value, then_llbb: Self::BasicBlock, else_llbb: Self::BasicBlock); + fn set_value_name(&mut self, value: Self::Value, name: &str); + fn position_at_end(&mut self, llbb: Self::BasicBlock); + fn position_at_start(&mut self, llbb: Self::BasicBlock); + fn ret_void(&mut self); + fn ret(&mut self, v: Self::Value); + fn br(&mut self, dest: Self::BasicBlock); + fn cond_br( + &mut self, + cond: Self::Value, + then_llbb: Self::BasicBlock, + else_llbb: Self::BasicBlock, + ); fn switch(&self, v: Self::Value, else_llbb: Self::BasicBlock, num_cases: usize) -> Self::Value; fn invoke( &self, diff --git a/src/librustc_codegen_ssa/interfaces/mod.rs b/src/librustc_codegen_ssa/interfaces/mod.rs index 0b2617072a3..1797060f6a4 100644 --- a/src/librustc_codegen_ssa/interfaces/mod.rs +++ b/src/librustc_codegen_ssa/interfaces/mod.rs @@ -8,6 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Interface of a Rust codegen backend +//! +//! This crate defines all the traits that have to be implemented by a codegen backend in order to +//! use the backend-agnostic codegen code in `rustc_codegen_ssa`. +//! +//! The interface is designed around two backend-specific data structures, the codegen context and +//! the builder. The codegen context is supposed to be read-only after its creation and during the +//! actual codegen, while the builder stores the information about the function during codegen and +//! is used to produce the instructions of the backend IR. +//! +//! Finaly, a third `Backend` structure has to implement methods related to how codegen information +//! is passed to the backend, especially for asynchronous compilation. +//! +//! The traits contain associated types that are backend-specific, such as the backend's value or +//! basic blocks. + mod abi; mod asm; mod backend; @@ -22,7 +38,7 @@ pub use self::abi::{AbiBuilderMethods, AbiMethods}; pub use self::asm::{AsmBuilderMethods, AsmMethods}; -pub use self::backend::{Backend, BackendMethods, BackendTypes}; +pub use self::backend::{Backend, BackendTypes, ExtraBackendMethods}; pub use self::builder::BuilderMethods; pub use self::consts::ConstMethods; pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods}; diff --git a/src/librustc_codegen_ssa/interfaces/type_.rs b/src/librustc_codegen_ssa/interfaces/type_.rs index 52c06618faa..290ee791a1d 100644 --- a/src/librustc_codegen_ssa/interfaces/type_.rs +++ b/src/librustc_codegen_ssa/interfaces/type_.rs @@ -16,7 +16,7 @@ use rustc::ty::layout::{self, Align, Size}; use rustc::ty::Ty; use rustc::util::nodemap::FxHashMap; - use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg}; +use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg}; use std::cell::RefCell; use syntax::ast; diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 818c96f9e91..2a42ad91e3d 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! # Note -//! -//! This API is completely unstable and subject to change. - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] @@ -28,6 +24,10 @@ #![allow(dead_code)] #![feature(quote)] +//! This crate contains codegen code that is used by all codegen backends (LLVM and others). +//! The backend-agnostic functions of this crate use functions defined in various traits that +//! have to be implemented by each backends. + #[macro_use] extern crate bitflags; #[macro_use] extern crate log; extern crate rustc_apfloat; diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 46665193ab5..6fc7a266dd4 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -111,7 +111,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( }; let funclet_br = - |this: &mut Self, bx: &Bx, target: mir::BasicBlock| { + |this: &mut Self, bx: &mut Bx, target: mir::BasicBlock| { let (lltarget, is_cleanupret) = lltarget(this, target); if is_cleanupret { // micro-optimization: generate a `ret` rather than a jump @@ -124,7 +124,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let do_call = | this: &mut Self, - bx: &Bx, + bx: &mut Bx, fn_ty: FnType<'tcx, Ty<'tcx>>, fn_ptr: Bx::Value, llargs: &[Bx::Value], @@ -200,7 +200,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( } mir::TerminatorKind::Goto { target } => { - funclet_br(self, &bx, target); + funclet_br(self, &mut bx, target); } mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => { @@ -302,7 +302,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def { // we don't actually need to drop anything. - funclet_br(self, &bx, target); + funclet_br(self, &mut bx, target); return } @@ -332,7 +332,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx.cx().fn_type_of_instance(&drop_fn)) } }; - do_call(self, &bx, fn_ty, drop_fn, args, + do_call(self, &mut bx, fn_ty, drop_fn, args, Some((ReturnDest::Nothing, target)), unwind); } @@ -356,7 +356,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Don't codegen the panic block if success if known. if const_cond == Some(expected) { - funclet_br(self, &bx, target); + funclet_br(self, &mut bx, target); return; } @@ -427,7 +427,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let llfn = bx.cx().get_fn(instance); // Codegen the actual panic invoke/call. - do_call(self, &bx, fn_ty, llfn, &args, None, cleanup); + do_call(self, &mut bx, fn_ty, llfn, &args, None, cleanup); } mir::TerminatorKind::DropAndReplace { .. } => { @@ -477,7 +477,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( if let Some(destination_ref) = destination.as_ref() { let &(ref dest, target) = destination_ref; self.codegen_transmute(&bx, &args[0], dest); - funclet_br(self, &bx, target); + funclet_br(self, &mut bx, target); } else { // If we are trying to transmute to an uninhabited type, // it is likely there is no allotted destination. In fact, @@ -504,7 +504,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( Some(ty::InstanceDef::DropGlue(_, None)) => { // empty drop glue - a nop. let &(_, target) = destination.as_ref().unwrap(); - funclet_br(self, &bx, target); + funclet_br(self, &mut bx, target); return; } _ => bx.cx().new_fn_type(sig, &extra_args) @@ -550,7 +550,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Codegen the actual panic invoke/call. do_call( self, - &bx, + &mut bx, fn_ty, llfn, &[msg_file_line_col], @@ -648,7 +648,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( } if let Some((_, target)) = *destination { - funclet_br(self, &bx, target); + funclet_br(self, &mut bx, target); } else { bx.unreachable(); } @@ -740,7 +740,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( _ => span_bug!(span, "no llfn for call"), }; - do_call(self, &bx, fn_ty, fn_ptr, &llargs, + do_call(self, &mut bx, fn_ty, fn_ptr, &llargs, destination.as_ref().map(|&(_, target)| (ret_dest, target)), cleanup); } @@ -913,7 +913,7 @@ fn landing_pad_uncached( span_bug!(self.mir.span, "landing pad was not inserted?") } - let bx = self.new_block("cleanup"); + let mut bx = self.new_block("cleanup"); let llpersonality = self.cx.eh_personality(); let llretty = self.landing_pad_type(); @@ -952,7 +952,7 @@ pub fn build_block( &self, bb: mir::BasicBlock ) -> Bx { - let bx = Bx::with_cx(self.cx); + let mut bx = Bx::with_cx(self.cx); bx.position_at_end(self.blocks[bb]); bx } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 3fdc37ee833..dcd3f828361 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -214,7 +214,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( debug!("fn_ty: {:?}", fn_ty); let debug_context = cx.create_function_debug_context(instance, sig, llfn, mir); - let bx = Bx::new_block(cx, llfn, "start"); + let mut bx = Bx::new_block(cx, llfn, "start"); if mir.basic_blocks().iter().any(|bb| bb.is_cleanup) { bx.set_personality_fn(cx.eh_personality()); @@ -235,7 +235,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Compute debuginfo scopes from MIR scopes. let scopes = cx.create_mir_scopes(mir, &debug_context); - let (landing_pads, funclets) = create_funclets(mir, &bx, &cleanup_kinds, &block_bxs); + let (landing_pads, funclets) = create_funclets(mir, &mut bx, &cleanup_kinds, &block_bxs); let mut fx = FunctionCx { instance, @@ -262,7 +262,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Allocate variable and temp allocas fx.locals = { - let args = arg_local_refs(&bx, &fx, &fx.scopes, &memory_locals); + let args = arg_local_refs(&mut bx, &fx, &fx.scopes, &memory_locals); let allocate_local = |local| { let decl = &mir.local_decls[local]; @@ -363,7 +363,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( mir: &'a Mir<'tcx>, - bx: &Bx, + bx: &mut Bx, cleanup_kinds: &IndexVec, block_bxs: &IndexVec) -> (IndexVec>, @@ -400,7 +400,7 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // } Some(&mir::TerminatorKind::Abort) => { let cs_bx = bx.build_sibling_block(&format!("cs_funclet{:?}", bb)); - let cp_bx = bx.build_sibling_block(&format!("cp_funclet{:?}", bb)); + let mut cp_bx = bx.build_sibling_block(&format!("cp_funclet{:?}", bb)); ret_llbb = cs_bx.llbb(); let cs = cs_bx.catch_switch(None, None, 1); @@ -416,7 +416,7 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( cp_bx.br(llbb); } _ => { - let cleanup_bx = bx.build_sibling_block(&format!("funclet_{:?}", bb)); + let mut cleanup_bx = bx.build_sibling_block(&format!("funclet_{:?}", bb)); ret_llbb = cleanup_bx.llbb(); funclet = cleanup_bx.cleanup_pad(None, &[]); cleanup_bx.br(llbb); @@ -431,7 +431,7 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( /// argument's value. As arguments are places, these are always /// indirect. fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( - bx: &Bx, + bx: &mut Bx, fx: &FunctionCx<'a, 'tcx, Bx>, scopes: &IndexVec< mir::SourceScope, @@ -440,7 +440,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( memory_locals: &BitSet, ) -> Vec> { let mir = fx.mir; - let tcx = bx.tcx(); + let tcx = fx.cx.tcx(); let mut idx = 0; let mut llarg_idx = fx.fn_ty.ret.is_indirect() as usize; diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 69c53879354..2efc5af1fc6 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -31,7 +31,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_rvalue( &mut self, - bx: Bx, + mut bx: Bx, dest: PlaceRef<'tcx, Bx::Value>, rvalue: &mir::Rvalue<'tcx> ) -> Bx { @@ -121,8 +121,8 @@ pub fn codegen_rvalue( let count = bx.cx().const_usize(count); let end = dest.project_index(&bx, count).llval; - let header_bx = bx.build_sibling_block("repeat_loop_header"); - let body_bx = bx.build_sibling_block("repeat_loop_body"); + let mut header_bx = bx.build_sibling_block("repeat_loop_header"); + let mut body_bx = bx.build_sibling_block("repeat_loop_body"); let next_bx = bx.build_sibling_block("repeat_loop_next"); bx.br(header_bx.llbb());