Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_codegen_llvm: begin generalizing over backend values. #52987

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/librustc_codegen_llvm/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,13 @@ impl LlvmType for CastTarget {

pub trait ArgTypeExt<'ll, 'tcx> {
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>);
fn store_fn_arg(&self, bx: &Builder<'_, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>);
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'tcx, &'ll Value>);
fn store_fn_arg(
&self,
bx: &Builder<'_, 'll, 'tcx>,
idx: &mut usize,
dst: PlaceRef<'tcx, &'ll Value>,
);
}

impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
Expand All @@ -182,7 +187,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
/// place for the original Rust type of this argument/return.
/// Can be used for both storing formal arguments into Rust variables
/// or results of call/invoke instructions into their destinations.
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>) {
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'tcx, &'ll Value>) {
if self.is_ignore() {
return;
}
Expand Down Expand Up @@ -235,7 +240,12 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
}
}

fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>) {
fn store_fn_arg(
&self,
bx: &Builder<'a, 'll, 'tcx>,
idx: &mut usize,
dst: PlaceRef<'tcx, &'ll Value>,
) {
let mut next = || {
let val = llvm::get_param(bx.llfn(), *idx as c_uint);
*idx += 1;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use libc::{c_uint, c_char};
pub fn codegen_inline_asm(
bx: &Builder<'a, 'll, 'tcx>,
ia: &hir::InlineAsm,
outputs: Vec<PlaceRef<'ll, 'tcx>>,
outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
mut inputs: Vec<&'ll Value>
) {
let mut ext_constraints = vec![];
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_codegen_llvm/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ pub fn unsize_thin_ptr(
/// to a value of type `dst_ty` and store the result in `dst`
pub fn coerce_unsized_into(
bx: &Builder<'a, 'll, 'tcx>,
src: PlaceRef<'ll, 'tcx>,
dst: PlaceRef<'ll, 'tcx>
src: PlaceRef<'tcx, &'ll Value>,
dst: PlaceRef<'tcx, &'ll Value>
) {
let src_ty = src.layout.ty;
let dst_ty = dst.layout.ty;
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_codegen_llvm/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub fn codegen_intrinsic_call(
bx: &Builder<'a, 'll, 'tcx>,
callee_ty: Ty<'tcx>,
fn_ty: &FnType<'tcx, Ty<'tcx>>,
args: &[OperandRef<'ll, 'tcx>],
args: &[OperandRef<'tcx, &'ll Value>],
llresult: &'ll Value,
span: Span,
) {
Expand Down Expand Up @@ -592,7 +592,7 @@ pub fn codegen_intrinsic_call(
fn modify_as_needed(
bx: &Builder<'a, 'll, 'tcx>,
t: &intrinsics::Type,
arg: &OperandRef<'ll, 'tcx>,
arg: &OperandRef<'tcx, &'ll Value>,
) -> Vec<&'ll Value> {
match *t {
intrinsics::Type::Aggregate(true, ref contents) => {
Expand Down Expand Up @@ -985,7 +985,7 @@ fn generic_simd_intrinsic(
bx: &Builder<'a, 'll, 'tcx>,
name: &str,
callee_ty: Ty<'tcx>,
args: &[OperandRef<'ll, 'tcx>],
args: &[OperandRef<'tcx, &'ll Value>],
ret_ty: Ty<'tcx>,
llret_ty: &'ll Type,
span: Span
Expand Down Expand Up @@ -1166,7 +1166,7 @@ fn generic_simd_intrinsic(
in_len: usize,
bx: &Builder<'a, 'll, 'tcx>,
span: Span,
args: &[OperandRef<'ll, 'tcx>],
args: &[OperandRef<'tcx, &'ll Value>],
) -> Result<&'ll Value, ()> {
macro_rules! emit_error {
($msg: tt) => {
Expand Down
18 changes: 9 additions & 9 deletions src/librustc_codegen_llvm/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
fn_ty: FnType<'tcx, Ty<'tcx>>,
fn_ptr: &'ll Value,
llargs: &[&'ll Value],
destination: Option<(ReturnDest<'ll, 'tcx>, mir::BasicBlock)>,
destination: Option<(ReturnDest<'tcx, &'ll Value>, mir::BasicBlock)>,
cleanup: Option<mir::BasicBlock>
| {
if let Some(cleanup) = cleanup {
Expand Down Expand Up @@ -636,7 +636,7 @@ impl FunctionCx<'a, 'll, 'tcx> {

fn codegen_argument(&mut self,
bx: &Builder<'a, 'll, 'tcx>,
op: OperandRef<'ll, 'tcx>,
op: OperandRef<'tcx, &'ll Value>,
llargs: &mut Vec<&'ll Value>,
arg: &ArgType<'tcx, Ty<'tcx>>) {
// Fill padding with undef value, where applicable.
Expand Down Expand Up @@ -736,7 +736,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
}
}

fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'ll, 'tcx> {
fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'tcx, &'ll Value> {
let cx = bx.cx;
if let Some(slot) = self.personality_slot {
slot
Expand Down Expand Up @@ -812,7 +812,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
fn make_return_dest(&mut self, bx: &Builder<'a, 'll, 'tcx>,
dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>,
llargs: &mut Vec<&'ll Value>, is_intrinsic: bool)
-> ReturnDest<'ll, 'tcx> {
-> ReturnDest<'tcx, &'ll Value> {
// If the return is ignored, we can just return a do-nothing ReturnDest
if fn_ret.is_ignore() {
return ReturnDest::Nothing;
Expand Down Expand Up @@ -894,7 +894,7 @@ impl FunctionCx<'a, 'll, 'tcx> {

fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'll, 'tcx>,
src: &mir::Operand<'tcx>,
dst: PlaceRef<'ll, 'tcx>) {
dst: PlaceRef<'tcx, &'ll Value>) {
let src = self.codegen_operand(bx, src);
let llty = src.layout.llvm_type(bx.cx);
let cast_ptr = bx.pointercast(dst.llval, llty.ptr_to());
Expand All @@ -906,7 +906,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
// Stores the return value of a function call into it's final location.
fn store_return(&mut self,
bx: &Builder<'a, 'll, 'tcx>,
dest: ReturnDest<'ll, 'tcx>,
dest: ReturnDest<'tcx, &'ll Value>,
ret_ty: &ArgType<'tcx, Ty<'tcx>>,
llval: &'ll Value) {
use self::ReturnDest::*;
Expand Down Expand Up @@ -937,13 +937,13 @@ impl FunctionCx<'a, 'll, 'tcx> {
}
}

enum ReturnDest<'ll, 'tcx> {
enum ReturnDest<'tcx, V> {
// Do nothing, the return value is indirect or ignored
Nothing,
// Store the return value to the pointer
Store(PlaceRef<'ll, 'tcx>),
Store(PlaceRef<'tcx, V>),
// Stores an indirect return value to an operand local place
IndirectOperand(PlaceRef<'ll, 'tcx>, mir::Local),
IndirectOperand(PlaceRef<'tcx, V>, mir::Local),
// Stores a direct return value to an operand local place
DirectOperand(mir::Local)
}
19 changes: 11 additions & 8 deletions src/librustc_codegen_llvm/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
/// don't really care about it very much. Anyway, this value
/// contains an alloca into which the personality is stored and
/// then later loaded when generating the DIVERGE_BLOCK.
personality_slot: Option<PlaceRef<'ll, 'tcx>>,
personality_slot: Option<PlaceRef<'tcx, &'ll Value>>,

/// A `Block` for each MIR `BasicBlock`
blocks: IndexVec<mir::BasicBlock, &'ll BasicBlock>,
Expand Down Expand Up @@ -97,7 +97,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
///
/// Avoiding allocs can also be important for certain intrinsics,
/// notably `expect`.
locals: IndexVec<mir::Local, LocalRef<'ll, 'tcx>>,
locals: IndexVec<mir::Local, LocalRef<'tcx, &'ll Value>>,

/// Debug information for MIR scopes.
scopes: IndexVec<mir::SourceScope, debuginfo::MirDebugScope<'ll>>,
Expand Down Expand Up @@ -178,13 +178,16 @@ impl FunctionCx<'a, 'll, 'tcx> {
}
}

enum LocalRef<'ll, 'tcx> {
Place(PlaceRef<'ll, 'tcx>),
Operand(Option<OperandRef<'ll, 'tcx>>),
enum LocalRef<'tcx, V> {
Place(PlaceRef<'tcx, V>),
Operand(Option<OperandRef<'tcx, V>>),
}

impl LocalRef<'ll, 'tcx> {
fn new_operand(cx: &CodegenCx<'ll, 'tcx>, layout: TyLayout<'tcx>) -> LocalRef<'ll, 'tcx> {
impl LocalRef<'tcx, &'ll Value> {
fn new_operand(
cx: &CodegenCx<'ll, 'tcx>,
layout: TyLayout<'tcx>,
) -> LocalRef<'tcx, &'ll Value> {
if layout.is_zst() {
// Zero-size temporaries aren't always initialized, which
// doesn't matter because they don't contain data, but
Expand Down Expand Up @@ -418,7 +421,7 @@ fn arg_local_refs(
fx: &FunctionCx<'a, 'll, 'tcx>,
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope<'ll>>,
memory_locals: &BitArray<mir::Local>,
) -> Vec<LocalRef<'ll, 'tcx>> {
) -> Vec<LocalRef<'tcx, &'ll Value>> {
let mir = fx.mir;
let tcx = bx.tcx();
let mut idx = 0;
Expand Down
53 changes: 31 additions & 22 deletions src/librustc_codegen_llvm/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ use super::place::PlaceRef;
/// uniquely determined by the value's type, but is kept as a
/// safety check.
#[derive(Copy, Clone, Debug)]
pub enum OperandValue<'ll> {
pub enum OperandValue<V> {
/// A reference to the actual operand. The data is guaranteed
/// to be valid for the operand's lifetime.
Ref(&'ll Value, Align),
Ref(V, Align),
/// A single LLVM value.
Immediate(&'ll Value),
Immediate(V),
/// A pair of immediate LLVM values. Used by fat pointers too.
Pair(&'ll Value, &'ll Value)
Pair(V, V)
}

/// An `OperandRef` is an "SSA" reference to a Rust value, along with
Expand All @@ -51,23 +51,23 @@ pub enum OperandValue<'ll> {
/// directly is sure to cause problems -- use `OperandRef::store`
/// instead.
#[derive(Copy, Clone)]
pub struct OperandRef<'ll, 'tcx> {
pub struct OperandRef<'tcx, V> {
// The value.
pub val: OperandValue<'ll>,
pub val: OperandValue<V>,

// The layout of value, based on its Rust type.
pub layout: TyLayout<'tcx>,
}

impl fmt::Debug for OperandRef<'ll, 'tcx> {
impl fmt::Debug for OperandRef<'tcx, &'ll Value> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "OperandRef({:?} @ {:?})", self.val, self.layout)
}
}

impl OperandRef<'ll, 'tcx> {
impl OperandRef<'tcx, &'ll Value> {
pub fn new_zst(cx: &CodegenCx<'ll, 'tcx>,
layout: TyLayout<'tcx>) -> OperandRef<'ll, 'tcx> {
layout: TyLayout<'tcx>) -> OperandRef<'tcx, &'ll Value> {
assert!(layout.is_zst());
OperandRef {
val: OperandValue::Immediate(C_undef(layout.immediate_llvm_type(cx))),
Expand All @@ -77,7 +77,7 @@ impl OperandRef<'ll, 'tcx> {

pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
val: &'tcx ty::Const<'tcx>)
-> Result<OperandRef<'ll, 'tcx>, Lrc<ConstEvalErr<'tcx>>> {
-> Result<OperandRef<'tcx, &'ll Value>, Lrc<ConstEvalErr<'tcx>>> {
let layout = bx.cx.layout_of(val.ty);

if layout.is_zst() {
Expand Down Expand Up @@ -138,7 +138,7 @@ impl OperandRef<'ll, 'tcx> {
}
}

pub fn deref(self, cx: &CodegenCx<'ll, 'tcx>) -> PlaceRef<'ll, 'tcx> {
pub fn deref(self, cx: &CodegenCx<'ll, 'tcx>) -> PlaceRef<'tcx, &'ll Value> {
let projected_ty = self.layout.ty.builtin_deref(true)
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty;
let (llptr, llextra) = match self.val {
Expand Down Expand Up @@ -176,7 +176,7 @@ impl OperandRef<'ll, 'tcx> {
pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'll, 'tcx>,
llval: &'ll Value,
layout: TyLayout<'tcx>)
-> OperandRef<'ll, 'tcx> {
-> OperandRef<'tcx, &'ll Value> {
let val = if let layout::Abi::ScalarPair(ref a, ref b) = layout.abi {
debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}",
llval, layout);
Expand All @@ -191,7 +191,11 @@ impl OperandRef<'ll, 'tcx> {
OperandRef { val, layout }
}

pub fn extract_field(&self, bx: &Builder<'a, 'll, 'tcx>, i: usize) -> OperandRef<'ll, 'tcx> {
pub fn extract_field(
&self,
bx: &Builder<'a, 'll, 'tcx>,
i: usize,
) -> OperandRef<'tcx, &'ll Value> {
let field = self.layout.field(bx.cx, i);
let offset = self.layout.fields.offset(i);

Expand Down Expand Up @@ -249,27 +253,32 @@ impl OperandRef<'ll, 'tcx> {
}
}

impl OperandValue<'ll> {
pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) {
impl OperandValue<&'ll Value> {
pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>) {
self.store_with_flags(bx, dest, MemFlags::empty());
}

pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) {
pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>) {
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
}

pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) {
pub fn unaligned_volatile_store(
self,
bx: &Builder<'a, 'll, 'tcx>,
dest: PlaceRef<'tcx,
&'ll Value>,
) {
self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED);
}

pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) {
pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>) {
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
}

fn store_with_flags(
self,
bx: &Builder<'a, 'll, 'tcx>,
dest: PlaceRef<'ll, 'tcx>,
dest: PlaceRef<'tcx, &'ll Value>,
flags: MemFlags,
) {
debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
Expand Down Expand Up @@ -302,7 +311,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
fn maybe_codegen_consume_direct(&mut self,
bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>)
-> Option<OperandRef<'ll, 'tcx>>
-> Option<OperandRef<'tcx, &'ll Value>>
{
debug!("maybe_codegen_consume_direct(place={:?})", place);

Expand Down Expand Up @@ -350,7 +359,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_consume(&mut self,
bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>)
-> OperandRef<'ll, 'tcx>
-> OperandRef<'tcx, &'ll Value>
{
debug!("codegen_consume(place={:?})", place);

Expand All @@ -374,7 +383,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_operand(&mut self,
bx: &Builder<'a, 'll, 'tcx>,
operand: &mir::Operand<'tcx>)
-> OperandRef<'ll, 'tcx>
-> OperandRef<'tcx, &'ll Value>
{
debug!("codegen_operand(operand={:?})", operand);

Expand Down
Loading