Annotation of gcc/halfpic.c, revision 1.1.1.7

1.1       root        1: /* OSF/rose half-pic support functions.
                      2:    Copyright (C) 1992 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
1.1.1.7 ! root       18: the Free Software Foundation, 59 Temple Place - Suite 330,
        !            19: Boston, MA 02111-1307, USA.  */
1.1       root       20: 
                     21: /* The OSF/rose half-pic model assumes that the non-library code does
                     22:    not need to have full PIC (position independent code), but rather,
                     23:    that pointers to external references are put into the data section
1.1.1.3   root       24:    and dereferenced as normal pointers.  References to static data does
1.1       root       25:    not need to be PIC-ized.
                     26: 
                     27:    Another optimization is to have the compiler know what symbols are
                     28:    in the shared libraries, and to only lay down the pointers to
                     29:    things which in the library proper.  */
                     30: 
                     31: #include "config.h"
                     32: 
                     33: #ifdef HALF_PIC_INIT
                     34: 
                     35: #include "tree.h"
                     36: #include "rtl.h"
                     37: #include <stdio.h>
1.1.1.3   root       38: #include "obstack.h"
1.1       root       39: 
1.1.1.3   root       40: #define obstack_chunk_alloc xmalloc
                     41: #define obstack_chunk_free free
                     42: 
                     43: extern char *xmalloc ();
                     44: extern void  free ();
1.1       root       45: extern rtx eliminate_constant_term ();
1.1.1.3   root       46: extern void assemble_name ();
                     47: extern void output_addr_const ();
1.1       root       48: 
1.1.1.5   root       49: int flag_half_pic              = 0;    /* Global half-pic flag.  */
                     50: int half_pic_number_ptrs       = 0;    /* # distinct pointers found */
                     51: int half_pic_number_refs       = 0;    /* # half-pic references */
                     52: int (*ptr_half_pic_address_p)() = half_pic_address_p;
1.1.1.3   root       53: 
                     54: /* Obstack to hold generated pic names.  */
                     55: static struct obstack half_pic_obstack;
                     56: 
                     57: /* List of pointers created to pic references.  */
                     58: 
                     59: struct all_refs {
                     60:   struct all_refs *hash_next;  /* next name in hash chain */
                     61:   struct all_refs *next;       /* next name created */
                     62:   int             external_p;  /* name is an external reference */
                     63:   int             pointer_p;   /* pointer created.  */
                     64:   char           *ref_name;    /* reference name to ptr to real_name */
                     65:   int             ref_len;     /* reference name length */
                     66:   char           *real_name;   /* real function/data name */
                     67:   int             real_len;    /* strlen (real_name) */
                     68: };
                     69: 
                     70: static struct all_refs *half_pic_names;
                     71: 
                     72: static char *half_pic_prefix;
                     73: static int   half_pic_prefix_len;
                     74: 
                     75: 
                     76: /* Return the hash bucket of a name or NULL.  The hash chain is
                     77:    organized as a self reorganizing circularly linked chain.  It is
                     78:    assumed that any name passed to use will never be reallocated.  For
                     79:    names in SYMBOL_REF's this is true, because the names are allocated
                     80:    on the permanent obstack.  */
                     81: 
                     82: #ifndef MAX_HASH_TABLE
                     83: #define MAX_HASH_TABLE 1009
                     84: #endif
                     85: 
                     86: #define HASHBITS 30
                     87: 
                     88: static struct all_refs *
                     89: half_pic_hash (name, len, create_p)
                     90:      char *name;               /* name to hash */
                     91:      int len;                  /* length of the name (or 0 to call strlen) */
                     92:      int create_p;             /* != 0 to create new hash bucket if new */
                     93: {
                     94:   static struct all_refs *hash_table[MAX_HASH_TABLE];
                     95:   static struct all_refs  zero_all_refs;
                     96: 
                     97:   unsigned char *uname;
                     98:   int hash;
                     99:   int i;
                    100:   int ch;
                    101:   struct all_refs *first;
                    102:   struct all_refs *ptr;
                    103: 
                    104:   if (len == 0)
                    105:     len = strlen (name);
                    106: 
                    107:   /* Compute hash code */
                    108:   uname = (unsigned char *)name;
                    109:   ch = uname[0];
                    110:   hash = len * 613 + ch;
                    111:   for (i = 1; i < len; i += 2)
                    112:     hash = (hash * 613) + uname[i];
                    113: 
                    114:   hash &= (1 << HASHBITS) - 1;
                    115:   hash %= MAX_HASH_TABLE;
                    116: 
                    117:   /* See if the name is in the hash table.  */
                    118:   ptr = first = hash_table[hash];
                    119:   if (ptr)
                    120:     {
                    121:       do
                    122:        {
                    123:          if (len == ptr->real_len
                    124:              && ch == *(ptr->real_name)
                    125:              && !strcmp (name, ptr->real_name))
                    126:            {
                    127:              hash_table[hash] = ptr;
                    128:              return ptr;
                    129:            }
                    130: 
                    131:          ptr = ptr->hash_next;
                    132:        }
                    133:       while (ptr != first);
                    134:     }
                    135: 
                    136:   /* name not in hash table.  */
                    137:   if (!create_p)
                    138:     return (struct all_refs *)0;
                    139: 
                    140:   ptr = (struct all_refs *) obstack_alloc (&half_pic_obstack, sizeof (struct all_refs));
                    141:   *ptr = zero_all_refs;
                    142: 
                    143:   ptr->real_name = name;
                    144:   ptr->real_len  = len;
                    145: 
                    146:   /* Update circular links.  */
                    147:   if (first == (struct all_refs *)0)
                    148:     ptr->hash_next = ptr;
                    149: 
                    150:   else
                    151:     {
                    152:       ptr->hash_next = first->hash_next;
                    153:       first->hash_next = ptr;
                    154:     }
                    155: 
                    156:   hash_table[hash] = ptr;
                    157:   return ptr;
                    158: }
