diff --git a/osprey/ipa/common/ipc_bread.cxx b/osprey/ipa/common/ipc_bread.cxx
index 0e3544e..aec41bc 100644
--- a/osprey/ipa/common/ipc_bread.cxx
+++ b/osprey/ipa/common/ipc_bread.cxx
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.  All Rights Reserved.
+ */
+
+/*
  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
  */
 
@@ -342,6 +346,10 @@ IP_READ_file_info (IP_FILE_HDR& s)
         ErrMsg ( EC_IR_Scn_Read, "dst", IP_FILE_HDR_file_name(s));
     }
     Set_IP_FILE_HDR_dst(s, Current_DST);
+
+#ifndef _LIGHTWEIGHT_INLINER
+    IP_build_global_filelists(s, IP_FILE_HDR_incl_map(s), IP_FILE_HDR_fn_map(s));
+#endif
     remap_dst(s);    
   }
 }
@@ -421,7 +429,7 @@ Count_WN (WN * wn, INT32& bbs, INT32& stmts, INT32& calls)
 
 INT
 IP_READ_fix_tree (PU_Info* pu, WN *node, char *base, Elf64_Word size,
-                  const IPC_GLOBAL_IDX_MAP* idx_map)
+                  const IPC_GLOBAL_IDX_MAP* idx_map, incl_name_map_t& fn_map)
 {
     OPCODE opcode = (OPCODE) WN_opcode (node);
     WN *wn;
@@ -483,7 +491,7 @@ IP_READ_fix_tree (PU_Info* pu, WN *node, char *base, Elf64_Word size,
             WN_last(node) = convert_offset(WN_last(node), base);
 
             do {
-                if (IP_READ_fix_tree (pu, wn, base, size, idx_map) == ERROR_VALUE)
+                if (IP_READ_fix_tree (pu, wn, base, size, idx_map, fn_map) == ERROR_VALUE)
                     return ERROR_VALUE;
                 wn = WN_next(wn);
             } while (wn);
@@ -500,13 +508,30 @@ IP_READ_fix_tree (PU_Info* pu, WN *node, char *base, Elf64_Word size,
             else {
                 wn = convert_offset(wn, base);
                 *wn_ptr = wn;
-                if (IP_READ_fix_tree (pu, wn, base, size, idx_map) == ERROR_VALUE)
+                if (IP_READ_fix_tree (pu, wn, base, size, idx_map, fn_map) == ERROR_VALUE)
                     return ERROR_VALUE;
             }
         }
     }
     
     if (OPCODE_has_next_prev(opcode)) {
+
+        // update STMT SRCPOS file nbr
+        mUINT64 isrcpos = WN_linenum(node);
+        if( SRCPOS_filenum(isrcpos) != 0 ) {
+           UINT32 mapped_fn = fn_map[SRCPOS_filenum(isrcpos)];
+           if (mapped_fn == 0) {
+               DevWarn("mapped file number is zero, node=%p", node);
+               isrcpos = 0;
+           }
+           else
+               SRCPOS_filenum(isrcpos) = mapped_fn;
+           WN_Set_Linenum(node, isrcpos);
+       }
+       else {
+           DevWarn("original source position file nbr is zero, node=%p", node);
+        }
+
         wn = WN_prev(node);
         if (wn == (WN *) -1) {
             WN_prev(node) = NULL;
@@ -548,7 +573,8 @@ IP_READ_fix_tree (PU_Info* pu, WN *node, char *base, Elf64_Word size,
 
 WN *
 IP_READ_get_tree (void *handle, PU_Info *pu,
-                  const IPC_GLOBAL_IDX_MAP* idx_map)
+                  const IPC_GLOBAL_IDX_MAP* idx_map,
+                  incl_name_map_t& fn_map)
 {
     Subsect_State st = PU_Info_state(pu, WT_TREE);
     if (st == Subsect_InMem)
@@ -582,7 +608,7 @@ IP_READ_get_tree (void *handle, PU_Info *pu,
     // Fix up the pointers in the WNs, and remap symbol table indices.
 
     Current_Map_Tab = PU_Info_maptab(pu);
-    if (IP_READ_fix_tree (pu, wn, tree_base, size, idx_map) == ERROR_VALUE)
+    if (IP_READ_fix_tree (pu, wn, tree_base, size, idx_map, fn_map) == ERROR_VALUE)
       return reinterpret_cast<WN*>(ERROR_VALUE);
 
     WN_next(wn) = NULL;
@@ -789,7 +815,10 @@ IP_READ_pu (IPA_NODE* node, IP_FILE_HDR& s, INT p_index, MEM_POOL *pool)
     }
 #endif
 
-    if (IP_READ_get_tree (fhandle, pu, IP_FILE_HDR_idx_maps(s)) == (WN*) -1) {
+    if (IP_READ_get_tree (fhandle,
+                          pu,
+                          IP_FILE_HDR_idx_maps(s),
+                          IP_FILE_HDR_fn_map(s)) == (WN*) -1) {
       ErrMsg ( EC_IR_Scn_Read, "tree", IP_FILE_HDR_file_name(s));
     }
 
diff --git a/osprey/ipa/common/ipc_bwrite.cxx b/osprey/ipa/common/ipc_bwrite.cxx
index e12c49d..c43c5ea 100644
--- a/osprey/ipa/common/ipc_bwrite.cxx
+++ b/osprey/ipa/common/ipc_bwrite.cxx
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.  All Rights Reserved.
+ */
+
+/*
  * Copyright (C) 2007. QLogic Corporation. All Rights Reserved.
  */
 
@@ -154,7 +158,7 @@ extern "C" void IP_write_global_symtab(void)
   PU_Info *pu_tree = NULL;
   if (! dummy_pu_list.empty ()) {
     pu_tree = Write_Dummy_PUs (symtab_file);
-    DST_TYPE merged_dst = IPC_merge_DSTs(pu_tree, Malloc_Mem_Pool);
+    DST_TYPE merged_dst = IPC_merge_DSTs(pu_tree, NULL, Malloc_Mem_Pool);
     // Write a the pu_info tree
     WN_write_PU_Infos (pu_tree, symtab_file);
     WN_write_dst(merged_dst, symtab_file);
@@ -479,6 +483,9 @@ private:
   UINT32 nfiles;
   UINT32 ProMP_next_idx;
 
+  DST_TYPE gbl_file_list;
+
+  BOOL pool_initd;
   MEM_POOL pool;
 
 public:
@@ -504,6 +511,10 @@ public:
   // it closes the output file (if any).
   void flush();
 
+  void build_global_filelists(IP_FILE_HDR& ip_fhdr,
+                              incl_name_map_t& incl_map,
+                              incl_name_map_t& fn_map);
+
 private:
   // Helper function for flush().
   size_t pu_tree_add_comments(size_t index, size_t count, PU_Info* head);
@@ -518,11 +529,13 @@ private:
 // Definitions of output_queue member functions.
 
 output_queue::output_queue()
-  : head(0), tail(0), out_file(0), nfiles(0), ProMP_next_idx (1), pool()
+  : head(0), tail(0), out_file(0), nfiles(0), ProMP_next_idx (1), gbl_file_list(NULL),
+    pool_initd(FALSE),  pool()
 {}
 
 output_queue::~output_queue()
 {
+  if( pool_initd ) MEM_POOL_Pop_Unfreeze(&pool);   // pop global filelist
   Is_True(head == 0, ("IPA output queue has not been flushed"));
 }
 
@@ -608,6 +621,7 @@ void output_queue::push(PU_Info* pu) {
       MEM_POOL_Initialize(&pool, "IPA bwrite mempool", FALSE);
     this->open_output_file();
     MEM_POOL_Push_Freeze(&pool);
+    pool_initd = TRUE;
   }
 
   // Write pu to the file.
@@ -773,7 +787,7 @@ void output_queue::flush() {
 
     // Must call IPC_merge_DSTs before WN_write_PU_Infos, because some
     // indices in the pu tree are updated in the DST merge.
-    DST_TYPE merged_dst = IPC_merge_DSTs(head, &pool);
+    DST_TYPE merged_dst = IPC_merge_DSTs(head, gbl_file_list, &pool);
     WN_write_PU_Infos(head, out_file);
     WN_write_dst(merged_dst, out_file);
 
@@ -827,6 +841,29 @@ void output_queue::close_output_file() {
   out_file = 0;
 }
 
+void
+output_queue::build_global_filelists(IP_FILE_HDR& ip_fhdr,
+                                     incl_name_map_t& incl_map,
+                                     incl_name_map_t& fn_map)
+{
+  if (!pool_initd ) {
+    MEM_POOL_Initialize(&pool, "IPA bwrite mempool", FALSE);
+    pool_initd = TRUE;
+  }
+
+  if( gbl_file_list== NULL ) {
+    DST_Type* gbl_flist;
+    MEM_POOL_Push_Freeze(&pool);
+    gbl_file_list = DST_create(&pool);
+    gbl_flist = (DST_Type*)gbl_file_list;
+    gbl_flist->block_list[DST_include_dirs_block] = DST_include_dirs_block;
+    DST_new_block(gbl_file_list, &pool, DST_include_dirs_block, sizeof(block_header));
+    gbl_flist->block_list[DST_file_names_block] = DST_file_names_block;
+    DST_new_block(gbl_file_list, &pool, DST_file_names_block,sizeof(block_header));
+  }
+
+  Add_files_to_global_file_list(IP_FILE_HDR_dst(ip_fhdr), gbl_file_list, incl_map, fn_map, &pool);
+}
 
 // The global IPA binary output queue.
 output_queue Output_Queue;
@@ -944,3 +981,11 @@ extern "C" void IP_flush_output(void)
 {
   Output_Queue.flush();
 }
+
+#ifndef _LIGHTWEIGHT_INLINER
+void
+IP_build_global_filelists(IP_FILE_HDR& ip_fhdr, incl_name_map_t& incl_map, incl_name_map_t& fn_map)
+{
+  Output_Queue.build_global_filelists(ip_fhdr, incl_map, fn_map);
+}
+#endif
diff --git a/osprey/ipa/common/ipc_bwrite.h b/osprey/ipa/common/ipc_bwrite.h
index c2441c3..b4ab779 100644
--- a/osprey/ipa/common/ipc_bwrite.h
+++ b/osprey/ipa/common/ipc_bwrite.h
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.  All Rights Reserved.
+ */
+
+/*
  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
  */
 
@@ -56,6 +60,13 @@ extern void IP_flush_output(void);
 extern char* IP_global_symtab_name(void);
 extern void IP_write_global_symtab(void);
 
+#ifndef _LIGHTWEIGHT_INLINER
+extern void IP_build_global_filelists(IP_FILE_HDR& ip_fhdr,
+                                      incl_name_map_t& incl_map,
+                                      incl_name_map_t& fn_map);
+
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/osprey/ipa/common/ipc_dst_merge.cxx b/osprey/ipa/common/ipc_dst_merge.cxx
index d3c1941..ae607b8 100644
--- a/osprey/ipa/common/ipc_dst_merge.cxx
+++ b/osprey/ipa/common/ipc_dst_merge.cxx
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.  All Rights Reserved.
+ */
+
+/*
  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
  */
 
@@ -42,6 +46,8 @@
 #include <stdint.h>
 #include <dwarf.h>
 #include <vector>
+#include <map>
+#include <list>
 #include <algorithm>
 
 #include <ext/hash_map>
@@ -206,47 +212,35 @@ void construct_transitive_closure(dst_hash_map& M)
   }
 }
 
-// Merge the include dirs and file names in all of M's DSTs into
-// the output DST output.  This is slightly tricky because file name
-// nodes refer to include directories by ordinal number, and the ordinal
-// number changes in the merge.  We take care of that by copying the
-// directories in the same order as in the original DSTs.  All we need,
-// then, is a per-DST ordinal number offset.
-void merge_directories_and_files(dst_hash_map& M, MEM_POOL* p,
-                                 DST_TYPE output)
+// fix-up the file nbr part of the USRCPOS in DST nodes that contain USRCPOSs
+void
+fix_up_dst_srcpos(DST_TYPE dst, PU_Info *pu_tree)
 {
-  Is_True( DST_IS_NULL(DST_get_include_dirs(output)),
-          ("Output DST already has include dirs"));
-  Is_True( DST_IS_NULL(DST_get_file_names(output)),
-          ("Output DST already has file names"));
+  PU_Info* pu = pu_tree;
   
-  UINT16 prev_include_dirs = 0;
-  DST_IDX cur_include_dir = DST_INVALID_IDX;
-  DST_IDX cur_filename = DST_INVALID_IDX;
-
-  for (dst_hash_map::iterator i = M.begin(); i != M.end(); ++i) {
-    DST_TYPE src = i->first;
-    UINT16 include_dirs_this_dst = 0;
-
-    // Merge in this DST's include dirs.
-    DST_IDX old_dir = DST_get_include_dirs(src);
-    while( !DST_IS_NULL(old_dir) ) {
-      ++include_dirs_this_dst;
-      cur_include_dir =
-        DST_copy_include_dir(src, output, p, cur_include_dir, old_dir);
-      old_dir = DST_INCLUDE_DIR_next(DST_get_include_dir(src, old_dir));
-    }
-
-    // Merge in this DST's filenames.
-    DST_IDX old_file = DST_get_file_names(src);
-    while( !DST_IS_NULL(old_file) ) {
-      cur_filename = DST_copy_filename(src, output, p, cur_filename, old_file,
-                                       prev_include_dirs);
-      old_file = DST_INCLUDE_DIR_next(DST_get_file_name(src, old_file));
-    }
+  while (pu) {
+    if( !DST_IS_NULL(PU_Info_pu_dst(pu)) ) {
 
-    // Add the include dirs we've merged in to the offset
-    prev_include_dirs += include_dirs_this_dst;
+      IP_FILE_HDR& ipa_node = Get_Node_From_PU(pu)->File_Header();
+      incl_name_map_t& fn_map = IP_FILE_HDR_fn_map(ipa_node);
+      DST_INFO* info = DST_get_info(dst, PU_Info_pu_dst(pu));
+      DST_SUBPROGRAM* subprog = DST_get_subprogram_attr(dst, info);
+  
+      if( DST_IS_memdef(DST_INFO_flag(info)) ) {
+        INT32 old_fn = USRCPOS_filenum(DST_SUBPROGRAM_memdef_decl(subprog));
+        USRCPOS_filenum(DST_SUBPROGRAM_memdef_decl(subprog)) = fn_map[old_fn];
+      }
+      else if( DST_IS_declaration(DST_INFO_flag(info)) ) {
+        INT32 old_fn = USRCPOS_filenum(DST_SUBPROGRAM_decl_decl(subprog));
+        USRCPOS_filenum(DST_SUBPROGRAM_decl_decl(subprog)) = fn_map[old_fn];
+      }
+      else { // !DST_IS_declaration && !DST_IS_memdef ==> DST_SUBPR_DEF
+        INT32 old_fn = USRCPOS_filenum(DST_SUBPROGRAM_def_decl(subprog));
+        USRCPOS_filenum(DST_SUBPROGRAM_def_decl(subprog)) = fn_map[old_fn];
+      }
+   }      
+ 
+    pu = pu->next;
   }
 }
 
@@ -368,8 +362,166 @@ void update_pu_dst_indices(dst_hash_map& M, pu_info* pu)
 
 } // Close the unnamed namespace.
 
+typedef std::vector<char*> incl_dir_list_t;
+incl_dir_list_t dir_list;
+typedef std::pair<char*,INT32> fn_dirNbr_t;
+typedef std::vector<fn_dirNbr_t> fn_list_t;
+fn_list_t fn_list;
+
+// NOTE that if the path string is found, we return the entry+1 because the returned
+// value will be used (via the maps) to update the DST structures and the DSTs begin
+// counting at 1
+static INT32
+find_dir_path_in_list(char* str)
+{
+    incl_dir_list_t::iterator i;
+    INT32 cnt = 0;
+
+    for(i = dir_list.begin(); i != dir_list.end(); i++ ) {
+      if( strlen(str) == strlen(*i) && strcmp(str, *i) == 0 ) return cnt+1;
+      cnt++;
+    }
+    return -1;
+}
+
+static INT32
+add_dir_to_list(char* str)
+{
+    dir_list.push_back(str);
+    return dir_list.size();
+}
+
+// NOTE that if the fn_str is found, we return the entry+1 because the returned value
+// will be used (via the maps) to update the DST structures and the DSTs begin counting
+// at 1
+static INT32
+find_fn_in_list(char* fn_str,  char* orig_dir_str)
+{
+    fn_list_t::iterator i;
+    INT32 cnt = 0;
+
+    for(i = fn_list.begin(); i != fn_list.end(); i++ ) {
+      if( strlen(fn_str) == strlen(i->first) && strcmp(fn_str, i->first) == 0 ) {
+        char* new_dir_str = dir_list[i->second-1];
+        if( strlen(orig_dir_str) == strlen(new_dir_str) &&
+            strcmp(orig_dir_str, new_dir_str) == 0 ) {
+          return cnt+1;
+        }
+      }
+      cnt++;
+    }
+    return -1;
+}
+
+static INT32
+add_fn_to_list(char* fn, INT32 dir_nbr)
+{
+    fn_list.push_back(fn_dirNbr_t(fn, dir_nbr));
+    return fn_list.size();
+}
+
+void
+Add_files_to_global_file_list(DST_TYPE src, DST_TYPE dest,
+                              incl_name_map_t& incl_map,
+                              incl_name_map_t& fn_map,
+                              MEM_POOL* p)
+{
+  Is_True( src != NULL, ("Input DST is NULL"));
+  Is_True( dest != NULL, ("Output DST is NULL"));
+
+  DST_IDX wrk_idx = DST_INVALID_IDX;
+  DST_IDX cur_include_dir = DST_INVALID_IDX;
+  DST_IDX cur_filename = DST_INVALID_IDX;
+  INT32 old_fn_nbr = 1;
+  INT32 new_fn_nbr;
+  INT32 old_dir_nbr = 1;
+  INT32 new_dir_nbr;
+
+  // get the last entry in the incl dir list
+  for( wrk_idx = DST_get_include_dirs(dest);
+       !DST_IS_NULL(wrk_idx);
+       wrk_idx = DST_INCLUDE_DIR_next(DST_get_include_dir(dest,wrk_idx)) ){
+    cur_include_dir = wrk_idx;
+  }
+
+  // Add these include paths to the global include paths.
+  DST_IDX old_dir = DST_get_include_dirs(src);
+  if( DST_IS_NULL(DST_get_include_dirs(dest)) ) {
+    DST_set_current_block(dest, ((DST_Type*)dest)->block_list[DST_include_dirs_block]);
+  }
+  while( !DST_IS_NULL(old_dir) ) {
+    DST_INCLUDE_DIR* dir = DST_get_include_dir(src, old_dir);
+    char *dir_str = DST_IDX_to_string(src, DST_INCLUDE_DIR_path(dir));
+
+    if( (new_dir_nbr = find_dir_path_in_list(dir_str)) == -1 ) {
+      cur_include_dir = DST_copy_include_dir(src, dest, p, cur_include_dir, old_dir);
+      new_dir_nbr = add_dir_to_list(dir_str);
+    }
+    old_dir = DST_INCLUDE_DIR_next(DST_get_include_dir(src, old_dir));
+    incl_map[old_dir_nbr] = new_dir_nbr;
+    old_dir_nbr++;
+  }
+
+  // get the last entry in the file list
+  for( wrk_idx = DST_get_file_names(dest);
+       !DST_IS_NULL(wrk_idx);
+       wrk_idx = DST_FILE_NAME_next(DST_get_file_name(dest, wrk_idx)) ) {
+    cur_filename = wrk_idx;
+  }
+
+  // Add these files to the global files
+  DST_IDX old_file = DST_get_file_names(src);
+  if( DST_IS_NULL(DST_get_file_names(dest)) ) {
+    DST_set_current_block(dest, ((DST_Type*)dest)->block_list[DST_file_names_block]);
+  }
+  while( !DST_IS_NULL(old_file) ) {
+    DST_FILE_NAME* fn = DST_get_file_name(src, old_file);
+    char* fn_str = DST_IDX_to_string(src, DST_FILE_NAME_name(fn));
+    UINT16 new_dir_nbr = incl_map[DST_FILE_NAME_dir(fn)];
+    char* src_dir_str = dir_list[new_dir_nbr-1];
+
+    if( (new_fn_nbr = find_fn_in_list(fn_str, src_dir_str)) == -1 ) {
+      cur_filename = DST_copy_filename(src, dest, p, cur_filename, old_file, new_dir_nbr);
+      new_fn_nbr = add_fn_to_list(fn_str, new_dir_nbr);
+    }
+    old_file = DST_FILE_NAME_next(DST_get_file_name(src, old_file));
+    fn_map[old_fn_nbr] = new_fn_nbr;
+    old_fn_nbr++;
+  }
+}
+
+void
+dump_path_file_lists(DST_TYPE dst)
+{
+  DST_IDX idx;
+  UINT64 file_size;
+  UINT64 fmod_time;
+  char *dirname;
+  int i;
+
+  i= 1;
+  idx = DST_get_include_dirs(dst);
+  while( !DST_IS_NULL(idx) ) {
+    DST_INCLUDE_DIR *dir = DST_get_include_dir(dst, idx);
+    fprintf(stderr, "indir[%d]: %s\n", i,  DST_IDX_to_string(dst,
+                                                             DST_INCLUDE_DIR_path(dir)));
+    idx = DST_INCLUDE_DIR_next(dir);
+
+    i++;
+  }
+  i = 1;
+  idx = DST_get_file_names(dst);
+  while( !DST_IS_NULL(idx) ) {
+    DST_FILE_NAME *f = DST_get_file_name(dst, idx);
+    fprintf(stderr, "filename[%d]: %s\n", i, DST_IDX_to_string(dst,
+                                                               DST_FILE_NAME_name(f)));
+    idx = DST_FILE_NAME_next(f);
+    i++;
+  }
+}
+
 // Preconditions: pu_tree isn't null, output is empty.
-DST_TYPE IPC_merge_DSTs(pu_info* pu_tree, MEM_POOL* p) 
+DST_TYPE IPC_merge_DSTs(pu_info* pu_tree, DST_TYPE gbl_dst,  MEM_POOL* p) 
 
 {
   dst_hash_map M(100, DST_TYPE_hash(), std::equal_to<DST_TYPE>(),
@@ -383,8 +535,12 @@ DST_TYPE IPC_merge_DSTs(pu_info* pu_tree, MEM_POOL* p)
   // Create the output DST.
   DST_TYPE output = DST_create(p);
 
-  // Merge the include directories and the file names.
-  merge_directories_and_files(M, p, output);
+  if (gbl_dst != NULL) {
+    // copy the global incl paths and filenames to the output file
+    DST_Type* g =  static_cast<DST_Type*>(gbl_dst);
+    DST_Type* o =  static_cast<DST_Type*>(output);
+    copy_DST_Type(g, o, p);
+  }
 
   // Merge the compile unit and subprogram nodes, updating the
   // entries in the DST map.
@@ -393,5 +549,19 @@ DST_TYPE IPC_merge_DSTs(pu_info* pu_tree, MEM_POOL* p)
   // Update the DST indices in the pu tree.
   update_pu_dst_indices(M, pu_tree);
 
+  // Update the file component of all USRCPOSs in the DSTs
+  fix_up_dst_srcpos(output, pu_tree);
+
+  // Update the file component of all USRCPOSs in the DSTs
+  fix_up_dst_srcpos(output, pu_tree);
+
   return output;
 }
+
+void dump_incl_name_map_t(incl_name_map_t *ptm)
+{
+  printf("size=%lu\n", (unsigned long)ptm->size());
+  for (std::map<int, int, std::less<int>, std::allocator<int> >::iterator it = ptm->begin();
+      it != ptm->end(); it++)
+    printf("%d/%d\n", it->first, it->second);
+}
diff --git a/osprey/ipa/common/ipc_dst_merge.h b/osprey/ipa/common/ipc_dst_merge.h
index c585c65..4ef670f 100644
--- a/osprey/ipa/common/ipc_dst_merge.h
+++ b/osprey/ipa/common/ipc_dst_merge.h
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.  All Rights Reserved.
+ */
+
+/*
  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
  */
 
@@ -50,6 +54,11 @@
 #include "pu_info.h"
 #include "mempool.h"
 
-DST_TYPE IPC_merge_DSTs(pu_info* pu_tree, MEM_POOL* p);
+void Add_files_to_global_file_list(DST_TYPE src, DST_TYPE dest,
+                                   incl_name_map_t& incl_map,
+                                   incl_name_map_t& fn_map,
+                                   MEM_POOL* p);
+DST_TYPE IPC_merge_DSTs(pu_info* pu_tree, DST_TYPE gbl_dst,  MEM_POOL* p);
+void dump_path_file_lists(DST_TYPE gbl_file_list);
 
 #endif /* IPC_DST_MERGE_included */
diff --git a/osprey/ipa/common/ipc_dst_utils.cxx b/osprey/ipa/common/ipc_dst_utils.cxx
index 927a98c..b208cf1 100644
--- a/osprey/ipa/common/ipc_dst_utils.cxx
+++ b/osprey/ipa/common/ipc_dst_utils.cxx
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.  All Rights Reserved.
+ */
+
+/*
  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
  */
 
@@ -87,6 +91,24 @@ DST_IDX DST_get_file_names(DST_TYPE dst_vptr)
     return DST_INVALID_IDX;
 }
 
+void
+copy_DST_Type(DST_TYPE src, DST_TYPE dest, MEM_POOL* p)
+{
+  DST_Type* s = static_cast<DST_Type*>(src);
+  DST_Type* d = static_cast<DST_Type*>(dest);
+  block_header* s_blkhdr;
+  block_header* d_blkhdr;
+  int i;
+
+  for( i = 0; i <= s->last_block_header; i++ ) {
+    s_blkhdr = &s->dst_blocks[i];
+    DST_new_block(dest, p, s_blkhdr->kind, s_blkhdr->allocsize);
+    d_blkhdr = &d->dst_blocks[d->current_block_header];
+    memcpy(d_blkhdr->offset, s_blkhdr->offset, s_blkhdr->size);
+    d_blkhdr->size = s_blkhdr->size;
+  }
+}
+
 //------------------------------------------------------------
 // Low-level functions for initialization and allocation.
 
@@ -305,12 +327,12 @@ DST_IDX DST_copy_filename(DST_TYPE src, DST_TYPE dest,
                           MEM_POOL* p,
                           DST_IDX prev, 
                           DST_IDX old_index,
-                          UINT16 offset)
+                          UINT16 incl_dir_nbr)
 {
   DST_FILE_NAME* f = DST_get_file_name(src, old_index);
   return DST_mk_filename(dest, p,
                          DST_IDX_to_string(src, DST_FILE_NAME_name(f)),
-                         DST_FILE_NAME_dir(f) + offset,
+                         incl_dir_nbr,
                          DST_FILE_NAME_size(f),
                          DST_FILE_NAME_modt(f),
                          prev);
diff --git a/osprey/ipa/common/ipc_dst_utils.h b/osprey/ipa/common/ipc_dst_utils.h
index c22514a..1e3de09 100644
--- a/osprey/ipa/common/ipc_dst_utils.h
+++ b/osprey/ipa/common/ipc_dst_utils.h
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.  All Rights Reserved.
+ */
+
+/*
  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
  */
 
@@ -155,6 +159,12 @@ DST_IDX DST_get_include_dirs(DST_TYPE);
 // exist; if none does, the return value is DST_INVALID_IDX.
 DST_IDX DST_get_file_names(DST_TYPE);
 
+// copy the source DST_Type to the dest DST+_Type
+void copy_DST_Type(DST_TYPE src, DST_TYPE dest, MEM_POOL* p);
+
+// build a new dest block and copy the contents of the src block to it
+void copy_block(DST_TYPE src, DST_TYPE dest, DST_BLOCK_KIND kind, MEM_POOL* p);
+
 // Converts a DST_IDX into a pointer to DST_INFO.  
 inline DST_INFO* DST_get_info(DST_TYPE dst, DST_IDX info_idx) {
   Is_True(dst != 0, ("DST pointer is null"));
diff --git a/osprey/ipa/common/ipc_file.h b/osprey/ipa/common/ipc_file.h
index 7751aff..81c2872 100644
--- a/osprey/ipa/common/ipc_file.h
+++ b/osprey/ipa/common/ipc_file.h
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.  All Rights Reserved.
+ */
+
+/*
  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
  */
 
@@ -50,6 +54,11 @@
 #include "dwarf_DST_mem.h"
 #endif
 
+#include <map>
+
+// used to map debug directory names and file names
+typedef std::map<INT32, INT32, std::less<INT32>, std::allocator<INT32> > incl_name_map_t;
+
 // forward declaration
 
 class SUMMARY_FILE_HEADER;		// see ipl_summary.h
@@ -125,6 +134,8 @@ struct IP_FILE_HDR
     // symbol table related
     FILE_INFO file_info;		// file scope symtab attributes
     DST_TYPE dst;                       // The debug symbol table.
+    incl_name_map_t *incl_map;		// map original file pathnames to new
+    incl_name_map_t *fn_map;		// map original filenames to new
     char *summary;			// section base of summary info
     SUMMARY_FILE_HEADER *file_header;	// header for the summary info
     const IPC_GLOBAL_IDX_MAP *idx_maps;	// maps for merged global symtab
@@ -139,6 +150,8 @@ struct IP_FILE_HDR
 	BZERO (this, sizeof(IP_FILE_HDR));
 	file_name = name;
 	input_map_addr = mmap_addr;
+        incl_map = new incl_name_map_t;
+        fn_map = new incl_name_map_t;
 	MEM_POOL_Initialize (&mem_pool, const_cast<char *> (file_name),
 			     FALSE /* non-zero mempool */);
 	MEM_POOL_Push (&mem_pool);
@@ -276,6 +289,15 @@ Set_IP_FILE_HDR_file_info (IP_FILE_HDR& hdr, FILE_INFO& file_info) {
     hdr.file_info = file_info;
 }
 
+inline incl_name_map_t& IP_FILE_HDR_incl_map( IP_FILE_HDR& h) {
+        return (*h.incl_map);
+}
+
+
+inline incl_name_map_t& IP_FILE_HDR_fn_map( IP_FILE_HDR& h) {
+  return (*h.fn_map);
+}
+
 inline DST_TYPE IP_FILE_HDR_dst(const IP_FILE_HDR& h) {
   return h.dst;
 }
diff --git a/osprey/ipa/main/optimize/ipo_inline.cxx b/osprey/ipa/main/optimize/ipo_inline.cxx
index 8b66b05..497357a 100644
--- a/osprey/ipa/main/optimize/ipo_inline.cxx
+++ b/osprey/ipa/main/optimize/ipo_inline.cxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.  All Rights Reserved.
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.  All Rights Reserved.
  */
 
 /*
@@ -2014,13 +2014,6 @@ void
 IPO_INLINE::Process_Op_Code (TREE_ITER& iter, IPO_INLINE_AUX& aux)
 {
     WN* wn = iter.Wn ();
-#if defined(KEY) && !defined(_STANDALONE_INLINER) && !defined(_LIGHTWEIGHT_INLINER)
-    // bug 3060
-    // Give everything the linenum of the callsite
-    // bug 6170: for lw-inliner, maintain the callee's line# information
-    if (OPERATOR_has_next_prev(WN_operator(wn)))
-      WN_Set_Linenum (wn, WN_Get_Linenum (Call_Wn()));
-#endif // KEY && !_STANDALONE_INLINER && !_LIGHTWEIGHT_INLINER
     OPERATOR oper = WN_operator (wn);
     switch(oper) {
     case OPR_RETURN_VAL:
