Index: lto-streamer-out.c
===================================================================
--- lto-streamer-out.c	(revision 174264)
+++ lto-streamer-out.c	(working copy)
@@ -95,6 +95,7 @@ clear_line_info (struct output_block *ob
   ob->current_file = NULL;
   ob->current_line = 0;
   ob->current_col = 0;
+  ob->location_output_done = 1;
 }
 
 
@@ -587,29 +588,72 @@ pack_value_fields (struct bitpack_d *bp,
 }
 
 
-/* Emit location LOC to output block OB.  */
+/* Output info about new location into bitpack BP.
+   After outputting bitpack, lto_output_location_data has
+   to be done to output actual data.  */
+
+static inline void
+lto_output_location_bitpack (struct bitpack_d *bp,
+			     struct output_block *ob,
+			     location_t loc)
+{
+  gcc_checking_assert (ob->location_output_done);
+  bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
+  if (loc == UNKNOWN_LOCATION)
+    ob->output_file = ob->output_line = ob->output_col = 0;
+  else
+    {
+      expanded_location xloc;
+
+      xloc = expand_location (loc);
+
+      ob->output_file = xloc.file != ob->current_file;
+      ob->output_line = xloc.line != ob->current_line;
+      ob->output_col = xloc.column != ob->current_col;
+    }
+  bp_pack_value (bp, ob->output_file, 1);
+  bp_pack_value (bp, ob->output_line, 1);
+  bp_pack_value (bp, ob->output_col, 1);
+  ob->location_output_done = false;
+}
+
+
+/* Output location info we prepared to output in
+   lto_output_location_bitpack  */
 
 static void
-lto_output_location (struct output_block *ob, location_t loc)
+lto_output_location_data (struct output_block *ob)
 {
-  expanded_location xloc;
+  gcc_checking_assert (!ob->location_output_done);
 
-  if (loc == UNKNOWN_LOCATION)
+  if (ob->output_file)
+    lto_output_string (ob, ob->main_stream, ob->current_file);
+  if (ob->output_line)
     {
-      lto_output_string (ob, ob->main_stream, NULL);
-      return;
+      gcc_checking_assert (ob->current_line >= 0);
+      output_uleb128 (ob, ob->current_line);
     }
+  if (ob->output_col)
+    {
+      gcc_checking_assert (ob->current_col >= 0);
+      output_uleb128 (ob, ob->current_col);
+    }
+  ob->location_output_done = true;
+}
 
-  xloc = expand_location (loc);
 
-  lto_output_string (ob, ob->main_stream, xloc.file);
-  output_sleb128 (ob, xloc.line);
-  output_sleb128 (ob, xloc.column);
-  output_sleb128 (ob, xloc.sysp);
-
-  ob->current_file = xloc.file;
-  ob->current_line = xloc.line;
-  ob->current_col = xloc.column;
+/* Emit location LOC to output block OB.
+   When bitpack is handy, it is more space effecient to call
+   lto_output_location_bitpack and lto_output_location_data directly
+   adding info into the existing bitpack.  */
+
+static void
+lto_output_location (struct output_block *ob, location_t loc)
+{
+  struct bitpack_d bp = bitpack_create (ob->main_stream);
+  lto_output_location_bitpack (&bp, ob, loc);
+  lto_output_bitpack (&bp);
+  lto_output_location_data (ob);
 }
 
 