1.1       root      159: 
                    160: 
                    161: /* Do any half-pic initializations.  */
                    162: 
                    163: void
                    164: half_pic_init ()
                    165: {
                    166:   flag_half_pic = TRUE;
1.1.1.3   root      167:   half_pic_prefix = HALF_PIC_PREFIX;
                    168:   half_pic_prefix_len = strlen (half_pic_prefix);
                    169:   obstack_init (&half_pic_obstack);
                    170: }
                    171: 
                    172: 
                    173: /* Write out all pointers to pic references.  */
                    174: 
                    175: void
                    176: half_pic_finish (stream)
                    177:      FILE *stream;
                    178: {
                    179:   struct all_refs *p = half_pic_names;
                    180: 
                    181:   if (!p)
                    182:     return;
                    183: 
                    184:   data_section ();
                    185:   for (; p != 0; p = p->next)
                    186:     {
                    187:       /* Emit the pointer if used.  */
                    188:       if (p->pointer_p)
                    189:        {
                    190:          ASM_OUTPUT_LABEL (stream, p->ref_name);
                    191:          ASM_OUTPUT_INT (stream, gen_rtx (SYMBOL_REF, Pmode, p->real_name));
                    192:        }
                    193:     }
1.1       root      194: }
                    195: 
                    196: 
                    197: /* Encode in a declaration whether or not it is half-pic.  */
                    198: 
                    199: void
                    200: half_pic_encode (decl)
                    201:      tree decl;
                    202: {
1.1.1.3   root      203:   enum tree_code code = TREE_CODE (decl);
                    204:   tree asm_name;
                    205:   struct all_refs *ptr;
                    206: 
                    207:   if (!flag_half_pic)
                    208:     return;
                    209: 
                    210:   if (code != VAR_DECL && code != FUNCTION_DECL)
                    211:     return;
                    212: 
                    213:   asm_name = DECL_ASSEMBLER_NAME (decl);
1.1.1.4   root      214: 
1.1.1.3   root      215:   if (!asm_name)
                    216:     return;
                    217: 
1.1.1.4   root      218: #ifdef HALF_PIC_DEBUG
                    219:   if (HALF_PIC_DEBUG)
                    220:     {
                    221:       if (HALF_PIC_DEBUG)
                    222:        fprintf (stderr, "\n========== Half_pic_encode %.*s\n",
                    223:                 IDENTIFIER_LENGTH (asm_name),
                    224:                 IDENTIFIER_POINTER (asm_name));
                    225:       debug_tree (decl);
                    226:     }
                    227: #endif
                    228: 
                    229:   /* If this is not an external reference, it can't be half-pic.  */
                    230:   if (!DECL_EXTERNAL (decl) && (code != VAR_DECL || !TREE_PUBLIC (decl)))
                    231:     return;
                    232: 
1.1.1.3   root      233:   ptr = half_pic_hash (IDENTIFIER_POINTER (asm_name),
                    234:                       IDENTIFIER_LENGTH (asm_name),
                    235:                       TRUE);
                    236: 
                    237:   ptr->external_p = TRUE;
                    238: 
                    239: #ifdef HALF_PIC_DEBUG
                    240:   if (HALF_PIC_DEBUG)
1.1.1.4   root      241:     fprintf (stderr, "\n%.*s is half-pic\n",
1.1.1.3   root      242:             IDENTIFIER_LENGTH (asm_name),
                    243:             IDENTIFIER_POINTER (asm_name));
                    244: #endif
                    245: }
                    246: 
                    247: 
                    248: /* Mark that an object is now local, and no longer needs half-pic.  */
                    249: 
                    250: void
                    251: half_pic_declare (name)
                    252:      char *name;
                    253: {
                    254:   struct all_refs *ptr;
                    255: 
                    256:   if (!flag_half_pic)
                    257:     return;
                    258: 
                    259:   ptr = half_pic_hash (name, 0, FALSE);
                    260:   if (!ptr)
                    261:     return;
                    262: 
                    263:   ptr->external_p = FALSE;
                    264: 
                    265: #ifdef HALF_PIC_DEBUG
                    266:   if (HALF_PIC_DEBUG)
                    267:     fprintf (stderr, "\n========== Half_pic_declare %s\n", name);
1.1       root      268: #endif
                    269: }
                    270: 
                    271: 
