about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/trans/_match.rs16
-rw-r--r--src/librustc/middle/trans/base.rs170
-rw-r--r--src/librustc/middle/trans/build.rs5
-rw-r--r--src/librustc/middle/trans/callee.rs14
-rw-r--r--src/librustc/middle/trans/closure.rs20
-rw-r--r--src/librustc/middle/trans/common.rs1
-rw-r--r--src/librustc/middle/trans/consts.rs8
-rw-r--r--src/librustc/middle/trans/context.rs7
-rw-r--r--src/librustc/middle/trans/controlflow.rs22
-rw-r--r--src/librustc/middle/trans/datum.rs8
-rw-r--r--src/librustc/middle/trans/expr.rs46
-rw-r--r--src/librustc/middle/trans/foreign.rs32
-rw-r--r--src/librustc/middle/trans/glue.rs44
-rw-r--r--src/librustc/middle/trans/inline.rs5
-rw-r--r--src/librustc/middle/trans/meth.rs20
-rw-r--r--src/librustc/middle/trans/monomorphize.rs4
-rw-r--r--src/librustc/middle/trans/tvec.rs22
-rw-r--r--src/librustc/middle/trans/uniq.rs4
18 files changed, 225 insertions, 223 deletions
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 72da71afed6..958677eab4a 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -259,7 +259,7 @@ pub enum opt_result {
     range_result(Result, Result),
 }
 pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
