Skip to content

Commit a55ef3a

Browse files
debuginfo: Make debuginfo source location assignment more stable (Pt. 1)
So far, the source location an LLVM instruction was linked to was controlled by `debuginfo::set_source_location()` and `debuginfo::clear_source_location()`. This interface mimicked how LLVM's `IRBuilder` handles debug location assignment. While this interface has some theoretical performance benefits, it also makes things terribly unstable: One sets some quasi-global state and then hopes that it is still correct when a given instruction is emitted---an assumption that has been proven to not hold a bit too often. This patch requires the debug source location to be passed to the actual instruction emitting function. This makes source location assignment explicit and will prevent future changes to `trans` from accidentally breaking things in the majority of cases. This patch does not yet implement the new principle for all instruction kinds but the stepping experience should have improved significantly nonetheless already.
1 parent 51e28dd commit a55ef3a

File tree

14 files changed

+889
-405
lines changed

14 files changed

+889
-405
lines changed

src/librustc_trans/trans/_match.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,10 @@ use trans::cleanup::{self, CleanupMethods};
208208
use trans::common::*;
209209
use trans::consts;
210210
use trans::datum::*;
211+
use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
211212
use trans::expr::{self, Dest};
212213
use trans::tvec;
213214
use trans::type_of;
214-
use trans::debuginfo;
215215
use middle::ty::{self, Ty};
216216
use session::config::FullDebugInfo;
217217
use util::common::indenter;
@@ -632,7 +632,7 @@ fn bind_subslice_pat(bcx: Block,
632632

633633
let slice_begin = InBoundsGEP(bcx, base, &[C_uint(bcx.ccx(), offset_left)]);
634634
let slice_len_offset = C_uint(bcx.ccx(), offset_left + offset_right);
635-
let slice_len = Sub(bcx, len, slice_len_offset);
635+
let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None);
636636
let slice_ty = ty::mk_slice(bcx.tcx(),
637637
bcx.tcx().mk_region(ty::ReStatic),
638638
ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable});
@@ -656,7 +656,7 @@ fn extract_vec_elems<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
656656
elems.extend(range(0, before).map(|i| GEPi(bcx, base, &[i])));
657657
elems.extend(range(0, after).rev().map(|i| {
658658
InBoundsGEP(bcx, base, &[
659-
Sub(bcx, len, C_uint(bcx.ccx(), i + 1))
659+
Sub(bcx, len, C_uint(bcx.ccx(), i + 1), DebugLoc::None)
660660
])
661661
}));
662662
ExtractedBlock { vals: elems, bcx: bcx }
@@ -731,7 +731,7 @@ impl FailureHandler {
731731
Infallible =>
732732
panic!("attempted to panic in a non-panicking panic handler!"),
733733
JumpToBasicBlock(basic_block) =>
734-
Br(bcx, basic_block),
734+
Br(bcx, basic_block, DebugLoc::None),
735735
Unreachable =>
736736
build::Unreachable(bcx)
737737
}
@@ -889,7 +889,7 @@ fn compile_guard<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
889889
}
890890
}
891891