@@ -642,7 +686,7 @@ lto_output_tree_ref (struct output_block
 
   if (expr == NULL_TREE)
     {
-      output_zero (ob);
+      output_record_start (ob, LTO_null);
       return;
     }
 
Index: lto-streamer-in.c
===================================================================
--- lto-streamer-in.c	(revision 174264)
+++ lto-streamer-in.c	(working copy)
@@ -281,40 +281,69 @@ clear_line_info (struct data_in *data_in
   data_in->current_file = NULL;
   data_in->current_line = 0;
   data_in->current_col = 0;
+  data_in->location_input_done = true;
 }
 
 
-/* Read a location from input block IB.  */
+/* Read a location bitpack from input block IB.  */
+
+static inline void
+lto_input_location_bitpack (struct data_in *data_in, struct bitpack_d *bp)
+{
+  gcc_checking_assert (data_in->location_input_done);
+  data_in->location_input_done = false;
+  data_in->input_unknown_location = bp_unpack_value (bp, 1);
+  data_in->input_file_p = bp_unpack_value (bp, 1);
+  data_in->input_line_p = bp_unpack_value (bp, 1);
+  data_in->input_col_p = bp_unpack_value (bp, 1);
+}
+
+
+/* Read locaiton data we determined to change and update info.  */
 
 static location_t
-lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
+lto_input_location_data (struct lto_input_block *ib, struct data_in *data_in)
 {
-  expanded_location xloc;
+  bool prev_file = data_in->current_file != NULL;
 
-  xloc.file = lto_input_string (data_in, ib);
-  if (xloc.file == NULL)
+  gcc_checking_assert (!data_in->location_input_done);
+  data_in->location_input_done = true;
+  if (data_in->input_unknown_location)
     return UNKNOWN_LOCATION;
+  if (data_in->input_file_p)
+    {
+      data_in->current_file = lto_input_string (data_in, ib);
+      data_in->current_file = canon_file_name (data_in->current_file);
+    }
+  if (data_in->input_line_p)
+    data_in->current_line = lto_input_uleb128 (ib);
+  if (data_in->input_col_p)
+    data_in->current_col = lto_input_uleb128 (ib);
 
-  xloc.file = canon_file_name (xloc.file);
-  xloc.line = lto_input_sleb128 (ib);
-  xloc.column = lto_input_sleb128 (ib);
-  xloc.sysp = lto_input_sleb128 (ib);
-
-  if (data_in->current_file != xloc.file)
+  if (data_in->input_file_p)
     {
-      if (data_in->current_file)
+      if (prev_file)
 	linemap_add (line_table, LC_LEAVE, false, NULL, 0);
 
-      linemap_add (line_table, LC_ENTER, xloc.sysp, xloc.file, xloc.line);
+      linemap_add (line_table, LC_ENTER, false, data_in->current_file, data_in->current_line);
     }
-  else if (data_in->current_line != xloc.line)
-    linemap_line_start (line_table, xloc.line, xloc.column);
+  else if (data_in->input_line_p)
+    linemap_line_start (line_table, data_in->current_line, data_in->current_col);
 
-  data_in->current_file = xloc.file;
-  data_in->current_line = xloc.line;
-  data_in->current_col = xloc.column;
+  return linemap_position_for_column (line_table, data_in->current_col);
+}
+
+
+/* Read a location from input block IB.  */
+
+static location_t
+lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
+{
+  struct bitpack_d bp;
 
-  return linemap_position_for_column (line_table, xloc.column);
+  bp = lto_input_bitpack (ib);
+  lto_input_location_bitpack (data_in, &bp);
+  return lto_input_location_data (ib, data_in);
 }
 
 
Index: lto-streamer.h
===================================================================
--- lto-streamer.h	(revision 174264)
+++ lto-streamer.h	(working copy)
@@ -694,6 +694,10 @@ struct output_block
   const char *current_file;
   int current_line;
   int current_col;
+  unsigned output_file : 1;
+  unsigned output_line : 1;
+  unsigned output_col : 1;
+  unsigned location_output_done : 1;
 
   /* True if writing globals and types.  */
   bool global;
@@ -728,6 +732,11 @@ struct data_in
   const char *current_file;
   int current_line;
   int current_col;
+  unsigned input_unknown_location : 1;
+  unsigned input_file_p : 1;
+  unsigned input_line_p : 1;
+  unsigned input_col_p : 1;
+  unsigned location_input_done : 1;
 
   /* Maps each reference number to the resolution done by the linker. */
   VEC(ld_plugin_symbol_resolution_t,heap) *globals_resolution;