-    let _icx = bcx.insn_ctxt("match::trans_opt");
+    let _icx = push_ctxt("match::trans_opt");
     let ccx = bcx.ccx();
     let bcx = bcx;
     match *o {
@@ -870,7 +870,7 @@ pub fn extract_variant_args(bcx: block,
                             disr_val: int,
                             val: ValueRef)
     -> ExtractedBlock {
-    let _icx = bcx.insn_ctxt("match::extract_variant_args");
+    let _icx = push_ctxt("match::extract_variant_args");
     let args = do vec::from_fn(adt::num_args(repr, disr_val)) |i| {
         adt::trans_field_ptr(bcx, repr, val, disr_val, i)
     };
@@ -896,7 +896,7 @@ pub fn extract_vec_elems(bcx: block,
                          val: ValueRef,
                          count: ValueRef)
                       -> ExtractedBlock {
-    let _icx = bcx.insn_ctxt("match::extract_vec_elems");
+    let _icx = push_ctxt("match::extract_vec_elems");
     let vec_datum = match_datum(bcx, val, pat_id);
     let (bcx, base, len) = vec_datum.get_vec_base_and_len(bcx, pat_span,
                                                           pat_id, 0);
@@ -1088,7 +1088,7 @@ pub fn compare_values(cx: block,
                       rhs: ValueRef,
                       rhs_t: ty::t)
                    -> Result {
-    let _icx = cx.insn_ctxt("compare_values");
+    let _icx = push_ctxt("compare_values");
     if ty::type_is_scalar(rhs_t) {
       let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::eq);
       return rslt(rs.bcx, rs.val);
@@ -1277,7 +1277,7 @@ pub fn compile_submatch(bcx: block,
       For an empty match, a fall-through case must exist
      */
     assert!((m.len() > 0u || chk.is_some()));
-    let _icx = bcx.insn_ctxt("match::compile_submatch");
+    let _icx = push_ctxt("match::compile_submatch");
     let mut bcx = bcx;
     let tcx = bcx.tcx();
     let dm = tcx.def_map;
@@ -1617,7 +1617,7 @@ pub fn trans_match(bcx: block,
                    discr_expr: @ast::expr,
                    arms: ~[ast::arm],
                    dest: Dest) -> block {
-    let _icx = bcx.insn_ctxt("match::trans_match");
+    let _icx = push_ctxt("match::trans_match");
     do with_scope(bcx, match_expr.info(), "match") |bcx| {
         trans_match_inner(bcx, discr_expr, arms, dest)
     }
@@ -1664,7 +1664,7 @@ pub fn trans_match_inner(scope_cx: block,
                          discr_expr: @ast::expr,
                          arms: &[ast::arm],
                          dest: Dest) -> block {
-    let _icx = scope_cx.insn_ctxt("match::trans_match_inner");
+    let _icx = push_ctxt("match::trans_match_inner");
     let mut bcx = scope_cx;
     let tcx = bcx.tcx();
 
@@ -1751,7 +1751,7 @@ pub fn bind_irrefutable_pat(bcx: block,
                             make_copy: bool,
                             binding_mode: IrrefutablePatternBindingMode)
                          -> block {
-    let _icx = bcx.insn_ctxt("match::bind_irrefutable_pat");
+    let _icx = push_ctxt("match::bind_irrefutable_pat");
     let ccx = bcx.fcx.ccx;
     let mut bcx = bcx;
 
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index b94442c85ef..bd57a709a90 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -73,6 +73,7 @@ use core::libc::c_uint;
 use core::str;
 use core::uint;
 use core::vec;
+use core::local_data;
 use extra::time;
 use syntax::ast::ident;
 use syntax::ast_map::{path, path_elt_to_str, path_name};
@@ -88,49 +89,52 @@ use syntax::abi::{X86, X86_64, Arm, Mips};
 
 pub use middle::trans::context::task_llcx;
 
-pub struct icx_popper {
-    ccx: @mut CrateContext,
-}
+fn task_local_insn_key(_v: @~[&'static str]) {}
 
-#[unsafe_destructor]
-impl Drop for icx_popper {
-    fn finalize(&self) {
-        if self.ccx.sess.count_llvm_insns() {
-            self.ccx.stats.llvm_insn_ctxt.pop();
+pub fn with_insn_ctxt(blk: &fn(&[&'static str])) {
+    unsafe {
+        let opt = local_data::local_data_get(task_local_insn_key);
+        if opt.is_some() {
+            blk(*opt.unwrap());
         }
     }
 }
 
-pub fn icx_popper(ccx: @mut CrateContext) -> icx_popper {
-    icx_popper {
-        ccx: ccx
+pub fn init_insn_ctxt() {
+    unsafe {
+        local_data::local_data_set(task_local_insn_key, @~[]);
     }
 }
 
-pub trait get_insn_ctxt {
-    fn insn_ctxt(&self, s: &str) -> icx_popper;
-}
+pub struct _InsnCtxt { _x: () }
 
-impl get_insn_ctxt for @mut CrateContext {
-    fn insn_ctxt(&self, s: &str) -> icx_popper {
-        debug!("new insn_ctxt: %s", s);
-        if self.sess.count_llvm_insns() {
-            self.stats.llvm_insn_ctxt.push(str::to_owned(s));
+#[unsafe_destructor]
+impl Drop for _InsnCtxt {
+    fn finalize(&self) {
+        unsafe {
+            do local_data::local_data_modify(task_local_insn_key) |c| {
+                do c.map_consume |@ctx| {
+                    let mut ctx = ctx;
+                    ctx.pop();
+                    @ctx
+                }
+            }
         }
-        icx_popper(*self)
-    }
-}
-
-impl get_insn_ctxt for block {
-    fn insn_ctxt(&self, s: &str) -> icx_popper {
-        self.ccx().insn_ctxt(s)
     }
 }
 
-impl get_insn_ctxt for fn_ctxt {
-    fn insn_ctxt(&self, s: &str) -> icx_popper {
-        self.ccx.insn_ctxt(s)
+pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
+    debug!("new InsnCtxt: %s", s);
+    unsafe {
+        do local_data::local_data_modify(task_local_insn_key) |c| {
+            do c.map_consume |@ctx| {
+                let mut ctx = ctx;
+                ctx.push(s);
+                @ctx
+            }
+        }
     }
+    _InsnCtxt { _x: () }
 }
 
 fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool {
@@ -189,13 +193,13 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
     }
 }
 pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
-    let _icx = cx.insn_ctxt("umax");
+    let _icx = push_ctxt("umax");
     let cond = ICmp(cx, lib::llvm::IntULT, a, b);
     return Select(cx, cond, b, a);
 }
 
 pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
-    let _icx = cx.insn_ctxt("umin");
+    let _icx = push_ctxt("umin");
     let cond = ICmp(cx, lib::llvm::IntULT, a, b);
     return Select(cx, cond, a, b);
 }
@@ -204,7 +208,7 @@ pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
 // The type of the returned pointer is always i8*.  If you care about the
 // return type, use bump_ptr().
 pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef {
-    let _icx = bcx.insn_ctxt("ptr_offs");
+    let _icx = push_ctxt("ptr_offs");
     let raw = PointerCast(bcx, base, Type::i8p());
     InBoundsGEP(bcx, raw, [sz])
 }
@@ -213,7 +217,7 @@ pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef {
 // to a given type.
 pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) ->
    ValueRef {
-    let _icx = bcx.insn_ctxt("bump_ptr");
+    let _icx = push_ctxt("bump_ptr");
     let ccx = bcx.ccx();
     let bumped = ptr_offs(bcx, base, sz);
     let typ = type_of(ccx, t).ptr_to();
@@ -228,7 +232,7 @@ pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) ->
 pub fn opaque_box_body(bcx: block,
                        body_t: ty::t,
                        boxptr: ValueRef) -> ValueRef {
-    let _icx = bcx.insn_ctxt("opaque_box_body");
+    let _icx = push_ctxt("opaque_box_body");
     let ccx = bcx.ccx();
     let ty = type_of(ccx, body_t);
     let ty = Type::box(ccx, &ty);
@@ -242,7 +246,7 @@ pub fn malloc_raw_dyn(bcx: block,
                       t: ty::t,
                       heap: heap,
                       size: ValueRef) -> Result {
-    let _icx = bcx.insn_ctxt("malloc_raw");
+    let _icx = push_ctxt("malloc_raw");
     let ccx = bcx.ccx();
 
     let (mk_fn, langcall) = match heap {
@@ -306,7 +310,7 @@ pub struct MallocResult {
 // and pulls out the body
 pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef)
     -> MallocResult {
-    let _icx = bcx.insn_ctxt("malloc_general");
+    let _icx = push_ctxt("malloc_general");
     let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size);
     let non_gc_box = non_gc_box_cast(bcx, llbox);
     let body = GEPi(bcx, non_gc_box, [0u, abi::box_field_body]);
@@ -457,7 +461,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext,
                     parent_id: ast::def_id,
                     substs: &[ty::t])
                  -> ValueRef {
-    let _icx = ccx.insn_ctxt("trans_res_dtor");
+    let _icx = push_ctxt("trans_res_dtor");
     if !substs.is_empty() {
         let did = if did.crate != ast::local_crate {
             inline::maybe_instantiate_inline(ccx, did, true)
@@ -547,7 +551,7 @@ pub fn compare_scalar_values(cx: block,
                              nt: scalar_type,
                              op: ast::binop)
                           -> ValueRef {
-    let _icx = cx.insn_ctxt("compare_scalar_values");
+    let _icx = push_ctxt("compare_scalar_values");
     fn die(cx: block) -> ! {
         cx.tcx().sess.bug("compare_scalar_values: must be a\
                            comparison operator");
@@ -616,12 +620,12 @@ pub fn store_inbounds(cx: block, v: ValueRef, p: ValueRef, idxs: &[uint]) {
 // Iterates through the elements of a structural type.
 pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
                           f: val_and_ty_fn) -> block {
-    let _icx = cx.insn_ctxt("iter_structural_ty");
+    let _icx = push_ctxt("iter_structural_ty");
 
     fn iter_variant(cx: block, repr: &adt::Repr, av: ValueRef,
                     variant: ty::VariantInfo,
                     tps: &[ty::t], f: val_and_ty_fn) -> block {
-        let _icx = cx.insn_ctxt("iter_variant");
+        let _icx = push_ctxt("iter_variant");
         let tcx = cx.tcx();
         let mut cx = cx;
 
@@ -795,7 +799,7 @@ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t)
 
 pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef])
            -> (ValueRef, block) {
-    let _icx = bcx.insn_ctxt("invoke_");
+    let _icx = push_ctxt("invoke_");
     if bcx.unreachable {
         return (C_null(Type::i8()), bcx);
     }
@@ -911,7 +915,7 @@ pub fn in_lpad_scope_cx(bcx: block, f: &fn(si: &mut scope_info)) {
 }
 
 pub fn get_landing_pad(bcx: block) -> BasicBlockRef {
-    let _icx = bcx.insn_ctxt("get_landing_pad");
+    let _icx = push_ctxt("get_landing_pad");
 
     let mut cached = None;
     let mut pad_bcx = bcx; // Guaranteed to be set below
@@ -1004,20 +1008,20 @@ pub fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef {
 }
 
 pub fn spill_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef {
-    let _icx = cx.insn_ctxt("spill_if_immediate");
+    let _icx = push_ctxt("spill_if_immediate");
     if ty::type_is_immediate(t) { return do_spill(cx, v, t); }
     return v;
 }
 
 pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef {
-    let _icx = cx.insn_ctxt("load_if_immediate");
+    let _icx = push_ctxt("load_if_immediate");
     if ty::type_is_immediate(t) { return Load(cx, v); }
     return v;
 }
 
 pub fn trans_trace(bcx: block, sp_opt: Option<span>, trace_str: @str) {
     if !bcx.sess().trace() { return; }
-    let _icx = bcx.insn_ctxt("trans_trace");
+    let _icx = push_ctxt("trans_trace");
     add_comment(bcx, trace_str);
     let V_trace_str = C_cstr(bcx.ccx(), trace_str);
     let (V_filename, V_line) = match sp_opt {
@@ -1038,7 +1042,7 @@ pub fn trans_trace(bcx: block, sp_opt: Option<span>, trace_str: @str) {
 }
 
 pub fn build_return(bcx: block) {
-    let _icx = bcx.insn_ctxt("build_return");
+    let _icx = push_ctxt("build_return");
     Br(bcx, bcx.fcx.llreturn);
 }
 
@@ -1054,7 +1058,7 @@ pub fn init_local(bcx: block, local: @ast::local) -> block {
            bcx.to_str(), local.node.id);
     let _indenter = indenter();
 
-    let _icx = bcx.insn_ctxt("init_local");
+    let _icx = push_ctxt("init_local");
     let ty = node_id_type(bcx, local.node.id);
 
     debug!("ty=%s", bcx.ty_to_str(ty));
@@ -1102,7 +1106,7 @@ pub fn init_local(bcx: block, local: @ast::local) -> block {
 }
 
 pub fn trans_stmt(cx: block, s: &ast::stmt) -> block {
-    let _icx = cx.insn_ctxt("trans_stmt");
+    let _icx = push_ctxt("trans_stmt");
     debug!("trans_stmt(%s)", stmt_to_str(s, cx.tcx().sess.intr()));
 
     if cx.sess().asm_comments() {
@@ -1230,7 +1234,7 @@ pub fn trans_block_cleanups_(bcx: block,
                              cleanups: &[cleanup],
                              /* cleanup_cx: block, */
                              is_lpad: bool) -> block {
-    let _icx = bcx.insn_ctxt("trans_block_cleanups");
+    let _icx = push_ctxt("trans_block_cleanups");
     // NB: Don't short-circuit even if this block is unreachable because
     // GC-based cleanup needs to the see that the roots are live.
     let no_lpads =
@@ -1257,7 +1261,7 @@ pub fn trans_block_cleanups_(bcx: block,
 pub fn cleanup_and_leave(bcx: block,
                          upto: Option<BasicBlockRef>,
                          leave: Option<BasicBlockRef>) {
-    let _icx = bcx.insn_ctxt("cleanup_and_leave");
+    let _icx = push_ctxt("cleanup_and_leave");
     let mut cur = bcx;
     let mut bcx = bcx;
     let is_lpad = leave == None;
@@ -1324,12 +1328,12 @@ pub fn cleanup_and_leave(bcx: block,
 }
 
 pub fn cleanup_and_Br(bcx: block, upto: block, target: BasicBlockRef) {
-    let _icx = bcx.insn_ctxt("cleanup_and_Br");
+    let _icx = push_ctxt("cleanup_and_Br");
     cleanup_and_leave(bcx, Some(upto.llbb), Some(target));
 }
 
 pub fn leave_block(bcx: block, out_of: block) -> block {
-    let _icx = bcx.insn_ctxt("leave_block");
+    let _icx = push_ctxt("leave_block");
     let next_cx = sub_block(block_parent(out_of), "next");
     if bcx.unreachable { Unreachable(next_cx); }
     cleanup_and_Br(bcx, out_of, next_cx.llbb);
@@ -1340,7 +1344,7 @@ pub fn with_scope(bcx: block,
                   opt_node_info: Option<NodeInfo>,
                   name: &str,
                   f: &fn(block) -> block) -> block {
-    let _icx = bcx.insn_ctxt("with_scope");
+    let _icx = push_ctxt("with_scope");
 
     debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)",
            bcx.to_str(), opt_node_info, name);
@@ -1355,7 +1359,7 @@ pub fn with_scope_result(bcx: block,
                          opt_node_info: Option<NodeInfo>,
                          name: &str,
                          f: &fn(block) -> Result) -> Result {
-    let _icx = bcx.insn_ctxt("with_scope_result");
+    let _icx = push_ctxt("with_scope_result");
     let scope_cx = scope_block(bcx, opt_node_info, name);
     Br(bcx, scope_cx.llbb);
     let Result {bcx, val} = f(scope_cx);
@@ -1367,7 +1371,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option<NodeInfo>,
                           -> datum::DatumBlock {
     use middle::trans::datum::DatumBlock;
 
-    let _icx = bcx.insn_ctxt("with_scope_result");
+    let _icx = push_ctxt("with_scope_result");
     let scope_cx = scope_block(bcx, opt_node_info, name);
     Br(bcx, scope_cx.llbb);
     let DatumBlock {bcx, datum} = f(scope_cx);
@@ -1389,7 +1393,7 @@ pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) {
 }
 
 pub fn alloc_local(cx: block, local: @ast::local) -> block {
-    let _icx = cx.insn_ctxt("alloc_local");
+    let _icx = push_ctxt("alloc_local");
     let t = node_id_type(cx, local.node.id);
     let simple_name = match local.node.pat.node {
       ast::pat_ident(_, pth, None) => Some(path_to_ident(pth)),
@@ -1411,7 +1415,7 @@ pub fn alloc_local(cx: block, local: @ast::local) -> block {
 
 
 pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block {
-    let _icx = bcx.insn_ctxt("with_cond");
+    let _icx = push_ctxt("with_cond");
     let next_cx = base::sub_block(bcx, "next");
     let cond_cx = base::sub_block(bcx, "cond");
     CondBr(bcx, val, cond_cx.llbb, next_cx.llbb);
@@ -1421,7 +1425,7 @@ pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block {
 }
 
 pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
-    let _icx = cx.insn_ctxt("call_memcpy");
+    let _icx = push_ctxt("call_memcpy");
     let ccx = cx.ccx();
     let key = match ccx.sess.targ_cfg.arch {
         X86 | Arm | Mips => "llvm.memcpy.p0i8.p0i8.i32",
@@ -1437,7 +1441,7 @@ pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a
 }
 
 pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
-    let _icx = bcx.insn_ctxt("memcpy_ty");
+    let _icx = push_ctxt("memcpy_ty");
     let ccx = bcx.ccx();
     if ty::type_is_structural(t) {
         let llty = type_of::type_of(ccx, t);
@@ -1450,7 +1454,7 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
 }
 
 pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) {
-    let _icx = cx.insn_ctxt("zero_mem");
+    let _icx = push_ctxt("zero_mem");
     let bcx = cx;
     let ccx = cx.ccx();
     let llty = type_of::type_of(ccx, t);
@@ -1463,7 +1467,7 @@ pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) {
 // awful. (A telltale sign of this is large quantities of
 // `mov [byte ptr foo],0` in the generated code.)
 pub fn memzero(cx: block, llptr: ValueRef, ty: Type) {
-    let _icx = cx.insn_ctxt("memzero");
+    let _icx = push_ctxt("memzero");
     let ccx = cx.ccx();
 
     let intrinsic_key = match ccx.sess.targ_cfg.arch {
@@ -1481,7 +1485,7 @@ pub fn memzero(cx: block, llptr: ValueRef, ty: Type) {
 }
 
 pub fn alloc_ty(bcx: block, t: ty::t) -> ValueRef {
-    let _icx = bcx.insn_ctxt("alloc_ty");
+    let _icx = push_ctxt("alloc_ty");
     let ccx = bcx.ccx();
     let ty = type_of::type_of(ccx, t);
     assert!(!ty::type_has_params(t), "Type has params: %s", ty_to_str(ccx.tcx, t));
@@ -1494,7 +1498,7 @@ pub fn alloca(cx: block, ty: Type) -> ValueRef {
 }
 
 pub fn alloca_maybe_zeroed(cx: block, ty: Type, zero: bool) -> ValueRef {
-    let _icx = cx.insn_ctxt("alloca");
+    let _icx = push_ctxt("alloca");
     if cx.unreachable {
         unsafe {
             return llvm::LLVMGetUndef(ty.to_ref());
@@ -1507,7 +1511,7 @@ pub fn alloca_maybe_zeroed(cx: block, ty: Type, zero: bool) -> ValueRef {
 }
 
 pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
-    let _icx = cx.insn_ctxt("arrayalloca");
+    let _icx = push_ctxt("arrayalloca");
     if cx.unreachable {
         unsafe {
             return llvm::LLVMGetUndef(ty.to_ref());
@@ -1639,7 +1643,7 @@ pub fn create_llargs_for_fn_args(cx: fn_ctxt,
                                  self_arg: self_arg,
                                  args: &[ast::arg])
                               -> ~[ValueRef] {
-    let _icx = cx.insn_ctxt("create_llargs_for_fn_args");
+    let _icx = push_ctxt("create_llargs_for_fn_args");
 
     match self_arg {
       impl_self(tt) => {
@@ -1687,7 +1691,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
                             args: &[ast::arg],
                             raw_llargs: &[ValueRef],
                             arg_tys: &[ty::t]) -> block {
-    let _icx = fcx.insn_ctxt("copy_args_to_allocas");
+    let _icx = push_ctxt("copy_args_to_allocas");
     let mut bcx = bcx;
 
     match fcx.llself {
@@ -1753,7 +1757,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
 // Ties up the llstaticallocas -> llloadenv -> lltop edges,
 // and builds the return block.
 pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef) {
-    let _icx = fcx.insn_ctxt("finish_fn");
+    let _icx = push_ctxt("finish_fn");
     tie_up_header_blocks(fcx, lltop);
     build_return_block(fcx);
 }
@@ -1771,7 +1775,7 @@ pub fn build_return_block(fcx: fn_ctxt) {
 }
 
 pub fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) {
-    let _icx = fcx.insn_ctxt("tie_up_header_blocks");
+    let _icx = push_ctxt("tie_up_header_blocks");
     match fcx.llloadenv {
         Some(ll) => {
             Br(raw_block(fcx, false, fcx.llstaticallocas), ll);
@@ -1802,7 +1806,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
                      maybe_load_env: &fn(fn_ctxt),
                      finish: &fn(block)) {
     ccx.stats.n_closures += 1;
-    let _icx = ccx.insn_ctxt("trans_closure");
+    let _icx = push_ctxt("trans_closure");
     set_uwtable(llfndecl);
 
     debug!("trans_closure(..., param_substs=%s)",
@@ -1891,7 +1895,7 @@ pub fn trans_fn(ccx: @mut CrateContext,
     debug!("trans_fn(self_arg=%?, param_substs=%s)",
            self_arg,
            param_substs.repr(ccx.tcx));
-    let _icx = ccx.insn_ctxt("trans_fn");
+    let _icx = push_ctxt("trans_fn");
     ccx.stats.n_fns += 1;
     let the_path_str = path_str(ccx.sess, path);
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
@@ -1926,7 +1930,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext,
                           disr: int,
                           param_substs: Option<@param_substs>,
                           llfndecl: ValueRef) {
-    let _icx = ccx.insn_ctxt("trans_enum_variant");
+    let _icx = push_ctxt("trans_enum_variant");
     // Translate variant arguments to function arguments.
     let fn_args = do args.map |varg| {
         ast::arg {
@@ -2000,7 +2004,7 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext,
                           ctor_id: ast::node_id,
                           param_substs: Option<@param_substs>,
                           llfndecl: ValueRef) {
-    let _icx = ccx.insn_ctxt("trans_tuple_struct");
+    let _icx = push_ctxt("trans_tuple_struct");
 
     // Translate struct fields to function arguments.
     let fn_args = do fields.map |field| {
@@ -2086,7 +2090,7 @@ pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def,
 }
 
 pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
-    let _icx = ccx.insn_ctxt("trans_item");
+    let _icx = push_ctxt("trans_item");
     let path = match ccx.tcx.items.get_copy(&item.id) {
         ast_map::node_item(_, p) => p,
         // tjc: ?
@@ -2193,7 +2197,7 @@ pub fn trans_struct_def(ccx: @mut CrateContext, struct_def: @ast::struct_def) {
 // only as a convenience for humans working with the code, to organize names
 // and control visibility.
 pub fn trans_mod(ccx: @mut CrateContext, m: &ast::_mod) {
-    let _icx = ccx.insn_ctxt("trans_mod");
+    let _icx = push_ctxt("trans_mod");
     for m.items.each |item| {
         trans_item(ccx, *item);
     }
@@ -2560,7 +2564,7 @@ pub fn register_method(ccx: @mut CrateContext,
 
 // The constant translation pass.
 pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) {
-    let _icx = ccx.insn_ctxt("trans_constant");
+    let _icx = push_ctxt("trans_constant");
     match it.node {
       ast::item_enum(ref enum_definition, _) => {
         let vi = ty::enum_variants(ccx.tcx,
@@ -2922,19 +2926,13 @@ pub fn trans_crate(sess: session::Session,
 
     let ccx = @mut CrateContext::new(sess, llmod_id, tcx, emap2, maps,
                                  symbol_hasher, link_meta, reachable);
-    // FIXME(#6511): get LLVM building with --enable-threads so this
-    //               function can be called
-    // if !llvm::LLVMRustStartMultithreading() {
-    //     sess.bug("couldn't enable multi-threaded LLVM");
-    // }
-
     {
-        let _icx = ccx.insn_ctxt("data");
+        let _icx = push_ctxt("data");
         trans_constants(ccx, crate);
     }
 
     {
-        let _icx = ccx.insn_ctxt("text");
+        let _icx = push_ctxt("text");
         trans_mod(ccx, &crate.node.module);
     }
 
@@ -2963,6 +2961,12 @@ pub fn trans_crate(sess: session::Session,
         io::println(fmt!("n_closures: %u", ccx.stats.n_closures));
     }
 
+    if ccx.sess.count_llvm_insns() {
+        for ccx.stats.llvm_insns.each |&k, &v| {
+            io::println(fmt!("%-7u %s", v, k));
+        }
+    }
+
     let llcx = ccx.llcx;
     let link_meta = ccx.link_meta;
     let llmod = ccx.llmod;
diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs
index f1ccfba5b30..83c1a3c80db 100644
--- a/src/librustc/middle/trans/build.rs
+++ b/src/librustc/middle/trans/build.rs
@@ -19,6 +19,7 @@ use middle::trans::common::*;
 use middle::trans::machine::llalign_of_min;
 use syntax::codemap::span;
 
+use middle::trans::base;
 use middle::trans::type_::Type;
 
 use core::cast;
@@ -46,10 +47,8 @@ pub fn B(cx: block) -> BuilderRef {
 }
 
 pub fn count_insn(cx: block, category: &str) {
-    if cx.ccx().sess.count_llvm_insns() {
-
+    do base::with_insn_ctxt |v| {
         let h = &mut cx.ccx().stats.llvm_insns;
-        let v : &[~str] = cx.ccx().stats.llvm_insn_ctxt;
 
         // Build version of path with cycles removed.
 
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index c74a2320b5b..0809b1c124e 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -78,7 +78,7 @@ pub struct Callee {
 }
 
 pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
-    let _icx = bcx.insn_ctxt("trans_callee");
+    let _icx = push_ctxt("trans_callee");
     debug!("callee::trans(expr=%s)", expr.repr(bcx.tcx()));
 
     // pick out special kinds of expressions that can be called:
@@ -172,7 +172,7 @@ pub fn trans_fn_ref(bcx: block,
      * with id `def_id` into a function pointer.  This may require
      * monomorphization or inlining. */
 
-    let _icx = bcx.insn_ctxt("trans_fn_ref");
+    let _icx = push_ctxt("trans_fn_ref");
 
     let type_params = node_id_type_params(bcx, ref_id);
     let vtables = node_vtables(bcx, ref_id);
@@ -216,7 +216,7 @@ pub fn trans_fn_ref_with_vtables(
     // - `type_params`: values for each of the fn/method's type parameters
     // - `vtables`: values for each bound on each of the type parameters
 
-    let _icx = bcx.insn_ctxt("trans_fn_ref_with_vtables");
+    let _icx = push_ctxt("trans_fn_ref_with_vtables");
     let ccx = bcx.ccx();
     let tcx = ccx.tcx;
 
@@ -357,7 +357,7 @@ pub fn trans_call(in_cx: block,
                   id: ast::node_id,
                   dest: expr::Dest)
                   -> block {
-    let _icx = in_cx.insn_ctxt("trans_call");
+    let _icx = push_ctxt("trans_call");
     trans_call_inner(in_cx,
                      call_ex.info(),
                      expr_ty(in_cx, f),
@@ -375,7 +375,7 @@ pub fn trans_method_call(in_cx: block,
                          args: CallArgs,
                          dest: expr::Dest)
                          -> block {
-    let _icx = in_cx.insn_ctxt("trans_method_call");
+    let _icx = push_ctxt("trans_method_call");
     debug!("trans_method_call(call_ex=%s, rcvr=%s)",
            call_ex.repr(in_cx.tcx()),
            rcvr.repr(in_cx.tcx()));
@@ -671,7 +671,7 @@ pub fn trans_args(cx: block,
                   autoref_arg: AutorefArg,
                   llargs: &mut ~[ValueRef]) -> block
 {
-    let _icx = cx.insn_ctxt("trans_args");
+    let _icx = push_ctxt("trans_args");
     let mut temp_cleanups = ~[];
     let arg_tys = ty::ty_fn_args(fn_ty);
 
@@ -725,7 +725,7 @@ pub fn trans_arg_expr(bcx: block,
                       temp_cleanups: &mut ~[ValueRef],
                       ret_flag: Option<ValueRef>,
                       autoref_arg: AutorefArg) -> Result {
-    let _icx = bcx.insn_ctxt("trans_arg_expr");
+    let _icx = push_ctxt("trans_arg_expr");
     let ccx = bcx.ccx();
 
     debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s, \
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index 7d7c024640a..613bd86ab91 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -162,12 +162,12 @@ pub fn mk_closure_tys(tcx: ty::ctxt,
 
 pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t)
                   -> Result {
-    let _icx = bcx.insn_ctxt("closure::allocate_cbox");
+    let _icx = push_ctxt("closure::allocate_cbox");
     let ccx = bcx.ccx();
     let tcx = ccx.tcx;
 
     fn nuke_ref_count(bcx: block, llbox: ValueRef) {
-        let _icx = bcx.insn_ctxt("closure::nuke_ref_count");
+        let _icx = push_ctxt("closure::nuke_ref_count");
         // Initialize ref count to arbitrary value for debugging:
         let ccx = bcx.ccx();
         let llbox = PointerCast(bcx, llbox, Type::opaque_box(ccx).ptr_to());
@@ -206,7 +206,7 @@ pub struct ClosureResult {
 pub fn store_environment(bcx: block,
                          bound_values: ~[EnvValue],
                          sigil: ast::Sigil) -> ClosureResult {
-    let _icx = bcx.insn_ctxt("closure::store_environment");
+    let _icx = push_ctxt("closure::store_environment");
     let ccx = bcx.ccx();
     let tcx = ccx.tcx;
 
@@ -260,7 +260,7 @@ pub fn build_closure(bcx0: block,
                      cap_vars: &[moves::CaptureVar],
                      sigil: ast::Sigil,
                      include_ret_handle: Option<ValueRef>) -> ClosureResult {
-    let _icx = bcx0.insn_ctxt("closure::build_closure");
+    let _icx = push_ctxt("closure::build_closure");
     // If we need to, package up the iterator body to call
     let bcx = bcx0;
 
@@ -322,7 +322,7 @@ pub fn load_environment(fcx: fn_ctxt,
                         cap_vars: &[moves::CaptureVar],
                         load_ret_handle: bool,
                         sigil: ast::Sigil) {
-    let _icx = fcx.insn_ctxt("closure::load_environment");
+    let _icx = push_ctxt("closure::load_environment");
 
     let llloadenv = match fcx.llloadenv {
         Some(ll) => ll,
@@ -393,7 +393,7 @@ pub fn trans_expr_fn(bcx: block,
          (fn ptr, env) pair
      */
 
-    let _icx = bcx.insn_ctxt("closure::trans_expr_fn");
+    let _icx = push_ctxt("closure::trans_expr_fn");
 
     let dest_addr = match dest {
         expr::SaveIn(p) => p,
@@ -470,7 +470,7 @@ pub fn make_closure_glue(
         v: ValueRef,
         t: ty::t,
         glue_fn: @fn(block, v: ValueRef, t: ty::t) -> block) -> block {
-    let _icx = cx.insn_ctxt("closure::make_closure_glue");
+    let _icx = push_ctxt("closure::make_closure_glue");
     let bcx = cx;
     let tcx = cx.tcx();
 
@@ -494,7 +494,7 @@ pub fn make_opaque_cbox_take_glue(
     cboxptr: ValueRef)     // ptr to ptr to the opaque closure
     -> block {
     // Easy cases:
-    let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_take_glue");
+    let _icx = push_ctxt("closure::make_opaque_cbox_take_glue");
     match sigil {
         ast::BorrowedSigil => {
             return bcx;
@@ -553,7 +553,7 @@ pub fn make_opaque_cbox_drop_glue(
     sigil: ast::Sigil,
     cboxptr: ValueRef)     // ptr to the opaque closure
     -> block {
-    let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_drop_glue");
+    let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue");
     match sigil {
         ast::BorrowedSigil => bcx,
         ast::ManagedSigil => {
@@ -574,7 +574,7 @@ pub fn make_opaque_cbox_free_glue(
     sigil: ast::Sigil,
     cbox: ValueRef)     // ptr to ptr to the opaque closure
     -> block {
-    let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_free_glue");
+    let _icx = push_ctxt("closure::make_opaque_cbox_free_glue");
     match sigil {
         ast::BorrowedSigil => {
             return bcx;
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index c8b5b00d624..21e173fd0b4 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -101,7 +101,6 @@ pub struct Stats {
     n_monos: uint,
     n_inlines: uint,
     n_closures: uint,
-    llvm_insn_ctxt: ~[~str],
     llvm_insns: HashMap<~str, uint>,
     fn_times: ~[(~str, int)] // (ident, time)
 }
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index b688ca66c2b..e40534773c2 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -19,7 +19,7 @@ use metadata::csearch;
 use middle::const_eval;
 use middle::trans::adt;
 use middle::trans::base;
-use middle::trans::base::get_insn_ctxt;
+use middle::trans::base::push_ctxt;
 use middle::trans::common::*;
 use middle::trans::consts;
 use middle::trans::expr;
@@ -37,7 +37,7 @@ use syntax::{ast, ast_util, ast_map};
 
 pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit)
     -> ValueRef {
-    let _icx = cx.insn_ctxt("trans_lit");
+    let _icx = push_ctxt("trans_lit");
     match lit.node {
       ast::lit_int(i, t) => C_integral(Type::int_from_ty(cx, t), i as u64, true),
       ast::lit_uint(u, t) => C_integral(Type::uint_from_ty(cx, t), u, false),
@@ -249,7 +249,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
 
 fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
     unsafe {
-        let _icx = cx.insn_ctxt("const_expr");
+        let _icx = push_ctxt("const_expr");
         return match e.node {
           ast::expr_lit(lit) => consts::const_lit(cx, e, *lit),
           ast::expr_binary(_, b, e1, e2) => {
@@ -589,7 +589,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef {
 
 pub fn trans_const(ccx: @mut CrateContext, _e: @ast::expr, id: ast::node_id) {
     unsafe {
-        let _icx = ccx.insn_ctxt("trans_const");
+        let _icx = push_ctxt("trans_const");
         let g = base::get_item_val(ccx, id);
         // At this point, get_item_val has already translated the
         // constant's initializer to determine its LLVM type.
diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs
index ee6ead72c1e..715b1c88327 100644
--- a/src/librustc/middle/trans/context.rs
+++ b/src/librustc/middle/trans/context.rs
@@ -162,6 +162,10 @@ impl CrateContext {
                 None
             };
 
+            if sess.count_llvm_insns() {
+                base::init_insn_ctxt()
+            }
+
             CrateContext {
                   sess: sess,
                   llmod: llmod,
@@ -210,7 +214,6 @@ impl CrateContext {
                     n_monos: 0u,
                     n_inlines: 0u,
                     n_closures: 0u,
-                    llvm_insn_ctxt: ~[],
                     llvm_insns: HashMap::new(),
                     fn_times: ~[]
                   },
@@ -234,7 +237,6 @@ impl CrateContext {
             ((end.nsec as int) - (start.nsec as int)) / 1000000;
         self.stats.fn_times.push((name, elapsed));
     }
-
 }
 
 #[unsafe_destructor]
@@ -247,7 +249,6 @@ impl Drop for CrateContext {
 }
 
 fn task_local_llcx_key(_v: @ContextRef) {}
-
 pub fn task_llcx() -> ContextRef {
     let opt = unsafe { local_data::local_data_get(task_local_llcx_key) };
     *opt.expect("task-local LLVMContextRef wasn't ever set!")
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index a9892b34ccd..6be26354db1 100644
--- a/src/librustc/middle/trans/controlflow.rs
+++ b/src/librustc/middle/trans/controlflow.rs
@@ -35,7 +35,7 @@ use syntax::ast_util;
 use syntax::codemap::span;
 
 pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block {
-    let _icx = bcx.insn_ctxt("trans_block");
+    let _icx = push_ctxt("trans_block");
     let mut bcx = bcx;
     do block_locals(b) |local| {
         bcx = alloc_local(bcx, local);
@@ -67,7 +67,7 @@ pub fn trans_if(bcx: block,
            dest.to_str(bcx.ccx()));
     let _indenter = indenter();
 
-    let _icx = bcx.insn_ctxt("trans_if");
+    let _icx = push_ctxt("trans_if");
     let Result {bcx, val: cond_val} =
         expr::trans_to_datum(bcx, cond).to_result();
 
@@ -126,7 +126,7 @@ pub fn join_blocks(parent_bcx: block, in_cxs: &[block]) -> block {
 }
 
 pub fn trans_while(bcx: block, cond: @ast::expr, body: &ast::blk) -> block {
-    let _icx = bcx.insn_ctxt("trans_while");
+    let _icx = push_ctxt("trans_while");
     let next_bcx = sub_block(bcx, "while next");
 
     //            bcx
@@ -168,7 +168,7 @@ pub fn trans_loop(bcx:block,
                   body: &ast::blk,
                   opt_label: Option<ident>)
                -> block {
-    let _icx = bcx.insn_ctxt("trans_loop");
+    let _icx = push_ctxt("trans_loop");
     let next_bcx = sub_block(bcx, "next");
     let body_bcx_in = loop_scope_block(bcx, next_bcx, opt_label, "`loop`",
                                        body.info());
@@ -182,7 +182,7 @@ pub fn trans_log(log_ex: @ast::expr,
                  lvl: @ast::expr,
                  bcx: block,
                  e: @ast::expr) -> block {
-    let _icx = bcx.insn_ctxt("trans_log");
+    let _icx = push_ctxt("trans_log");
     let ccx = bcx.ccx();
     let mut bcx = bcx;
     if ty::type_is_bot(expr_ty(bcx, lvl)) {
@@ -244,7 +244,7 @@ pub fn trans_break_cont(bcx: block,
                         opt_label: Option<ident>,
                         to_end: bool)
                      -> block {
-    let _icx = bcx.insn_ctxt("trans_break_cont");
+    let _icx = push_ctxt("trans_break_cont");
     // Locate closest loop block, outputting cleanup as we go.
     let mut unwind = bcx;
     let mut target;
@@ -298,7 +298,7 @@ pub fn trans_cont(bcx: block, label_opt: Option<ident>) -> block {
 }
 
 pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block {
-    let _icx = bcx.insn_ctxt("trans_ret");
+    let _icx = push_ctxt("trans_ret");
     let mut bcx = bcx;
     let dest = match copy bcx.fcx.loop_ret {
       Some((flagptr, retptr)) => {
@@ -333,7 +333,7 @@ pub fn trans_fail_expr(bcx: block,
                        sp_opt: Option<span>,
                        fail_expr: Option<@ast::expr>)
                     -> block {
-    let _icx = bcx.insn_ctxt("trans_fail_expr");
+    let _icx = push_ctxt("trans_fail_expr");
     let mut bcx = bcx;
     match fail_expr {
         Some(arg_expr) => {
@@ -361,7 +361,7 @@ pub fn trans_fail(bcx: block,
                   sp_opt: Option<span>,
                   fail_str: @str)
                -> block {
-    let _icx = bcx.insn_ctxt("trans_fail");
+    let _icx = push_ctxt("trans_fail");
     let V_fail_str = C_cstr(bcx.ccx(), fail_str);
     return trans_fail_value(bcx, sp_opt, V_fail_str);
 }
@@ -370,7 +370,7 @@ fn trans_fail_value(bcx: block,
                     sp_opt: Option<span>,
                     V_fail_str: ValueRef)
                  -> block {
-    let _icx = bcx.insn_ctxt("trans_fail_value");
+    let _icx = push_ctxt("trans_fail_value");
     let ccx = bcx.ccx();
     let (V_filename, V_line) = match sp_opt {
       Some(sp) => {
@@ -394,7 +394,7 @@ fn trans_fail_value(bcx: block,
 
 pub fn trans_fail_bounds_check(bcx: block, sp: span,
                                index: ValueRef, len: ValueRef) -> block {
-    let _icx = bcx.insn_ctxt("trans_fail_bounds_check");
+    let _icx = push_ctxt("trans_fail_bounds_check");
     let (filename, line) = filename_and_line_num_from_span(bcx, sp);
     let args = ~[filename, line, index, len];
     let bcx = callee::trans_lang_call(
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index 8e25da202cc..32d0f8887b9 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -273,7 +273,7 @@ impl Datum {
          * `store_to()` instead, which will move if possible but copy if
          * neccessary. */
 
-        let _icx = bcx.insn_ctxt("copy_to");
+        let _icx = push_ctxt("copy_to");
 
         if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) {
             return bcx;
@@ -317,7 +317,7 @@ impl Datum {
          * A helper for `copy_to()` which does not check to see if we
          * are copying to/from the same value. */
 
-        let _icx = bcx.insn_ctxt("copy_to_no_check");
+        let _icx = push_ctxt("copy_to_no_check");
         let mut bcx = bcx;
 
         if action == DROP_EXISTING {
@@ -341,7 +341,7 @@ impl Datum {
     //
     pub fn move_to(&self, bcx: block, action: CopyAction, dst: ValueRef)
                    -> block {
-        let _icx = bcx.insn_ctxt("move_to");
+        let _icx = push_ctxt("move_to");
         let mut bcx = bcx;
 
         debug!("move_to(self=%s, action=%?, dst=%s)",
@@ -740,7 +740,7 @@ impl Datum {
                      expr_id: ast::node_id,
                      max: uint)
                      -> DatumBlock {
-        let _icx = bcx.insn_ctxt("autoderef");
+        let _icx = push_ctxt("autoderef");
 
         debug!("autoderef(expr_id=%d, max=%?, self=%?)",
                expr_id, max, self.to_str(bcx.ccx()));
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index c0a3b76aca4..44e571dfb2f 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -451,7 +451,7 @@ fn trans_to_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
 }
 
 fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
-    let _icx = bcx.insn_ctxt("trans_rvalue_datum_unadjusted");
+    let _icx = push_ctxt("trans_rvalue_datum_unadjusted");
 
     trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
 
@@ -502,7 +502,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
 
 fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
     let mut bcx = bcx;
-    let _icx = bcx.insn_ctxt("trans_rvalue_stmt");
+    let _icx = push_ctxt("trans_rvalue_stmt");
 
     if bcx.unreachable {
         return bcx;
@@ -558,7 +558,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
 
 fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
                                dest: Dest) -> block {
-    let _icx = bcx.insn_ctxt("trans_rvalue_dps_unadjusted");
+    let _icx = push_ctxt("trans_rvalue_dps_unadjusted");
     let tcx = bcx.tcx();
 
     trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
@@ -707,7 +707,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
 
 fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr,
                             def: ast::def, dest: Dest) -> block {
-    let _icx = bcx.insn_ctxt("trans_def_dps_unadjusted");
+    let _icx = push_ctxt("trans_def_dps_unadjusted");
     let ccx = bcx.ccx();
 
     let lldest = match dest {
@@ -755,7 +755,7 @@ fn trans_def_datum_unadjusted(bcx: block,
                               ref_expr: @ast::expr,
                               def: ast::def) -> DatumBlock
 {
-    let _icx = bcx.insn_ctxt("trans_def_datum_unadjusted");
+    let _icx = push_ctxt("trans_def_datum_unadjusted");
 
     match def {
         ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
@@ -816,7 +816,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
      * Translates an lvalue expression, always yielding a by-ref
      * datum.  Does not apply any adjustments. */
 
-    let _icx = bcx.insn_ctxt("trans_lval");
+    let _icx = push_ctxt("trans_lval");
     let mut bcx = bcx;
 
     debug!("trans_lvalue(expr=%s)", bcx.expr_to_str(expr));
@@ -855,7 +855,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
         //! Translates `base.field`.
 
         let mut bcx = bcx;
-        let _icx = bcx.insn_ctxt("trans_rec_field");
+        let _icx = push_ctxt("trans_rec_field");
 
         let base_datum = unpack_datum!(bcx, trans_to_datum(bcx, base));
         let repr = adt::represent_type(bcx.ccx(), base_datum.ty);
@@ -878,7 +878,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
                    idx: @ast::expr) -> DatumBlock {
         //! Translates `base[idx]`.
 
-        let _icx = bcx.insn_ctxt("trans_index");
+        let _icx = push_ctxt("trans_index");
         let ccx = bcx.ccx();
         let base_ty = expr_ty(bcx, base);
         let mut bcx = bcx;
@@ -942,7 +942,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
     {
         //! Translates a reference to a path.
 
-        let _icx = bcx.insn_ctxt("trans_def_lvalue");
+        let _icx = push_ctxt("trans_def_lvalue");
         let ccx = bcx.ccx();
         match def {
             ast::def_const(did) => {
@@ -1012,7 +1012,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
 }
 
 pub fn trans_local_var(bcx: block, def: ast::def) -> Datum {
-    let _icx = bcx.insn_ctxt("trans_local_var");
+    let _icx = push_ctxt("trans_local_var");
 
     return match def {
         ast::def_upvar(nid, _, _, _) => {
@@ -1143,7 +1143,7 @@ fn trans_rec_or_struct(bcx: block,
                        id: ast::node_id,
                        dest: Dest) -> block
 {
-    let _icx = bcx.insn_ctxt("trans_rec");
+    let _icx = push_ctxt("trans_rec");
     let bcx = bcx;
 
     let ty = node_id_type(bcx, id);
@@ -1217,7 +1217,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int,
              fields: &[(uint, @ast::expr)],
              optbase: Option<StructBaseInfo>,
              dest: Dest) -> block {
-    let _icx = bcx.insn_ctxt("trans_adt");
+    let _icx = push_ctxt("trans_adt");
     let mut bcx = bcx;
     let addr = match dest {
         Ignore => {
@@ -1263,7 +1263,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int,
 fn trans_immediate_lit(bcx: block, expr: @ast::expr,
                        lit: ast::lit) -> DatumBlock {
     // must not be a string constant, that is a RvalueDpsExpr
-    let _icx = bcx.insn_ctxt("trans_immediate_lit");
+    let _icx = push_ctxt("trans_immediate_lit");
     let ty = expr_ty(bcx, expr);
     immediate_rvalue_bcx(bcx, consts::const_lit(bcx.ccx(), expr, lit), ty)
 }
@@ -1272,7 +1272,7 @@ fn trans_unary_datum(bcx: block,
                      un_expr: @ast::expr,
                      op: ast::unop,
                      sub_expr: @ast::expr) -> DatumBlock {
-    let _icx = bcx.insn_ctxt("trans_unary_datum");
+    let _icx = push_ctxt("trans_unary_datum");
 
     // if deref, would be LvalueExpr
     assert!(op != ast::deref);
@@ -1333,7 +1333,7 @@ fn trans_unary_datum(bcx: block,
                         contents: @ast::expr,
                         contents_ty: ty::t,
                         heap: heap) -> DatumBlock {
-        let _icx = bcx.insn_ctxt("trans_boxed_expr");
+        let _icx = push_ctxt("trans_boxed_expr");
         let base::MallocResult { bcx, box: bx, body } =
             base::malloc_general(bcx, contents_ty, heap);
         add_clean_free(bcx, bx, heap);
@@ -1345,7 +1345,7 @@ fn trans_unary_datum(bcx: block,
 
 fn trans_addr_of(bcx: block, expr: @ast::expr,
                  subexpr: @ast::expr) -> DatumBlock {
-    let _icx = bcx.insn_ctxt("trans_addr_of");
+    let _icx = push_ctxt("trans_addr_of");
     let mut bcx = bcx;
     let sub_datum = unpack_datum!(bcx, trans_to_datum(bcx, subexpr));
     let llval = sub_datum.to_ref_llval(bcx);
@@ -1361,7 +1361,7 @@ fn trans_eager_binop(bcx: block,
                      lhs_datum: &Datum,
                      rhs_datum: &Datum)
                   -> DatumBlock {
-    let _icx = bcx.insn_ctxt("trans_eager_binop");
+    let _icx = push_ctxt("trans_eager_binop");
 
     let lhs = lhs_datum.to_appropriate_llval(bcx);
     let lhs_t = lhs_datum.ty;
@@ -1457,7 +1457,7 @@ fn trans_lazy_binop(bcx: block,
                     op: lazy_binop_ty,
                     a: @ast::expr,
                     b: @ast::expr) -> DatumBlock {
-    let _icx = bcx.insn_ctxt("trans_lazy_binop");
+    let _icx = push_ctxt("trans_lazy_binop");
     let binop_ty = expr_ty(bcx, binop_expr);
     let bcx = bcx;
 
@@ -1503,7 +1503,7 @@ fn trans_binary(bcx: block,
                 lhs: @ast::expr,
                 rhs: @ast::expr) -> DatumBlock
 {
-    let _icx = bcx.insn_ctxt("trans_binary");
+    let _icx = push_ctxt("trans_binary");
 
     match op {
         ast::and => {
@@ -1550,7 +1550,7 @@ fn trans_overloaded_op(bcx: block,
 
 fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type,
             llsrc: ValueRef, signed: bool) -> ValueRef {
-    let _icx = bcx.insn_ctxt("int_cast");
+    let _icx = push_ctxt("int_cast");
     unsafe {
         let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref());
         let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype.to_ref());
@@ -1568,7 +1568,7 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type,
 
 fn float_cast(bcx: block, lldsttype: Type, llsrctype: Type,
               llsrc: ValueRef) -> ValueRef {
-    let _icx = bcx.insn_ctxt("float_cast");
+    let _icx = push_ctxt("float_cast");
     let srcsz = llsrctype.float_width();
     let dstsz = lldsttype.float_width();
     return if dstsz > srcsz {
@@ -1602,7 +1602,7 @@ pub fn cast_type_kind(t: ty::t) -> cast_kind {
 
 fn trans_imm_cast(bcx: block, expr: @ast::expr,
                   id: ast::node_id) -> DatumBlock {
-    let _icx = bcx.insn_ctxt("trans_cast");
+    let _icx = push_ctxt("trans_cast");
     let ccx = bcx.ccx();
 
     let t_out = node_id_type(bcx, id);
@@ -1669,7 +1669,7 @@ fn trans_assign_op(bcx: block,
                    dst: @ast::expr,
                    src: @ast::expr) -> block
 {
-    let _icx = bcx.insn_ctxt("trans_assign_op");
+    let _icx = push_ctxt("trans_assign_op");
     let mut bcx = bcx;
 
     debug!("trans_assign_op(expr=%s)", bcx.expr_to_str(expr));
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 913a857e0fb..2d23942f601 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -188,7 +188,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
                   needs_c_return: bool,
                   arg_builder: wrap_arg_builder,
                   ret_builder: wrap_ret_builder) {
-    let _icx = ccx.insn_ctxt("foreign::build_wrap_fn_");
+    let _icx = push_ctxt("foreign::build_wrap_fn_");
     let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None);
 
     // Patch up the return type if it's not immediate and we're returning via
@@ -274,7 +274,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
 pub fn trans_foreign_mod(ccx: @mut CrateContext,
                          path: &ast_map::path,
                          foreign_mod: &ast::foreign_mod) {
-    let _icx = ccx.insn_ctxt("foreign::trans_foreign_mod");
+    let _icx = push_ctxt("foreign::trans_foreign_mod");
 
     let arch = ccx.sess.targ_cfg.arch;
     let abi = match foreign_mod.abis.for_arch(arch) {
@@ -370,11 +370,11 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
          *     }
          */
 
-        let _icx = ccx.insn_ctxt("foreign::build_shim_fn");
+        let _icx = push_ctxt("foreign::build_shim_fn");
 
         fn build_args(bcx: block, tys: &ShimTypes, llargbundle: ValueRef)
                    -> ~[ValueRef] {
-            let _icx = bcx.insn_ctxt("foreign::shim::build_args");
+            let _icx = push_ctxt("foreign::shim::build_args");
             tys.fn_ty.build_shim_args(bcx, tys.llsig.llarg_tys, llargbundle)
         }
 
@@ -382,7 +382,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
                      tys: &ShimTypes,
                      llargbundle: ValueRef,
                      llretval: ValueRef) {
-            let _icx = bcx.insn_ctxt("foreign::shim::build_ret");
+            let _icx = push_ctxt("foreign::shim::build_ret");
             tys.fn_ty.build_shim_ret(bcx,
                                      tys.llsig.llarg_tys,
                                      tys.ret_def,
@@ -488,7 +488,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
          * account for the Rust modes.
          */
 
-        let _icx = ccx.insn_ctxt("foreign::build_wrap_fn");
+        let _icx = push_ctxt("foreign::build_wrap_fn");
 
         build_wrap_fn_(ccx,
                        tys,
@@ -503,7 +503,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
                       tys: &ShimTypes,
                       llwrapfn: ValueRef,
                       llargbundle: ValueRef) {
-            let _icx = bcx.insn_ctxt("foreign::wrap::build_args");
+            let _icx = push_ctxt("foreign::wrap::build_args");
             let ccx = bcx.ccx();
             let n = tys.llsig.llarg_tys.len();
             for uint::range(0, n) |i| {
@@ -528,7 +528,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
         fn build_ret(bcx: block,
                      shim_types: &ShimTypes,
                      llargbundle: ValueRef) {
-            let _icx = bcx.insn_ctxt("foreign::wrap::build_ret");
+            let _icx = push_ctxt("foreign::wrap::build_ret");
             let arg_count = shim_types.fn_sig.inputs.len();
             for bcx.fcx.llretptr.iter().advance |&retptr| {
                 let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]);
@@ -1155,7 +1155,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
                         body: &ast::blk,
                         llwrapfn: ValueRef,
                         id: ast::node_id) {
-    let _icx = ccx.insn_ctxt("foreign::build_foreign_fn");
+    let _icx = push_ctxt("foreign::build_foreign_fn");
 
     fn build_rust_fn(ccx: @mut CrateContext,
                      path: ast_map::path,
@@ -1163,7 +1163,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
                      body: &ast::blk,
                      id: ast::node_id)
                   -> ValueRef {
-        let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn");
+        let _icx = push_ctxt("foreign::foreign::build_rust_fn");
         let t = ty::node_id_to_type(ccx.tcx, id);
         // XXX: Bad copy.
         let ps = link::mangle_internal_name_by_path(
@@ -1205,11 +1205,11 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
          * one of those types that is passed by pointer in Rust.
          */
 
-        let _icx = ccx.insn_ctxt("foreign::foreign::build_shim_fn");
+        let _icx = push_ctxt("foreign::foreign::build_shim_fn");
 
         fn build_args(bcx: block, tys: &ShimTypes, llargbundle: ValueRef)
                       -> ~[ValueRef] {
-            let _icx = bcx.insn_ctxt("foreign::extern::shim::build_args");
+            let _icx = push_ctxt("foreign::extern::shim::build_args");
             let ccx = bcx.ccx();
             let mut llargvals = ~[];
             let mut i = 0u;
@@ -1284,7 +1284,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
          *    }
          */
 
-        let _icx = ccx.insn_ctxt("foreign::foreign::build_wrap_fn");
+        let _icx = push_ctxt("foreign::foreign::build_wrap_fn");
 
         build_wrap_fn_(ccx,
                        tys,
@@ -1299,7 +1299,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
                       tys: &ShimTypes,
                       llwrapfn: ValueRef,
                       llargbundle: ValueRef) {
-            let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_args");
+            let _icx = push_ctxt("foreign::foreign::wrap::build_args");
             tys.fn_ty.build_wrap_args(bcx,
                                       tys.llsig.llret_ty,
                                       llwrapfn,
@@ -1307,7 +1307,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
         }
 
         fn build_ret(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) {
-            let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_ret");
+            let _icx = push_ctxt("foreign::foreign::wrap::build_ret");
             tys.fn_ty.build_wrap_ret(bcx, tys.llsig.llarg_tys, llargbundle);
             build_return(bcx);
         }
@@ -1329,7 +1329,7 @@ pub fn register_foreign_fn(ccx: @mut CrateContext,
                            node_id: ast::node_id,
                            attrs: &[ast::attribute])
                            -> ValueRef {
-    let _icx = ccx.insn_ctxt("foreign::register_foreign_fn");
+    let _icx = push_ctxt("foreign::register_foreign_fn");
 
     let t = ty::node_id_to_type(ccx.tcx, node_id);
 
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 294d56dcd76..127177118a0 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -45,7 +45,7 @@ use extra::time;
 use syntax::ast;
 
 pub fn trans_free(cx: block, v: ValueRef) -> block {
-    let _icx = cx.insn_ctxt("trans_free");
+    let _icx = push_ctxt("trans_free");
     callee::trans_lang_call(cx,
         cx.tcx().lang_items.free_fn(),
         [PointerCast(cx, v, Type::i8p())],
@@ -53,7 +53,7 @@ pub fn trans_free(cx: block, v: ValueRef) -> block {
 }
 
 pub fn trans_exchange_free(cx: block, v: ValueRef) -> block {
-    let _icx = cx.insn_ctxt("trans_exchange_free");
+    let _icx = push_ctxt("trans_exchange_free");
     callee::trans_lang_call(cx,
         cx.tcx().lang_items.exchange_free_fn(),
         [PointerCast(cx, v, Type::i8p())],
@@ -62,7 +62,7 @@ pub fn trans_exchange_free(cx: block, v: ValueRef) -> block {
 
 pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block {
     // NB: v is an *alias* of type t here, not a direct value.
-    let _icx = cx.insn_ctxt("take_ty");
+    let _icx = push_ctxt("take_ty");
     if ty::type_needs_drop(cx.tcx(), t) {
         return call_tydesc_glue(cx, v, t, abi::tydesc_field_take_glue);
     }
@@ -71,7 +71,7 @@ pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block {
 
 pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block {
     // NB: v is an *alias* of type t here, not a direct value.
-    let _icx = cx.insn_ctxt("drop_ty");
+    let _icx = push_ctxt("drop_ty");
     if ty::type_needs_drop(cx.tcx(), t) {
         return call_tydesc_glue(cx, v, t, abi::tydesc_field_drop_glue);
     }
@@ -79,7 +79,7 @@ pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block {
 }
 
 pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
-    let _icx = bcx.insn_ctxt("drop_ty_immediate");
+    let _icx = push_ctxt("drop_ty_immediate");
     match ty::get(t).sty {
         ty::ty_uniq(_)
       | ty::ty_evec(_, ty::vstore_uniq)
@@ -96,7 +96,7 @@ pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
 }
 
 pub fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> Result {
-    let _icx = bcx.insn_ctxt("take_ty_immediate");
+    let _icx = push_ctxt("take_ty_immediate");
     match ty::get(t).sty {
       ty::ty_box(_) | ty::ty_opaque_box |
       ty::ty_evec(_, ty::vstore_box) |
@@ -117,7 +117,7 @@ pub fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> Result {
 
 pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block {
     // NB: v is an *alias* of type t here, not a direct value.
-    let _icx = cx.insn_ctxt("free_ty");
+    let _icx = push_ctxt("free_ty");
     if ty::type_needs_drop(cx.tcx(), t) {
         return call_tydesc_glue(cx, v, t, abi::tydesc_field_free_glue);
     }
@@ -125,7 +125,7 @@ pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block {
 }
 
 pub fn free_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
-    let _icx = bcx.insn_ctxt("free_ty_immediate");
+    let _icx = push_ctxt("free_ty_immediate");
     match ty::get(t).sty {
       ty::ty_uniq(_) |
       ty::ty_evec(_, ty::vstore_uniq) |
@@ -207,7 +207,7 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
 pub fn lazily_emit_simplified_tydesc_glue(ccx: @mut CrateContext,
                                           field: uint,
                                           ti: @mut tydesc_info) -> bool {
-    let _icx = ccx.insn_ctxt("lazily_emit_simplified_tydesc_glue");
+    let _icx = push_ctxt("lazily_emit_simplified_tydesc_glue");
     let simpl = simplified_glue_type(ccx.tcx, field, ti.ty);
     if simpl != ti.ty {
         let simpl_ti = get_tydesc(ccx, simpl);
@@ -232,7 +232,7 @@ pub fn lazily_emit_simplified_tydesc_glue(ccx: @mut CrateContext,
 pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext,
                                field: uint,
                                ti: @mut tydesc_info) {
-    let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue");
+    let _icx = push_ctxt("lazily_emit_tydesc_glue");
     let llfnty = type_of_glue_fn(ccx);
 
     if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
@@ -300,7 +300,7 @@ pub fn call_tydesc_glue_full(bcx: block,
                              tydesc: ValueRef,
                              field: uint,
                              static_ti: Option<@mut tydesc_info>) {
-    let _icx = bcx.insn_ctxt("call_tydesc_glue_full");
+    let _icx = push_ctxt("call_tydesc_glue_full");
     let ccx = bcx.ccx();
     // NB: Don't short-circuit even if this block is unreachable because
     // GC-based cleanup needs to the see that the roots are live.
@@ -347,14 +347,14 @@ pub fn call_tydesc_glue_full(bcx: block,
 // See [Note-arg-mode]
 pub fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: uint)
     -> block {
-    let _icx = cx.insn_ctxt("call_tydesc_glue");
+    let _icx = push_ctxt("call_tydesc_glue");
     let ti = get_tydesc(cx.ccx(), t);
     call_tydesc_glue_full(cx, v, ti.tydesc, field, Some(ti));
     return cx;
 }
 
 pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) {
-    let _icx = bcx.insn_ctxt("make_visit_glue");
+    let _icx = push_ctxt("make_visit_glue");
     let bcx = do with_scope(bcx, None, "visitor cleanup") |bcx| {
         let mut bcx = bcx;
         let (visitor_trait, object_ty) = ty::visitor_object_ty(bcx.tcx());
@@ -369,7 +369,7 @@ pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) {
 
 pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
     // NB: v0 is an *alias* of type t here, not a direct value.
-    let _icx = bcx.insn_ctxt("make_free_glue");
+    let _icx = push_ctxt("make_free_glue");
     let ccx = bcx.ccx();
     let bcx = match ty::get(t).sty {
       ty::ty_box(body_mt) => {
@@ -461,7 +461,7 @@ pub fn trans_struct_drop(bcx: block,
 
 pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
     // NB: v0 is an *alias* of type t here, not a direct value.
-    let _icx = bcx.insn_ctxt("make_drop_glue");
+    let _icx = push_ctxt("make_drop_glue");
     let ccx = bcx.ccx();
     let bcx = match ty::get(t).sty {
       ty::ty_box(_) | ty::ty_opaque_box |
@@ -532,7 +532,7 @@ pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef,
                               box_ptr_ptr: Option<ValueRef>,
                               t: ty::t)
                            -> block {
-    let _icx = bcx.insn_ctxt("decr_refcnt_maybe_free");
+    let _icx = push_ctxt("decr_refcnt_maybe_free");
     let ccx = bcx.ccx();
 
     do with_cond(bcx, IsNotNull(bcx, box_ptr)) |bcx| {
@@ -551,7 +551,7 @@ pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef,
 
 
 pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) {
-    let _icx = bcx.insn_ctxt("make_take_glue");
+    let _icx = push_ctxt("make_take_glue");
     // NB: v is a *pointer* to type t here, not a direct value.
     let bcx = match ty::get(t).sty {
       ty::ty_box(_) | ty::ty_opaque_box |
@@ -600,7 +600,7 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) {
 }
 
 pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) {
-    let _icx = cx.insn_ctxt("incr_refcnt_of_boxed");
+    let _icx = push_ctxt("incr_refcnt_of_boxed");
     let ccx = cx.ccx();
     let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]);
     let rc = Load(cx, rc_ptr);
@@ -650,7 +650,7 @@ pub type glue_helper = @fn(block, ValueRef, ty::t);
 
 pub fn declare_generic_glue(ccx: @mut CrateContext, t: ty::t, llfnty: Type,
                             name: ~str) -> ValueRef {
-    let _icx = ccx.insn_ctxt("declare_generic_glue");
+    let _icx = push_ctxt("declare_generic_glue");
     let name = name;
     let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, (~"glue_" + name)).to_managed();
     debug!("%s is for type %s", fn_nm, ppaux::ty_to_str(ccx.tcx, t));
@@ -665,7 +665,7 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext,
                                llfn: ValueRef,
                                helper: glue_helper)
                             -> ValueRef {
-    let _icx = ccx.insn_ctxt("make_generic_glue_inner");
+    let _icx = push_ctxt("make_generic_glue_inner");
     let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None);
     lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
     ccx.stats.n_glues_created += 1u;
@@ -695,7 +695,7 @@ pub fn make_generic_glue(ccx: @mut CrateContext,
                          helper: glue_helper,
                          name: &str)
                       -> ValueRef {
-    let _icx = ccx.insn_ctxt("make_generic_glue");
+    let _icx = push_ctxt("make_generic_glue");
     if !ccx.sess.trans_stats() {
         return make_generic_glue_inner(ccx, t, llfn, helper);
     }
@@ -708,7 +708,7 @@ pub fn make_generic_glue(ccx: @mut CrateContext,
 }
 
 pub fn emit_tydescs(ccx: &mut CrateContext) {
-    //let _icx = ccx.insn_ctxt("emit_tydescs");
+    let _icx = push_ctxt("emit_tydescs");
     // As of this point, allow no more tydescs to be created.
     ccx.finished_tydescs = true;
     let glue_fn_ty = Type::generic_glue_fn(ccx);
diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs
index 00afece9197..01849ac6e8f 100644
--- a/src/librustc/middle/trans/inline.rs
+++ b/src/librustc/middle/trans/inline.rs
@@ -12,8 +12,7 @@ use core::prelude::*;
 
 use metadata::csearch;
 use middle::astencode;
-use middle::trans::base::{get_insn_ctxt};
-use middle::trans::base::{impl_owned_self, impl_self, no_self};
+use middle::trans::base::{push_ctxt,impl_owned_self, impl_self, no_self};
 use middle::trans::base::{trans_item, get_item_val, trans_fn};
 use middle::trans::common::*;
 use middle::ty;
@@ -30,7 +29,7 @@ use syntax::ast_util::local_def;
 pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id,
                                 translate: bool)
     -> ast::def_id {
-    let _icx = ccx.insn_ctxt("maybe_instantiate_inline");
+    let _icx = push_ctxt("maybe_instantiate_inline");
     match ccx.external.find(&fn_id) {
         Some(&Some(node_id)) => {
             // Already inline
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 055e1ebbd37..3a8efb55c15 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -51,7 +51,7 @@ pub fn trans_impl(ccx: @mut CrateContext,
                   generics: &ast::Generics,
                   self_ty: Option<ty::t>,
                   id: ast::node_id) {
-    let _icx = ccx.insn_ctxt("impl::trans_impl");
+    let _icx = push_ctxt("impl::trans_impl");
     let tcx = ccx.tcx;
 
     debug!("trans_impl(path=%s, name=%s, self_ty=%s, id=%?)",
@@ -159,7 +159,7 @@ pub fn trans_method(ccx: @mut CrateContext,
 pub fn trans_self_arg(bcx: block,
                       base: @ast::expr,
                       mentry: typeck::method_map_entry) -> Result {
-    let _icx = bcx.insn_ctxt("impl::trans_self_arg");
+    let _icx = push_ctxt("impl::trans_self_arg");
     let mut temp_cleanups = ~[];
 
     // Compute the type of self.
@@ -187,7 +187,7 @@ pub fn trans_method_callee(bcx: block,
                            this: @ast::expr,
                            mentry: typeck::method_map_entry)
                            -> Callee {
-    let _icx = bcx.insn_ctxt("impl::trans_method_callee");
+    let _icx = push_ctxt("impl::trans_method_callee");
     let tcx = bcx.tcx();
 
     debug!("trans_method_callee(callee_id=%?, this=%s, mentry=%s)",
@@ -293,7 +293,7 @@ pub fn trans_static_method_callee(bcx: block,
                                   trait_id: ast::def_id,
                                   callee_id: ast::node_id)
                                -> FnData {
-    let _icx = bcx.insn_ctxt("impl::trans_static_method_callee");
+    let _icx = push_ctxt("impl::trans_static_method_callee");
     let ccx = bcx.ccx();
 
     debug!("trans_static_method_callee(method_id=%?, trait_id=%s, \
@@ -437,7 +437,7 @@ pub fn trans_monomorphized_callee(bcx: block,
                                   n_method: uint,
                                   vtbl: typeck::vtable_origin)
                                   -> Callee {
-    let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee");
+    let _icx = push_ctxt("impl::trans_monomorphized_callee");
     return match vtbl {
       typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
           let ccx = bcx.ccx();
@@ -586,7 +586,7 @@ pub fn trans_trait_callee(bcx: block,
     // first evaluate the self expression (expected a by-ref result) and then
     // extract the self data and vtable out of the pair.
 
-    let _icx = bcx.insn_ctxt("impl::trans_trait_callee");
+    let _icx = push_ctxt("impl::trans_trait_callee");
     let mut bcx = bcx;
     let self_datum = unpack_datum!(bcx,
         expr::trans_to_datum(bcx, self_expr));
@@ -619,7 +619,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
     // Same as `trans_trait_callee()` above, except that it is given
     // a by-ref pointer to the @Trait pair.
 
-    let _icx = bcx.insn_ctxt("impl::trans_trait_callee");
+    let _icx = push_ctxt("impl::trans_trait_callee");
     let ccx = bcx.ccx();
     let mut bcx = bcx;
 
@@ -770,7 +770,7 @@ pub fn make_vtable(ccx: @mut CrateContext,
                    ptrs: &[ValueRef])
                    -> ValueRef {
     unsafe {
-        let _icx = ccx.insn_ctxt("impl::make_vtable");
+        let _icx = push_ctxt("impl::make_vtable");
 
         let mut components = ~[ tydesc.tydesc ];
         for ptrs.each |&ptr| {
@@ -797,7 +797,7 @@ pub fn make_impl_vtable(bcx: block,
                         vtables: typeck::vtable_res)
                         -> ValueRef {
     let ccx = bcx.ccx();
-    let _icx = ccx.insn_ctxt("impl::make_impl_vtable");
+    let _icx = push_ctxt("impl::make_impl_vtable");
     let tcx = ccx.tcx;
 
     let trt_id = match ty::impl_trait_ref(tcx, impl_id) {
@@ -841,7 +841,7 @@ pub fn trans_trait_cast(bcx: block,
                         _store: ty::TraitStore)
                      -> block {
     let mut bcx = bcx;
-    let _icx = bcx.insn_ctxt("impl::trans_cast");
+    let _icx = push_ctxt("impl::trans_cast");
 
     let lldest = match dest {
         Ignore => {
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index f082150e394..17605fdd5be 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -13,9 +13,8 @@ use core::prelude::*;
 use back::link::mangle_exported_name;
 use driver::session;
 use lib::llvm::ValueRef;
-use middle::trans::base::{get_insn_ctxt};
 use middle::trans::base::{set_inline_hint_if_appr, set_inline_hint};
-use middle::trans::base::{trans_enum_variant};
+use middle::trans::base::{trans_enum_variant,push_ctxt};
 use middle::trans::base::{trans_fn, decl_internal_cdecl_fn};
 use middle::trans::base::{get_item_val, no_self};
 use middle::trans::base;
@@ -61,6 +60,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
            ref_id);
 
     assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t)));
+    let _icx = push_ctxt("monomorphic_fn");
     let _icx = ccx.insn_ctxt("monomorphic_fn");
     let mut must_cast = false;
     let substs = vec::map(real_substs.tps, |t| {
diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs
index 014c46b06e4..d7c8c06c707 100644
--- a/src/librustc/middle/trans/tvec.rs
+++ b/src/librustc/middle/trans/tvec.rs
@@ -53,7 +53,7 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t {
 }
 
 pub fn get_fill(bcx: block, vptr: ValueRef) -> ValueRef {
-    let _icx = bcx.insn_ctxt("tvec::get_fill");
+    let _icx = push_ctxt("tvec::get_fill");
     Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill]))
 }
 pub fn set_fill(bcx: block, vptr: ValueRef, fill: ValueRef) {
@@ -68,12 +68,12 @@ pub fn get_bodyptr(bcx: block, vptr: ValueRef) -> ValueRef {
 }
 
 pub fn get_dataptr(bcx: block, vptr: ValueRef) -> ValueRef {
-    let _icx = bcx.insn_ctxt("tvec::get_dataptr");
+    let _icx = push_ctxt("tvec::get_dataptr");
     GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u])
 }
 
 pub fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
-    let _icx = bcx.insn_ctxt("tvec::pointer_add");
+    let _icx = push_ctxt("tvec::pointer_add");
     let old_ty = val_ty(ptr);
     let bptr = PointerCast(bcx, ptr, Type::i8p());
     return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
@@ -81,7 +81,7 @@ pub fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
 
 pub fn alloc_raw(bcx: block, unit_ty: ty::t,
                  fill: ValueRef, alloc: ValueRef, heap: heap) -> Result {
-    let _icx = bcx.insn_ctxt("tvec::alloc_uniq");
+    let _icx = push_ctxt("tvec::alloc_uniq");
     let ccx = bcx.ccx();
 
     let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty);
@@ -105,7 +105,7 @@ pub fn alloc_vec(bcx: block,
                  elts: uint,
                  heap: heap)
               -> Result {
-    let _icx = bcx.insn_ctxt("tvec::alloc_uniq");
+    let _icx = push_ctxt("tvec::alloc_uniq");
     let ccx = bcx.ccx();
     let llunitty = type_of::type_of(ccx, unit_ty);
     let unit_sz = nonzero_llsize_of(ccx, llunitty);
@@ -119,7 +119,7 @@ pub fn alloc_vec(bcx: block,
 }
 
 pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result {
-    let _icx = bcx.insn_ctxt("tvec::duplicate_uniq");
+    let _icx = push_ctxt("tvec::duplicate_uniq");
 
     let fill = get_fill(bcx, get_bodyptr(bcx, vptr));
     let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
@@ -137,7 +137,7 @@ pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result {
 
 pub fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) ->
    block {
-    let _icx = bcx.insn_ctxt("tvec::make_drop_glue_unboxed");
+    let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
     let tcx = bcx.tcx();
     let unit_ty = ty::sequence_element_type(tcx, vec_ty);
     if ty::type_needs_drop(tcx, unit_ty) {
@@ -349,7 +349,7 @@ pub fn write_content(bcx: block,
                      content_expr: @ast::expr,
                      dest: Dest)
                   -> block {
-    let _icx = bcx.insn_ctxt("tvec::write_content");
+    let _icx = push_ctxt("tvec::write_content");
     let mut bcx = bcx;
 
     debug!("write_content(vt=%s, dest=%s, vstore_expr=%?)",
@@ -548,7 +548,7 @@ pub type iter_vec_block<'self> = &'self fn(block, ValueRef, ty::t) -> block;
 
 pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t,
                     fill: ValueRef, f: iter_vec_block) -> block {
-    let _icx = bcx.insn_ctxt("tvec::iter_vec_raw");
+    let _icx = push_ctxt("tvec::iter_vec_raw");
 
     let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
 
@@ -579,14 +579,14 @@ pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t,
 
 pub fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t,
                      fill: ValueRef, f: iter_vec_block) -> block {
-    let _icx = bcx.insn_ctxt("tvec::iter_vec_uniq");
+    let _icx = push_ctxt("tvec::iter_vec_uniq");
     let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr));
     iter_vec_raw(bcx, data_ptr, vec_ty, fill, f)
 }
 
 pub fn iter_vec_unboxed(bcx: block, body_ptr: ValueRef, vec_ty: ty::t,
                         f: iter_vec_block) -> block {
-    let _icx = bcx.insn_ctxt("tvec::iter_vec_unboxed");
+    let _icx = push_ctxt("tvec::iter_vec_unboxed");
     let fill = get_fill(bcx, body_ptr);
     let dataptr = get_dataptr(bcx, body_ptr);
     return iter_vec_raw(bcx, dataptr, vec_ty, fill, f);
diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs
index 4ce2b780011..d27d6efb241 100644
--- a/src/librustc/middle/trans/uniq.rs
+++ b/src/librustc/middle/trans/uniq.rs
@@ -21,7 +21,7 @@ use middle::ty;
 
 pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t)
     -> block {
-    let _icx = bcx.insn_ctxt("uniq::make_free_glue");
+    let _icx = push_ctxt("uniq::make_free_glue");
     let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty);
 
     let not_null = IsNotNull(bcx, box_datum.val);
@@ -38,7 +38,7 @@ pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t)
 }
 
 pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result {
-    let _icx = bcx.insn_ctxt("uniq::duplicate");
+    let _icx = push_ctxt("uniq::duplicate");
 
     // Load the body of the source (*src)
     let src_datum = immediate_rvalue(src_box, src_ty);