1.1.1.6   root      272: /* Mark that an object is explicitly external.  */
                    273: 
                    274: void
                    275: half_pic_external (name)
                    276:      char *name;
                    277: {
                    278:   struct all_refs *ptr;
                    279: 
                    280:   if (!flag_half_pic)
                    281:     return;
                    282: 
                    283:   ptr = half_pic_hash (name, 0, TRUE);
                    284:   if (!ptr)
                    285:     return;
                    286: 
                    287:   ptr->external_p = TRUE;
                    288: 
                    289: #ifdef HALF_PIC_DEBUG
                    290:   if (HALF_PIC_DEBUG)
                    291:     fprintf (stderr, "\n========== Half_pic_external %s\n", name);
                    292: #endif
                    293: }
                    294: 
                    295: 
1.1       root      296: /* Return whether an address is half-pic.  */
                    297: 
                    298: int
                    299: half_pic_address_p (addr)
                    300:      rtx addr;
                    301: {
                    302:   char *name;
1.1.1.3   root      303:   int len;
                    304:   struct all_refs *ptr;
                    305: 
                    306:   if (!flag_half_pic)
                    307:     return FALSE;
1.1       root      308: 
                    309:   switch (GET_CODE (addr))
                    310:     {
1.1.1.3   root      311:     default:
                    312:       break;
                    313: 
1.1       root      314:     case CONST:
1.1.1.2   root      315:       {
                    316:        rtx offset = const0_rtx;
1.1.1.4   root      317:        addr = eliminate_constant_term (XEXP (addr, 0), &offset);
1.1.1.2   root      318:        if (GET_CODE (addr) != SYMBOL_REF)
                    319:          return FALSE;
                    320:       }
1.1       root      321:       /* fall through */
                    322: 
                    323:     case SYMBOL_REF:
                    324:       name = XSTR (addr, 0);
                    325: 
1.1.1.3   root      326: #ifdef HALF_PIC_DEBUG
                    327:       if (HALF_PIC_DEBUG)
                    328:        fprintf (stderr, "\n========== Half_pic_address_p %s\n", name);
                    329: #endif
                    330: 
1.1       root      331:       /* If this is a label, it will have a '*' in front of it.  */
                    332:       if (name[0] == '*')
                    333:        return FALSE;
1.1.1.3   root      334: 
                    335:       /* If this is a reference to the actual half-pic pointer, it
                    336:         is obviously not half-pic.  */
                    337: 
                    338:       len = strlen (name);
                    339:       if (len > half_pic_prefix_len
                    340:          && half_pic_prefix[0] == name[0]
                    341:          && !strncmp (name, half_pic_prefix, half_pic_prefix_len))
                    342:        return FALSE;
                    343: 
                    344:       ptr = half_pic_hash (name, len, FALSE);
                    345:       if (ptr == (struct all_refs *)0)
                    346:        return FALSE;
                    347: 
                    348:       if (ptr->external_p)
                    349:        {
                    350: #ifdef HALF_PIC_DEBUG
                    351:          if (HALF_PIC_DEBUG)
                    352:            fprintf (stderr, "%s is half-pic\n", name);
                    353: #endif
                    354:          return TRUE;
                    355:        }
1.1       root      356:     }
                    357: 
                    358:   return FALSE;
                    359: }
                    360: 
1.1.1.3   root      361: 
                    362: /* Return the name of the pointer to the PIC function, allocating
                    363:    it if need be.  */
                    364: 
                    365: struct rtx_def *
                    366: half_pic_ptr (operand)
                    367:      rtx operand;
                    368: {
                    369:   char *name;
                    370:   struct all_refs *p;
                    371:   int len;
                    372: 
                    373:   if (GET_CODE (operand) != SYMBOL_REF)
                    374:     return operand;
                    375: 
                    376:   name = XSTR (operand, 0);
                    377:   len = strlen (name);
                    378:   p = half_pic_hash (name, len, FALSE);
                    379:   if (p == (struct all_refs *)0 || !p->external_p)
                    380:     return operand;
                    381: 
                    382:   if (!p->pointer_p)
                    383:     {                          /* first time, create pointer */
                    384:       obstack_grow (&half_pic_obstack, half_pic_prefix, half_pic_prefix_len);
                    385:       obstack_grow (&half_pic_obstack, name, len+1);
                    386: 
                    387:       p->next      = half_pic_names;
                    388:       p->ref_name  = (char *) obstack_finish (&half_pic_obstack);
                    389:       p->ref_len   = len + half_pic_prefix_len;
                    390:       p->pointer_p = TRUE;
                    391: 
                    392:       half_pic_names = p;
                    393:       half_pic_number_ptrs++;
                    394:     }
                    395: 
                    396:   half_pic_number_refs++;
                    397:   return gen_rtx (SYMBOL_REF, Pmode, p->ref_name);
                    398: }
                    399: 
1.1       root      400: #endif /* HALF_PIC_INIT */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.