diff options
| author | bors <bors@rust-lang.org> | 2020-08-30 15:57:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-08-30 15:57:57 +0000 |
| commit | 85fbf49ce0e2274d0acf798f6e703747674feec3 (patch) | |
| tree | 158a05eb3f204a8e72939b58427d0c2787a4eade /compiler/rustc_codegen_llvm/src/declare.rs | |
| parent | db534b3ac286cf45688c3bbae6aa6e77439e52d2 (diff) | |
| parent | 9e5f7d5631b8f4009ac1c693e585d4b7108d4275 (diff) | |
| download | rust-85fbf49ce0e2274d0acf798f6e703747674feec3.tar.gz rust-85fbf49ce0e2274d0acf798f6e703747674feec3.zip | |
Auto merge of #74862 - mark-i-m:mv-compiler, r=petrochenkov
Move almost all compiler crates to compiler/ This PR implements https://github.com/rust-lang/compiler-team/issues/336 and moves all `rustc_*` crates from `src` to the new `compiler` directory. `librustc_foo` directories are renamed to `rustc_foo`. `src` directories are introduced inside `rustc_*` directories to mirror the scheme already use for `library` crates.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/declare.rs')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/declare.rs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs new file mode 100644 index 00000000000..ec42bd4a039 --- /dev/null +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -0,0 +1,95 @@ +//! Declare various LLVM values. +//! +//! Prefer using functions and methods from this module rather than calling LLVM +//! functions directly. These functions do some additional work to ensure we do +//! the right thing given the preconceptions of codegen. +//! +//! Some useful guidelines: +//! +//! * Use declare_* family of methods if you are declaring, but are not +//! interested in defining the Value they return. +//! * Use define_* family of methods when you might be defining the Value. +//! * When in doubt, define. + +use crate::abi::{FnAbi, FnAbiLlvmExt}; +use crate::attributes; +use crate::context::CodegenCx; +use crate::llvm; +use crate::llvm::AttributePlace::Function; +use crate::type_::Type; +use crate::value::Value; +use rustc_codegen_ssa::traits::*; +use rustc_middle::ty::Ty; +use tracing::debug; + +/// Declare a function. +/// +/// If there’s a value with the same name already declared, the function will +/// update the declaration and return existing Value instead. +fn declare_raw_fn( + cx: &CodegenCx<'ll, '_>, + name: &str, + callconv: llvm::CallConv, + ty: &'ll Type, +) -> &'ll Value { + debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); + let llfn = unsafe { + llvm::LLVMRustGetOrInsertFunction(cx.llmod, name.as_ptr().cast(), name.len(), ty) + }; + + llvm::SetFunctionCallConv(llfn, callconv); + // Function addresses in Rust are never significant, allowing functions to + // be merged. + llvm::SetUnnamedAddress(llfn, llvm::UnnamedAddr::Global); + + if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.target.options.disable_redzone) { + llvm::Attribute::NoRedZone.apply_llfn(Function, llfn); + } + + attributes::default_optimisation_attrs(cx.tcx.sess, llfn); + attributes::non_lazy_bind(cx.sess(), llfn); + llfn +} + +impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { + fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value { + debug!("declare_global(name={:?})", name); + unsafe { llvm::LLVMRustGetOrInsertGlobal(self.llmod, name.as_ptr().cast(), name.len(), ty) } + } + + fn declare_cfn(&self, name: &str, fn_type: &'ll Type) -> &'ll Value { + declare_raw_fn(self, name, llvm::CCallConv, fn_type) + } + + fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value { + debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi); + + let llfn = declare_raw_fn(self, name, fn_abi.llvm_cconv(), fn_abi.llvm_type(self)); + fn_abi.apply_attrs_llfn(self, llfn); + llfn + } + + fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> { + if self.get_defined_value(name).is_some() { + None + } else { + Some(self.declare_global(name, ty)) + } + } + + fn define_private_global(&self, ty: &'ll Type) -> &'ll Value { + unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) } + } + + fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { + debug!("get_declared_value(name={:?})", name); + unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_ptr().cast(), name.len()) } + } + + fn get_defined_value(&self, name: &str) -> Option<&'ll Value> { + self.get_declared_value(name).and_then(|val| { + let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 }; + if !declaration { Some(val) } else { None } + }) + } +} |
