tc-hppa.c: Speed up search for last label
authorJohn David Anglin <danglin@gcc.gnu.org>
Thu, 11 Jun 2015 22:50:39 +0000 (18:50 -0400)
committerJohn David Anglin <danglin@gcc.gnu.org>
Thu, 11 Jun 2015 22:50:39 +0000 (18:50 -0400)
gas/ChangeLog
gas/config/tc-hppa.c

index 4b78a5134e315dbb0cf876371eb90bbc6b7d3205..d9c525d097c49043c874cbfc7b0c49a48f3394ad 100644 (file)
@@ -1,3 +1,11 @@
+2015-06-11  John David Anglin  <danglin@gcc.gnu.org>
+
+       PR gas/18427
+       * gas/config/tc-hppa.c (last_label_symbol): Declare.
+       (pa_get_label): Return last label in current space/segment or NULL.
+       (pa_define_label): Record last label and add to root.
+       (pa_undefine_label): Remove last label from root.
+
 2015-06-08  Nick Clifton  <nickc@redhat.com>
 
        * config/tc-rx.c (rx_op): Correct handling of integer bignums.
index 57d7e96be72c87e462d6ee35b15f19be12b5f358..06e222db0a90193d5269f61dd237b86a80ae3976 100644 (file)
@@ -606,6 +606,9 @@ static int within_procedure;
    seen in each subspace.  */
 static label_symbol_struct *label_symbols_rootp = NULL;
 
+/* Last label symbol */
+static label_symbol_struct last_label_symbol;
+
 /* Nonzero when strict matching is enabled.  Zero otherwise.
 
    Each opcode in the table has a flag which indicates whether or
@@ -1114,19 +1117,17 @@ pa_check_eof (void)
 static label_symbol_struct *
 pa_get_label (void)
 {
-  label_symbol_struct *label_chain;
+  label_symbol_struct *label_chain = label_symbols_rootp;
 
-  for (label_chain = label_symbols_rootp;
-       label_chain;
-       label_chain = label_chain->lss_next)
+  if (label_chain)
     {
 #ifdef OBJ_SOM
-    if (current_space == label_chain->lss_space && label_chain->lss_label)
-      return label_chain;
+      if (current_space == label_chain->lss_space && label_chain->lss_label)
+       return label_chain;
 #endif
 #ifdef OBJ_ELF
-    if (now_seg == label_chain->lss_segment && label_chain->lss_label)
-      return label_chain;
+      if (now_seg == label_chain->lss_segment && label_chain->lss_label)
+       return label_chain;
 #endif
     }
 
@@ -1139,28 +1140,23 @@ pa_get_label (void)
 void
 pa_define_label (symbolS *symbol)
 {
-  label_symbol_struct *label_chain = pa_get_label ();
+  label_symbol_struct *label_chain = label_symbols_rootp;
 
-  if (label_chain)
-    label_chain->lss_label = symbol;
-  else
-    {
-      /* Create a new label entry and add it to the head of the chain.  */
-      label_chain = xmalloc (sizeof (label_symbol_struct));
-      label_chain->lss_label = symbol;
+  if (!label_chain)
+    label_chain = &last_label_symbol;
+
+  label_chain->lss_label = symbol;
 #ifdef OBJ_SOM
-      label_chain->lss_space = current_space;
+  label_chain->lss_space = current_space;
 #endif
 #ifdef OBJ_ELF
-      label_chain->lss_segment = now_seg;
+  label_chain->lss_segment = now_seg;
 #endif
-      label_chain->lss_next = NULL;
 
-      if (label_symbols_rootp)
-       label_chain->lss_next = label_symbols_rootp;
+  /* Not used.  */
+  label_chain->lss_next = NULL;
 
-      label_symbols_rootp = label_chain;
-    }
+  label_symbols_rootp = label_chain;
 
 #ifdef OBJ_ELF
   dwarf2_emit_label (symbol);
@@ -1173,33 +1169,7 @@ pa_define_label (symbolS *symbol)
 static void
 pa_undefine_label (void)
 {
-  label_symbol_struct *label_chain;
-  label_symbol_struct *prev_label_chain = NULL;
-
-  for (label_chain = label_symbols_rootp;
-       label_chain;
-       label_chain = label_chain->lss_next)
-    {
-      if (1
-#ifdef OBJ_SOM
-         && current_space == label_chain->lss_space && label_chain->lss_label
-#endif
-#ifdef OBJ_ELF
-         && now_seg == label_chain->lss_segment && label_chain->lss_label
-#endif
-         )
-       {
-         /* Remove the label from the chain and free its memory.  */
-         if (prev_label_chain)
-           prev_label_chain->lss_next = label_chain->lss_next;
-         else
-           label_symbols_rootp = label_chain->lss_next;
-
-         free (label_chain);
-         break;
-       }
-      prev_label_chain = label_chain;
-    }
+  label_symbols_rootp = NULL;
 }
 
 /* An HPPA-specific version of fix_new.  This is required because the HPPA