Skip to content

Commit 1e42072

Browse files
committed
rustc_codegen_ssa: hide address ops from the declare_local interface.
1 parent c2e7743 commit 1e42072

File tree

4 files changed

+77
-72
lines changed

4 files changed

+77
-72
lines changed

src/librustc_codegen_llvm/debuginfo/mod.rs

+53-48
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// See doc.rs for documentation.
22
mod doc;
33

4-
use rustc_codegen_ssa::mir::debuginfo::VariableAccess::*;
54
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
65

76
use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit};
@@ -28,17 +27,18 @@ use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet};
2827
use rustc_data_structures::small_c_str::SmallCStr;
2928
use rustc_index::vec::IndexVec;
3029
use rustc_codegen_ssa::debuginfo::type_names;
31-
use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope, VariableAccess,
30+
use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope,
3231
VariableKind};
3332

3433
use libc::c_uint;
3534
use std::cell::RefCell;
3635
use std::ffi::{CStr, CString};
3736

37+
use smallvec::SmallVec;
3838
use syntax_pos::{self, BytePos, Span, Pos};
3939
use syntax::ast;
4040
use syntax::symbol::Symbol;
41-
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
41+
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Size};
4242
use rustc_codegen_ssa::traits::*;
4343

4444
pub mod gdb;
@@ -153,7 +153,9 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
153153
variable_name: ast::Name,
154154
variable_type: Ty<'tcx>,
155155
scope_metadata: &'ll DIScope,
156-
variable_access: VariableAccess<'_, &'ll Value>,
156+
variable_alloca: Self::Value,
157+
direct_offset: Size,
158+
indirect_offsets: &[Size],
157159
variable_kind: VariableKind,
158160
span: Span,
159161
) {
@@ -174,43 +176,55 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
174176
};
175177
let align = cx.align_of(variable_type);
176178

177-
let name = SmallCStr::new(&variable_name.as_str());
178-
match (variable_access, &[][..]) {
179-
(DirectVariable { alloca }, address_operations) |
180-
(IndirectVariable {alloca, address_operations}, _) => {
181-
let metadata = unsafe {
182-
llvm::LLVMRustDIBuilderCreateVariable(
183-
DIB(cx),
184-
dwarf_tag,
185-
scope_metadata,
186-
name.as_ptr(),
187-
file_metadata,
188-
loc.line as c_uint,
189-
type_metadata,
190-
cx.sess().opts.optimize != config::OptLevel::No,
191-
DIFlags::FlagZero,
192-
argument_index,
193-
align.bytes() as u32,
194-
)
195-
};
196-
source_loc::set_debug_location(self,
197-
InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()));
198-
unsafe {
199-
let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder);
200-
let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
201-
DIB(cx),
202-
alloca,
203-
metadata,
204-
address_operations.as_ptr(),
205-
address_operations.len() as c_uint,
206-
debug_loc,
207-
self.llbb());
208-
209-
llvm::LLVMSetInstDebugLocation(self.llbuilder, instr);
210-
}
211-
source_loc::set_debug_location(self, UnknownLocation);
179+
// Convert the direct and indirect offsets to address ops.
180+
let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() };
181+
let op_plus_uconst = || unsafe { llvm::LLVMRustDIBuilderCreateOpPlusUconst() };
182+
let mut addr_ops = SmallVec::<[_; 8]>::new();
183+
184+
if direct_offset.bytes() > 0 {
185+
addr_ops.push(op_plus_uconst());
186+
addr_ops.push(direct_offset.bytes() as i64);
187+
}
188+
for &offset in indirect_offsets {
189+
addr_ops.push(op_deref());
190+
if offset.bytes() > 0 {
191+
addr_ops.push(op_plus_uconst());
192+
addr_ops.push(offset.bytes() as i64);
212193
}
213194
}
195+
196+
let name = SmallCStr::new(&variable_name.as_str());
197+
let metadata = unsafe {
198+
llvm::LLVMRustDIBuilderCreateVariable(
199+
DIB(cx),
200+
dwarf_tag,
201+
scope_metadata,
202+
name.as_ptr(),
203+
file_metadata,
204+
loc.line as c_uint,
205+
type_metadata,
206+
cx.sess().opts.optimize != config::OptLevel::No,
207+
DIFlags::FlagZero,
208+
argument_index,
209+
align.bytes() as u32,
210+
)
211+
};
212+
source_loc::set_debug_location(self,
213+
InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()));
214+
unsafe {
215+
let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder);
216+
let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
217+
DIB(cx),
218+
variable_alloca,
219+
metadata,
220+
addr_ops.as_ptr(),
221+
addr_ops.len() as c_uint,
222+
debug_loc,
223+
self.llbb());
224+
225+
llvm::LLVMSetInstDebugLocation(self.llbuilder, instr);
226+
}
227+
source_loc::set_debug_location(self, UnknownLocation);
214228
}
215229

