Skip to content

Commit

Permalink
debuginfo: Implement direct debuginfo source location application for…
Browse files Browse the repository at this point in the history
… ICmp, FCmp, and CallWithConv.
  • Loading branch information
michaelwoerister committed Feb 6, 2015
1 parent d98d508 commit 0eec226
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 45 deletions.
27 changes: 19 additions & 8 deletions src/librustc_trans/trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,

let _icx = push_ctxt("compare_values");
if ty::type_is_scalar(rhs_t) {
let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq);
let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq, debug_loc);
return Result::new(rs.bcx, rs.val);
}

Expand Down Expand Up @@ -1149,17 +1149,28 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
RangeResult(Result { val: vbegin, .. },
Result { bcx, val: vend }) => {
let Result { bcx, val: llge } =
compare_scalar_types(
bcx, test_val,
vbegin, t, ast::BiGe);
compare_scalar_types(bcx,
test_val,
vbegin,
t,
ast::BiGe,
debug_loc);
let Result { bcx, val: llle } =
compare_scalar_types(
bcx, test_val, vend,
t, ast::BiLe);
compare_scalar_types(bcx,
test_val,
vend,
t,
ast::BiLe,
debug_loc);
Result::new(bcx, And(bcx, llge, llle, debug_loc))
}
LowerBound(Result { bcx, val }) => {
compare_scalar_types(bcx, test_val, val, t, ast::BiGe)
compare_scalar_types(bcx,
test_val,
val,
t,
ast::BiGe,
debug_loc)
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ pub fn trans_get_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
RawNullablePointer { nndiscr, nnty, .. } => {
let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
let llptrty = type_of::sizing_type_of(bcx.ccx(), nnty);
val = ICmp(bcx, cmp, Load(bcx, scrutinee), C_null(llptrty));
val = ICmp(bcx, cmp, Load(bcx, scrutinee), C_null(llptrty), DebugLoc::None);
signed = false;
}
StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
Expand All @@ -770,7 +770,7 @@ fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, discrfield: &Disc
let llptrptr = GEPi(bcx, scrutinee, &discrfield[]);
let llptr = Load(bcx, llptrptr);
let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)))
ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)), DebugLoc::None)
}

/// Helper for cases where the discriminant is simply loaded.
Expand Down
35 changes: 20 additions & 15 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ use trans::consts;
use trans::context::SharedCrateContext;
use trans::controlflow;
use trans::datum;
use trans::debuginfo::{self, DebugLoc};
use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
use trans::expr;
use trans::foreign;
use trans::glue;
Expand Down Expand Up @@ -540,9 +540,10 @@ pub fn compare_scalar_types<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
t: Ty<'tcx>,
op: ast::BinOp_)
op: ast::BinOp_,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
let f = |a| Result::new(cx, compare_scalar_values(cx, lhs, rhs, a, op));
let f = |a| Result::new(cx, compare_scalar_values(cx, lhs, rhs, a, op, debug_loc));