892-
with_cond(bcx, Not(bcx, val), |bcx| {
892+
with_cond(bcx, Not(bcx, val, guard_expr.debug_loc()), |bcx| {
893893
// Guard does not match: remove all bindings from the lllocals table
894894
for (_, &binding_info) in data.bindings_map.iter() {
895895
call_lifetime_end(bcx, binding_info.llmatch);
@@ -966,7 +966,7 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
966966
}
967967
_ => ()
968968
}
969-
Br(bcx, data.bodycx.llbb);
969+
Br(bcx, data.bodycx.llbb, DebugLoc::None);
970970
}
971971
}
972972
}
@@ -1096,7 +1096,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
10961096
if !exhaustive || i + 1 < len {
10971097
opt_cx = bcx.fcx.new_temp_block("match_case");
10981098
match kind {
1099-
Single => Br(bcx, opt_cx.llbb),
1099+
Single => Br(bcx, opt_cx.llbb, DebugLoc::None),
11001100
Switch => {
11011101
match opt.trans(bcx) {
11021102
SingleResult(r) => {
@@ -1131,7 +1131,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
11311131
compare_scalar_types(
11321132
bcx, test_val, vend,
11331133
t, ast::BiLe);
1134-
Result::new(bcx, And(bcx, llge, llle))
1134+
Result::new(bcx, And(bcx, llge, llle, DebugLoc::None))
11351135
}
11361136
LowerBound(Result { bcx, val }) => {
11371137
compare_scalar_types(bcx, test_val, val, t, ast::BiGe)
@@ -1149,12 +1149,12 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
11491149
if i + 1 < len && (guarded || multi_pats || kind == CompareSliceLength) {
11501150
branch_chk = Some(JumpToBasicBlock(bcx.llbb));
11511151
}
1152-
CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
1152+
CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb, DebugLoc::None);
11531153
}
11541154
_ => ()
11551155
}
11561156
} else if kind == Compare || kind == CompareSliceLength {
1157-
Br(bcx, else_cx.llbb);
1157+
Br(bcx, else_cx.llbb, DebugLoc::None);
11581158
}
11591159

11601160
let mut size = 0u;
@@ -1194,7 +1194,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
11941194
// Compile the fall-through case, if any
11951195
if !exhaustive && kind != Single {
11961196
if kind == Compare || kind == CompareSliceLength {
1197-
Br(bcx, else_cx.llbb);
1197+
Br(bcx, else_cx.llbb, DebugLoc::None);
11981198
}
11991199
match chk {
12001200
// If there is only one default arm left, move on to the next

src/librustc_trans/trans/adt.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ use trans::cleanup;
6262
use trans::cleanup::CleanupMethods;
6363
use trans::common::*;
6464
use trans::datum;
65+
use trans::debuginfo::DebugLoc;
6566
use trans::machine;
6667
use trans::monomorphize;
6768
use trans::type_::Type;
@@ -979,7 +980,7 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
979980
let variant_value = PointerCast(variant_cx, value, real_ty.ptr_to());
980981

981982
variant_cx = f(variant_cx, case, variant_value);
982-
Br(variant_cx, bcx_next.llbb);
983+
Br(variant_cx, bcx_next.llbb, DebugLoc::None);
983984
}
984985

985986
bcx_next

src/librustc_trans/trans/base.rs

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use trans::closure;
5757
use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral};
5858
use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef};
5959
use trans::common::{CrateContext, ExternMap, FunctionContext};
60-
use trans::common::{NodeInfo, Result};
60+
use trans::common::{Result};
6161
use trans::common::{node_id_type, return_type_is_void};
6262
use trans::common::{tydesc_info, type_is_immediate};
6363
use trans::common::{type_is_zero_size, val_ty};
@@ -66,7 +66,7 @@ use trans::consts;
6666
use trans::context::SharedCrateContext;
6767
use trans::controlflow;
6868
use trans::datum;
69-
use trans::debuginfo;
69+
use trans::debuginfo::{self, DebugLoc};
7070
use trans::expr;
7171
use trans::foreign;
7272
use trans::glue;
@@ -792,7 +792,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
792792
&**variant,
793793
substs,
794794
&mut f);
795-
Br(variant_cx, next_cx.llbb);
795+
Br(variant_cx, next_cx.llbb, DebugLoc::None);
796796
}
797797
cx = next_cx;
798798
}
@@ -957,7 +957,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
957957
llfn: ValueRef,
958958
llargs: &[ValueRef],
959959
fn_ty: Ty<'tcx>,
960-
call_info: Option<NodeInfo>)
960+
debug_loc: DebugLoc)
961961
-> (ValueRef, Block<'blk, 'tcx>) {
962962
let _icx = push_ctxt("invoke_");
963963
if bcx.unreachable.get() {
@@ -983,30 +983,25 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
983983
let normal_bcx = bcx.fcx.new_temp_block("normal-return");
984984
let landing_pad = bcx.fcx.get_landing_pad();
985985

986-
match call_info {
987-
Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span),
988-
None => debuginfo::clear_source_location(bcx.fcx)
989-
};
990-
991986
let llresult = Invoke(bcx,
992987
llfn,
993988
&llargs[],
994989
normal_bcx.llbb,
995990
landing_pad,
996-
Some(attributes));
991+
Some(attributes),
992+
debug_loc);
997993
return (llresult, normal_bcx);
998994
} else {
999995
debug!("calling {} at {:?}", bcx.val_to_string(llfn), bcx.llbb);
1000996
for &llarg in llargs.iter() {
1001997
debug!("arg: {}", bcx.val_to_string(llarg));
1002998
}
1003999

1004-
match call_info {
1005-
Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span),
1006-
None => debuginfo::clear_source_location(bcx.fcx)
1007-
};
1008-
1009-
let llresult = Call(bcx, llfn, &llargs[], Some(attributes));
1000+
let llresult = Call(bcx,
1001+
llfn,
1002+
&llargs[],
1003+
Some(attributes),
1004+
debug_loc);
10101005
return (llresult, bcx);
10111006
}
10121007
}
@@ -1094,10 +1089,10 @@ pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
10941089
let fcx = bcx.fcx;
10951090
let next_cx = fcx.new_temp_block("next");
10961091
let cond_cx = fcx.new_temp_block("cond");
1097-
CondBr(bcx, val, cond_cx.llbb, next_cx.llbb);
1092+
CondBr(bcx, val, cond_cx.llbb, next_cx.llbb, DebugLoc::None);
10981093
let after_cx = f(cond_cx);
10991094
if !after_cx.terminated.get() {
1100-
Br(after_cx, next_cx.llbb);
1095+
Br(after_cx, next_cx.llbb, DebugLoc::None);
11011096
}
11021097
next_cx
11031098
}
@@ -1113,7 +1108,7 @@ pub fn call_lifetime_start(cx: Block, ptr: ValueRef) {
11131108
let llsize = C_u64(ccx, machine::llsize_of_alloc(ccx, val_ty(ptr).element_type()));
11141109
let ptr = PointerCast(cx, ptr, Type::i8p(ccx));
11151110
let lifetime_start = ccx.get_intrinsic(&"llvm.lifetime.start");
1116-
Call(cx, lifetime_start, &[llsize, ptr], None);
1111+
Call(cx, lifetime_start, &[llsize, ptr], None, DebugLoc::None);
11171112
}
11181113