216230
fn set_source_location(
@@ -571,13 +585,4 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
571585
fn debuginfo_finalize(&self) {
572586
finalize(self)
573587
}
574-
575-
fn debuginfo_upvar_ops_sequence(&self, byte_offset_of_var_in_env: u64) -> [i64; 4] {
576-
unsafe {
577-
[llvm::LLVMRustDIBuilderCreateOpDeref(),
578-
llvm::LLVMRustDIBuilderCreateOpPlusUconst(),
579-
byte_offset_of_var_in_env as i64,
580-
llvm::LLVMRustDIBuilderCreateOpDeref()]
581-
}
582-
}
583588
}

src/librustc_codegen_llvm/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ extern crate rustc_fs_util;
3838
extern crate rustc_driver as _;
3939

4040
#[macro_use] extern crate log;
41+
extern crate smallvec;
4142
extern crate syntax;
4243
extern crate syntax_pos;
4344
extern crate rustc_errors as errors;

src/librustc_codegen_ssa/mir/debuginfo.rs

+17-21
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc::hir::def_id::CrateNum;
33
use rustc::mir;
44
use rustc::session::config::DebugInfo;
55
use rustc::ty::{self, UpvarSubsts};
6-
use rustc::ty::layout::HasTyCtxt;
6+
use rustc::ty::layout::{HasTyCtxt, Size};
77
use rustc_target::abi::{Variants, VariantIdx};
88
use crate::traits::*;
99

@@ -19,14 +19,6 @@ pub struct FunctionDebugContext<D> {
1919
pub defining_crate: CrateNum,
2020
}
2121

22-
pub enum VariableAccess<'a, V> {
23-
// The llptr given is an alloca containing the variable's value
24-
DirectVariable { alloca: V },
25-
// The llptr given is an alloca containing the start of some pointer chain
26-
// leading to the variable's content.
27-
IndirectVariable { alloca: V, address_operations: &'a [i64] }
28-
}
29-
3022
pub enum VariableKind {
3123
ArgumentVariable(usize /*index*/),
3224
LocalVariable,
@@ -188,8 +180,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
188180
});
189181
if let Some(scope) = scope {
190182
bx.declare_local(debug_context, name, place.layout.ty, scope,
191-
VariableAccess::DirectVariable { alloca: place.llval },
192-
kind, span);
183+
place.llval, Size::ZERO, &[], kind, span);
193184
}
194185
}
195186
}
@@ -310,30 +301,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
310301
}
311302
None => &closure_layout.fields,
312303
};
313-
let byte_offset_of_var_in_env = fields.offset(field).bytes();
314-
315-
let ops = bx.debuginfo_upvar_ops_sequence(byte_offset_of_var_in_env);
316304

317305
// The environment and the capture can each be indirect.
318-
let mut ops = if env_ref { &ops[..] } else { &ops[1..] };
306+
let mut direct_offset = Size::ZERO;
307+
let indirect_offsets = [
308+
fields.offset(field),
309+
Size::ZERO,
310+
];
311+
let mut indirect_offsets = &indirect_offsets[..];
312+
313+
if !env_ref {
314+
direct_offset = indirect_offsets[0];
315+
indirect_offsets = &indirect_offsets[1..];
316+
}
319317

320318
let ty = if let (true, &ty::Ref(_, ty, _)) = (by_ref, &ty.kind) {
321319
ty
322320
} else {
323-
ops = &ops[..ops.len() - 1];
321+
indirect_offsets = &indirect_offsets[..indirect_offsets.len() - 1];
324322
ty
325323
};
326324

327-
let variable_access = VariableAccess::IndirectVariable {
328-
alloca: place.llval,
329-
address_operations: &ops
330-
};
331325
bx.declare_local(
332326
debug_context,
333327
name,
334328
ty,
335329
var_scope,
336-
variable_access,
330+
place.llval,
331+
direct_offset,
332+
indirect_offsets,
337333
VariableKind::LocalVariable,
338334
var_span
339335
);

src/librustc_codegen_ssa/traits/debuginfo.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use super::BackendTypes;
2-
use crate::mir::debuginfo::{FunctionDebugContext, VariableAccess, VariableKind};
2+
use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
33
use rustc::hir::def_id::CrateNum;
44
use rustc::mir;
55
use rustc::ty::{self, Ty, Instance};
6+
use rustc::ty::layout::Size;
67
use syntax::ast::Name;
78
use syntax_pos::{SourceFile, Span};
89

@@ -28,7 +29,6 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
2829
defining_crate: CrateNum,
2930
) -> Self::DIScope;
3031
fn debuginfo_finalize(&self);
31-
fn debuginfo_upvar_ops_sequence(&self, byte_offset_of_var_in_env: u64) -> [i64; 4];
3232
}
3333

3434
pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
@@ -38,7 +38,10 @@ pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
3838
variable_name: Name,
3939
variable_type: Ty<'tcx>,
4040
scope_metadata: Self::DIScope,
41-
variable_access: VariableAccess<'_, Self::Value>,
41+
variable_alloca: Self::Value,
42+
direct_offset: Size,
43+
// NB: each offset implies a deref (i.e. they're steps in a pointer chain).
44+
indirect_offsets: &[Size],
4245
variable_kind: VariableKind,
4346
span: Span,
4447
);

0 commit comments

Comments
 (0)