match t.sty {
ty::ty_tup(ref tys) if tys.is_empty() => f(nil_type),
Expand All @@ -561,7 +562,8 @@ pub fn compare_scalar_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
nt: scalar_type,
op: ast::BinOp_)
op: ast::BinOp_,
debug_loc: DebugLoc)
-> ValueRef {
let _icx = push_ctxt("compare_scalar_values");
fn die(cx: Block) -> ! {
Expand All @@ -588,7 +590,7 @@ pub fn compare_scalar_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
ast::BiGe => llvm::RealOGE,
_ => die(cx)
};
return FCmp(cx, cmp, lhs, rhs);
return FCmp(cx, cmp, lhs, rhs, debug_loc);
}
signed_int => {
let cmp = match op {
Expand All @@ -600,7 +602,7 @@ pub fn compare_scalar_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
ast::BiGe => llvm::IntSGE,
_ => die(cx)
};
return ICmp(cx, cmp, lhs, rhs);
return ICmp(cx, cmp, lhs, rhs, debug_loc);
}
unsigned_int => {
let cmp = match op {
Expand All @@ -612,7 +614,7 @@ pub fn compare_scalar_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
ast::BiGe => llvm::IntUGE,
_ => die(cx)
};
return ICmp(cx, cmp, lhs, rhs);
return ICmp(cx, cmp, lhs, rhs, debug_loc);
}
}
}
Expand All @@ -623,7 +625,8 @@ pub fn compare_simd_types<'blk, 'tcx>(
rhs: ValueRef,
t: Ty<'tcx>,
size: uint,
op: ast::BinOp)
op: ast::BinOp_,
debug_loc: DebugLoc)
-> ValueRef {
let cmp = match t.sty {
ty::ty_float(_) => {
Expand All @@ -634,7 +637,7 @@ pub fn compare_simd_types<'blk, 'tcx>(
cx.sess().bug("compare_simd_types: comparison operators \
not supported for floating point SIMD types")
},
ty::ty_uint(_) => match op.node {
ty::ty_uint(_) => match op {
ast::BiEq => llvm::IntEQ,
ast::BiNe => llvm::IntNE,
ast::BiLt => llvm::IntULT,
Expand All @@ -643,7 +646,7 @@ pub fn compare_simd_types<'blk, 'tcx>(
ast::BiGe => llvm::IntUGE,
_ => cx.sess().bug("compare_simd_types: must be a comparison operator"),
},
ty::ty_int(_) => match op.node {
ty::ty_int(_) => match op {
ast::BiEq => llvm::IntEQ,
ast::BiNe => llvm::IntNE,
ast::BiLt => llvm::IntSLT,
Expand All @@ -659,7 +662,7 @@ pub fn compare_simd_types<'blk, 'tcx>(
// to get the correctly sized type. This will compile to a single instruction
// once the IR is converted to assembly if the SIMD instruction is supported
// by the target architecture.
SExt(cx, ICmp(cx, cmp, lhs, rhs), return_ty)
SExt(cx, ICmp(cx, cmp, lhs, rhs, debug_loc), return_ty)
}

// Iterates through the elements of a structural type.
Expand Down Expand Up @@ -866,14 +869,16 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
("attempted remainder with a divisor of zero",
"attempted remainder with overflow")
};
let debug_loc = call_info.debug_loc();

let (is_zero, is_signed) = match rhs_t.sty {
ty::ty_int(t) => {
let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
(ICmp(cx, llvm::IntEQ, rhs, zero), true)
(ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), true)
}
ty::ty_uint(t) => {
let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
(ICmp(cx, llvm::IntEQ, rhs, zero), false)
(ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false)
}
_ => {
cx.sess().bug(&format!("fail-if-zero on unexpected type: {}",
Expand Down Expand Up @@ -910,10 +915,10 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
_ => unreachable!(),
};
let minus_one = ICmp(bcx, llvm::IntEQ, rhs,
C_integral(llty, -1, false));
C_integral(llty, -1, false), debug_loc);
with_cond(bcx, minus_one, |bcx| {
let is_min = ICmp(bcx, llvm::IntEQ, lhs,
C_integral(llty, min, true));
C_integral(llty, min, true), debug_loc);
with_cond(bcx, is_min, |bcx| {
controlflow::trans_fail(bcx,
call_info,
Expand Down
32 changes: 25 additions & 7 deletions src/librustc_trans/trans/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,22 +856,32 @@ pub fn FPCast(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {


/* Comparisons */
pub fn ICmp(cx: Block, op: IntPredicate, lhs: ValueRef, rhs: ValueRef)
-> ValueRef {
pub fn ICmp(cx: Block,
op: IntPredicate,
lhs: ValueRef,
rhs: ValueRef,
debug_loc: DebugLoc)
-> ValueRef {
unsafe {
if cx.unreachable.get() {
return llvm::LLVMGetUndef(Type::i1(cx.ccx()).to_ref());
}
debug_loc.apply(cx.fcx);
B(cx).icmp(op, lhs, rhs)
}
}

pub fn FCmp(cx: Block, op: RealPredicate, lhs: ValueRef, rhs: ValueRef)
-> ValueRef {
pub fn FCmp(cx: Block,
op: RealPredicate,
lhs: ValueRef,
rhs: ValueRef,
debug_loc: DebugLoc)
-> ValueRef {
unsafe {
if cx.unreachable.get() {
return llvm::LLVMGetUndef(Type::i1(cx.ccx()).to_ref());
}
debug_loc.apply(cx.fcx);
B(cx).fcmp(op, lhs, rhs)
}
}
Expand Down Expand Up @@ -941,9 +951,17 @@ pub fn Call(cx: Block,
B(cx).call(fn_, args, attributes)
}

pub fn CallWithConv(cx: Block, fn_: ValueRef, args: &[ValueRef], conv: CallConv,
attributes: Option<AttrBuilder>) -> ValueRef {
if cx.unreachable.get() { return _UndefReturn(cx, fn_); }
pub fn CallWithConv(cx: Block,
fn_: ValueRef,
args: &[ValueRef],
conv: CallConv,
attributes: Option<AttrBuilder>,
debug_loc: DebugLoc)
-> ValueRef {
if cx.unreachable.get() {
return _UndefReturn(cx, fn_);
}
debug_loc.apply(cx.fcx);
B(cx).call_with_conv(fn_, args, conv, attributes)
}

Expand Down
10 changes: 7 additions & 3 deletions src/librustc_trans/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,9 +827,13 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
abi);
fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean();

bcx = foreign::trans_native_call(bcx, callee_ty,
llfn, opt_llretslot.unwrap(),
&llargs[], arg_tys);
bcx = foreign::trans_native_call(bcx,
callee_ty,
llfn,
opt_llretslot.unwrap(),
&llargs[],
arg_tys,
debug_loc);
}

fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_cleanup_scope);
Expand Down
26 changes: 22 additions & 4 deletions src/librustc_trans/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let ccx = bcx.ccx();
let mut bcx = bcx;

let index_expr_debug_loc = index_expr.debug_loc();

// Check for overloaded index.
let method_ty = ccx.tcx()
.method_map
Expand Down Expand Up @@ -778,13 +780,17 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
debug!("trans_index: base {}", bcx.val_to_string(base));
debug!("trans_index: len {}", bcx.val_to_string(len));

let bounds_check = ICmp(bcx, llvm::IntUGE, ix_val, len);
let bounds_check = ICmp(bcx,
llvm::IntUGE,
ix_val,
len,
index_expr_debug_loc);
let expect = ccx.get_intrinsic(&("llvm.expect.i1"));
let expected = Call(bcx,
expect,
&[bounds_check, C_bool(ccx, false)],
None,
index_expr.debug_loc());
index_expr_debug_loc);
bcx = with_cond(bcx, expected, |bcx| {
controlflow::trans_fail_bounds_check(bcx,
expr_info(index_expr),
Expand Down Expand Up @@ -1744,9 +1750,21 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiGe | ast::BiLe | ast::BiGt => {
if ty::type_is_scalar(rhs_t) {
unpack_result!(bcx, base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op.node))
unpack_result!(bcx,
base::compare_scalar_types(bcx,
lhs,
rhs,
rhs_t,
op.node,
binop_debug_loc))
} else if is_simd {
base::compare_simd_types(bcx, lhs, rhs, intype, ty::simd_size(tcx, lhs_t), op)
base::compare_simd_types(bcx,
lhs,
rhs,
intype,
ty::simd_size(tcx, lhs_t),
op.node,
binop_debug_loc)
} else {
bcx.tcx().sess.span_bug(binop_expr.span, "comparison operator unsupported for type")
}
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_trans/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use trans::base;
use trans::build::*;
use trans::cabi;
use trans::common::*;
use trans::debuginfo::DebugLoc;
use trans::machine;
use trans::monomorphize;
use trans::type_::Type;
Expand Down Expand Up @@ -218,7 +219,8 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
llfn: ValueRef,
llretptr: ValueRef,
llargs_rust: &[ValueRef],
passed_arg_tys: Vec<Ty<'tcx>>)
passed_arg_tys: Vec<Ty<'tcx>>,
call_debug_loc: DebugLoc)
-> Block<'blk, 'tcx>
{
let ccx = bcx.ccx();
Expand Down Expand Up @@ -370,7 +372,8 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
llfn,
&llargs_foreign[],
cc,
Some(attrs));
Some(attrs),
call_debug_loc);

// If the function we just called does not use an outpointer,
// store the result into the rust outpointer. Cast the outpointer
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_trans/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,11 @@ fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, info:
// Return the sum of sizes and max of aligns.
let size = Add(bcx, sized_size, unsized_size, DebugLoc::None);
let align = Select(bcx,
ICmp(bcx, llvm::IntULT, sized_align, unsized_align),
ICmp(bcx,
llvm::IntULT,
sized_align,
unsized_align,
DebugLoc::None),
sized_align,
unsized_align);
(size, align)
Expand Down
10 changes: 7 additions & 3 deletions src/librustc_trans/trans/tvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let unit_size = llsize_of_alloc(ccx, llty);
if unit_size != 0 {
let len = get_len(bcx, vptr);
let not_empty = ICmp(bcx, llvm::IntNE, len, C_uint(ccx, 0us));
let not_empty = ICmp(bcx,
llvm::IntNE,
len,
C_uint(ccx, 0us),
DebugLoc::None);
with_cond(bcx, not_empty, |bcx| {
let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty));
let size = Mul(bcx, C_uint(ccx, unit_size), len, DebugLoc::None);
Expand Down Expand Up @@ -443,7 +447,7 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
{ // i < count
let lhs = Load(cond_bcx, loop_counter);
let rhs = count;
let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs);
let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs, DebugLoc::None);

CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
}
Expand Down Expand Up @@ -497,7 +501,7 @@ pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
let data_ptr =
Phi(header_bcx, val_ty(data_ptr), &[data_ptr], &[bcx.llbb]);
let not_yet_at_end =
ICmp(header_bcx, llvm::IntULT, data_ptr, data_end_ptr);
ICmp(header_bcx, llvm::IntULT, data_ptr, data_end_ptr, DebugLoc::None);
let body_bcx = fcx.new_temp_block("iter_vec_loop_body");
let next_bcx = fcx.new_temp_block("iter_vec_next");
CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
Expand Down

0 comments on commit 0eec226

Please sign in to comment.