diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 94965e7e0dc..1dc9e6b6545 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -305,6 +305,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
         time(time_passes, "resolution", (), |_|
              middle::resolve::resolve_crate(&sess, lang_items, krate));
 
+    // Discard MTWT tables that aren't required past resolution.
+    syntax::ext::mtwt::clear_tables();
+
     let named_region_map = time(time_passes, "lifetime resolution", (),
                                 |_| middle::resolve_lifetime::krate(&sess, krate));
 
@@ -585,6 +588,10 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
         if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
         let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate,
                                                      analysis, &outputs);
+
+        // Discard interned strings as they are no longer required.
+        token::get_ident_interner().clear();
+
         (outputs, trans, tcx.sess)
     };
     phase_5_run_llvm_passes(&sess, &trans, &outputs);
diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs
index 4d96dd75990..b04e1dfd8b5 100644
--- a/src/libsyntax/ext/mtwt.rs
+++ b/src/libsyntax/ext/mtwt.rs
@@ -126,6 +126,15 @@ pub fn display_sctable(table: &SCTable) {
     }
 }
 
+/// Clear the tables from TLD to reclaim memory.
+pub fn clear_tables() {
+    with_sctable(|table| {
+        *table.table.borrow_mut().get() = Vec::new();
+        *table.mark_memo.borrow_mut().get() = HashMap::new();
+        *table.rename_memo.borrow_mut().get() = HashMap::new();
+    });
+    with_resolve_table_mut(|table| *table = HashMap::new());
+}
 
 // Add a value to the end of a vec, return its index
 fn idx_push<T>(vec: &mut Vec<T> , val: T) -> u32 {
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 969c7cec87c..c1ed96fe4de 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -84,6 +84,11 @@ impl<T:Eq + Hash + Freeze + Clone + 'static> Interner<T> {
             None => None,
         }
     }
+
+    pub fn clear(&self) {
+        *self.map.borrow_mut().get() = HashMap::new();
+        *self.vect.borrow_mut().get() = Vec::new();
+    }
 }
 
 #[deriving(Clone, Eq, Hash, Ord)]
@@ -222,6 +227,11 @@ impl StrInterner {
             None => None,
         }
     }
+
+    pub fn clear(&self) {
+        *self.map.borrow_mut().get() = HashMap::new();
+        *self.vect.borrow_mut().get() = Vec::new();
+    }
 }
 
 #[cfg(test)]