11191114
pub fn call_lifetime_end(cx: Block, ptr: ValueRef) {
@@ -1127,7 +1122,7 @@ pub fn call_lifetime_end(cx: Block, ptr: ValueRef) {
11271122
let llsize = C_u64(ccx, machine::llsize_of_alloc(ccx, val_ty(ptr).element_type()));
11281123
let ptr = PointerCast(cx, ptr, Type::i8p(ccx));
11291124
let lifetime_end = ccx.get_intrinsic(&"llvm.lifetime.end");
1130-
Call(cx, lifetime_end, &[llsize, ptr], None);
1125+
Call(cx, lifetime_end, &[llsize, ptr], None, DebugLoc::None);
11311126
}
11321127

11331128
pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
@@ -1144,7 +1139,7 @@ pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a
11441139
let size = IntCast(cx, n_bytes, ccx.int_type());
11451140
let align = C_i32(ccx, align as i32);
11461141
let volatile = C_bool(ccx, false);
1147-
Call(cx, memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
1142+
Call(cx, memcpy, &[dst_ptr, src_ptr, size, align, volatile], None, DebugLoc::None);
11481143
}
11491144

11501145
pub fn memcpy_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@@ -1697,13 +1692,14 @@ fn copy_unboxed_closure_args_to_allocas<'blk, 'tcx>(
16971692
// and builds the return block.
16981693
pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
16991694
last_bcx: Block<'blk, 'tcx>,
1700-
retty: ty::FnOutput<'tcx>) {
1695+
retty: ty::FnOutput<'tcx>,
1696+
ret_debug_loc: DebugLoc) {
17011697
let _icx = push_ctxt("finish_fn");
17021698

17031699
let ret_cx = match fcx.llreturn.get() {
17041700
Some(llreturn) => {
17051701
if !last_bcx.terminated.get() {
1706-
Br(last_bcx, llreturn);
1702+
Br(last_bcx, llreturn, DebugLoc::None);
17071703
}
17081704
raw_block(fcx, false, llreturn)
17091705
}
@@ -1713,7 +1709,7 @@ pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
17131709
// This shouldn't need to recompute the return type,
17141710
// as new_fn_ctxt did it already.
17151711
let substd_retty = fcx.monomorphize(&retty);
1716-
build_return_block(fcx, ret_cx, substd_retty);
1712+
build_return_block(fcx, ret_cx, substd_retty, ret_debug_loc);
17171713

17181714
debuginfo::clear_source_location(fcx);
17191715
fcx.cleanup();
@@ -1722,10 +1718,11 @@ pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
17221718
// Builds the return block for a function.
17231719
pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
17241720
ret_cx: Block<'blk, 'tcx>,
1725-
retty: ty::FnOutput<'tcx>) {
1721+
retty: ty::FnOutput<'tcx>,
1722+
ret_debug_location: DebugLoc) {
17261723
if fcx.llretslotptr.get().is_none() ||
17271724
(!fcx.needs_ret_allocas && fcx.caller_expects_out_pointer) {
1728-
return RetVoid(ret_cx);
1725+
return RetVoid(ret_cx, ret_debug_location);
17291726
}
17301727

17311728
let retslot = if fcx.needs_ret_allocas {
@@ -1755,26 +1752,26 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
17551752
if let ty::FnConverging(retty) = retty {
17561753
store_ty(ret_cx, retval, get_param(fcx.llfn, 0), retty);
17571754
}
1758-
RetVoid(ret_cx)
1755+
RetVoid(ret_cx, ret_debug_location)
17591756
} else {
1760-
Ret(ret_cx, retval)
1757+
Ret(ret_cx, retval, ret_debug_location)
17611758
}
17621759
}
17631760
// Otherwise, copy the return value to the ret slot
17641761
None => match retty {
17651762
ty::FnConverging(retty) => {
17661763
if fcx.caller_expects_out_pointer {
17671764
memcpy_ty(ret_cx, get_param(fcx.llfn, 0), retslot, retty);
1768-
RetVoid(ret_cx)
1765+
RetVoid(ret_cx, ret_debug_location)
17691766
} else {
1770-
Ret(ret_cx, load_ty(ret_cx, retslot, retty))
1767+
Ret(ret_cx, load_ty(ret_cx, retslot, retty), ret_debug_location)
17711768
}
17721769
}
17731770
ty::FnDiverging => {
17741771
if fcx.caller_expects_out_pointer {
1775-
RetVoid(ret_cx)
1772+
RetVoid(ret_cx, ret_debug_location)
17761773
} else {
1777-
Ret(ret_cx, C_undef(Type::nil(fcx.ccx)))
1774+
Ret(ret_cx, C_undef(Type::nil(fcx.ccx)), ret_debug_location)
17781775
}
17791776
}
17801777
}
@@ -1905,7 +1902,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
19051902

19061903
match fcx.llreturn.get() {
19071904
Some(_) => {
1908-
Br(bcx, fcx.return_exit_block());
1905+
Br(bcx, fcx.return_exit_block(), DebugLoc::None);
19091906
fcx.pop_custom_cleanup_scope(arg_scope);
19101907
}
19111908
None => {
@@ -1924,8 +1921,11 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
19241921
}
19251922
}
19261923

1924+
let ret_debug_loc = DebugLoc::At(fn_cleanup_debug_loc.id,
1925+
fn_cleanup_debug_loc.span);
1926+
19271927
// Insert the mandatory first few basic blocks before lltop.
1928-
finish_fn(&fcx, bcx, output_type);
1928+
finish_fn(&fcx, bcx, output_type, ret_debug_loc);
19291929
}
19301930

19311931
// trans_fn: creates an LLVM function corresponding to a source language
@@ -1977,7 +1977,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
19771977
disr: ty::Disr,
19781978
args: callee::CallArgs,
19791979
dest: expr::Dest,
1980-
call_info: Option<NodeInfo>)
1980+
debug_loc: DebugLoc)
19811981
-> Result<'blk, 'tcx> {
19821982

19831983
let ccx = bcx.fcx.ccx;
@@ -2016,7 +2016,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
20162016
&fields[],
20172017
None,
20182018
expr::SaveIn(llresult),
2019-
call_info);
2019+
debug_loc);
20202020
}
20212021
_ => ccx.sess().bug("expected expr as arguments for variant/struct tuple constructor")
20222022
}
@@ -2027,7 +2027,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
20272027
let bcx = match dest {
20282028
expr::SaveIn(_) => bcx,
20292029
expr::Ignore => {
2030-
glue::drop_ty(bcx, llresult, result_ty, call_info)
2030+
glue::drop_ty(bcx, llresult, result_ty, debug_loc)
20312031
}
20322032
};
20332033

@@ -2094,7 +2094,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
20942094
adt::trans_set_discr(bcx, &*repr, dest, disr);
20952095
}
20962096

2097-
finish_fn(&fcx, bcx, result_ty);
2097+
finish_fn(&fcx, bcx, result_ty, DebugLoc::None);
20982098
}
20992099

21002100
fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, id: ast::NodeId) {

0 commit comments

Comments
 (0)