moids-size.c

     
   1  //! @file moids-size.c
   2  //! @author J. Marcel van der Veer
   3  //!
   4  //! @section Copyright
   5  //!
   6  //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
   7  //! Copyright 2001-2023 J. Marcel van der Veer [algol68g@xs4all.nl].
   8  //!
   9  //! @section License
  10  //!
  11  //! This program is free software; you can redistribute it and/or modify it 
  12  //! under the terms of the GNU General Public License as published by the 
  13  //! Free Software Foundation; either version 3 of the License, or 
  14  //! (at your option) any later version.
  15  //!
  16  //! This program is distributed in the hope that it will be useful, but 
  17  //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  //! more details. You should have received a copy of the GNU General Public 
  20  //! License along with this program. If not, see [http://www.gnu.org/licenses/].
  21  
  22  //! @section Synopsis
  23  //!
  24  //! Memory footprint (size) of a mode.
  25  
  26  #include "a68g.h"
  27  #include "a68g-prelude.h"
  28  #include "a68g-mp.h"
  29  #include "a68g-genie.h"
  30  #include "a68g-postulates.h"
  31  #include "a68g-parser.h"
  32  #include "a68g-options.h"
  33  #include "a68g-optimiser.h"
  34  #include "a68g-listing.h"
  35  
  36  // Next are routines to calculate the size of a mode.
  37  
  38  //! @brief Max unitings to simplout.
  39  
  40  void max_unitings_to_simplout (NODE_T * p, int *max)
  41  {
  42    for (; p != NO_NODE; FORWARD (p)) {
  43      if (IS (p, UNITING) && MOID (p) == M_SIMPLOUT) {
  44        MOID_T *q = MOID (SUB (p));
  45        if (q != M_SIMPLOUT) {
  46          int size = moid_size (q);
  47          MAXIMISE (*max, size);
  48        }
  49      }
  50      max_unitings_to_simplout (SUB (p), max);
  51    }
  52  }
  53  
  54  //! @brief Get max simplout size.
  55  
  56  void get_max_simplout_size (NODE_T * p)
  57  {
  58    A68 (max_simplout_size) = A68_REF_SIZE;       // For anonymous SKIP
  59    max_unitings_to_simplout (p, &A68 (max_simplout_size));
  60  }
  61  
  62  //! @brief Set moid sizes.
  63  
  64  void set_moid_sizes (MOID_T * z)
  65  {
  66    for (; z != NO_MOID; FORWARD (z)) {
  67      SIZE (z) = moid_size (z);
  68      DIGITS (z) = moid_digits (z);
  69    }
  70  // Next is guaranteed.
  71  #if (A68_LEVEL >= 3)
  72    SIZE (M_LONG_REAL) = moid_size (M_LONG_REAL);
  73    DIGITS (M_LONG_REAL) = 0;
  74  #else
  75    SIZE (M_LONG_REAL) = moid_size (M_LONG_REAL);
  76    DIGITS (M_LONG_REAL) = moid_digits (M_LONG_REAL);
  77  #endif
  78    SIZE (M_LONG_LONG_REAL) = moid_size (M_LONG_LONG_REAL);
  79    DIGITS (M_LONG_LONG_REAL) = moid_digits (M_LONG_LONG_REAL);
  80    SIZEC (M_LONG_COMPLEX) = SIZE (M_LONG_REAL);
  81    SIZEC (M_REF_LONG_COMPLEX) = SIZE (M_LONG_REAL);
  82    DIGITSC (M_LONG_COMPLEX) = DIGITS (M_LONG_REAL);
  83    DIGITSC (M_REF_LONG_COMPLEX) = DIGITS (M_LONG_REAL);
  84    SIZEC (M_LONG_LONG_COMPLEX) = SIZE (M_LONG_LONG_REAL);
  85    SIZEC (M_REF_LONG_LONG_COMPLEX) = SIZE (M_LONG_LONG_REAL);
  86    DIGITSC (M_LONG_LONG_COMPLEX) = DIGITS (M_LONG_LONG_REAL);
  87    DIGITSC (M_REF_LONG_LONG_COMPLEX) = DIGITS (M_LONG_LONG_REAL);
  88  }
  89  
  90  //! @brief Moid size 2.
  91  
  92  int moid_size_2 (MOID_T * p)
  93  {
  94    if (p == NO_MOID) {
  95      return 0;
  96    } else if (EQUIVALENT (p) != NO_MOID) {
  97      return moid_size_2 (EQUIVALENT (p));
  98    } else if (p == M_HIP) {
  99      return 0;
 100    } else if (p == M_VOID) {
 101      return 0;
 102    } else if (p == M_INT) {
 103      return SIZE_ALIGNED (A68_INT);
 104    } else if (p == M_LONG_LONG_INT) {
 105      return (int) size_long_mp ();
 106    } else if (p == M_REAL) {
 107      return SIZE_ALIGNED (A68_REAL);
 108    } else if (p == M_LONG_INT) {
 109  #if (A68_LEVEL >= 3)
 110      return SIZE_ALIGNED (A68_LONG_INT);
 111  #else
 112      return (int) size_mp ();
 113  #endif
 114    } else if (p == M_LONG_REAL) {
 115  #if (A68_LEVEL >= 3)
 116      return SIZE_ALIGNED (A68_LONG_REAL);
 117  #else
 118      return (int) size_mp ();
 119  #endif
 120    } else if (p == M_LONG_BITS) {
 121  #if (A68_LEVEL >= 3)
 122      return SIZE_ALIGNED (A68_LONG_BITS);
 123  #else
 124      return (int) size_mp ();
 125  #endif
 126    } else if (p == M_LONG_LONG_REAL) {
 127      return (int) size_long_mp ();
 128    } else if (p == M_BOOL) {
 129      return SIZE_ALIGNED (A68_BOOL);
 130    } else if (p == M_CHAR) {
 131      return SIZE_ALIGNED (A68_CHAR);
 132    } else if (p == M_ROW_CHAR) {
 133      return A68_REF_SIZE;
 134    } else if (p == M_BITS) {
 135      return SIZE_ALIGNED (A68_BITS);
 136    } else if (p == M_LONG_LONG_BITS) {
 137      return (int) size_long_mp ();
 138    } else if (p == M_BYTES) {
 139      return SIZE_ALIGNED (A68_BYTES);
 140    } else if (p == M_LONG_BYTES) {
 141      return SIZE_ALIGNED (A68_LONG_BYTES);
 142    } else if (p == M_FILE) {
 143      return SIZE_ALIGNED (A68_FILE);
 144    } else if (p == M_CHANNEL) {
 145      return SIZE_ALIGNED (A68_CHANNEL);
 146    } else if (p == M_FORMAT) {
 147      return SIZE_ALIGNED (A68_FORMAT);
 148    } else if (p == M_SEMA) {
 149      return A68_REF_SIZE;
 150    } else if (p == M_SOUND) {
 151      return SIZE_ALIGNED (A68_SOUND);
 152    } else if (p == M_COLLITEM) {
 153      return SIZE_ALIGNED (A68_COLLITEM);
 154    } else if (p == M_HEX_NUMBER) {
 155      int k = 0;
 156      MAXIMISE (k, SIZE_ALIGNED (A68_BOOL));
 157      MAXIMISE (k, SIZE_ALIGNED (A68_CHAR));
 158      MAXIMISE (k, SIZE_ALIGNED (A68_INT));
 159      MAXIMISE (k, SIZE_ALIGNED (A68_REAL));
 160      MAXIMISE (k, SIZE_ALIGNED (A68_BITS));
 161  #if (A68_LEVEL >= 3)
 162      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_INT));
 163      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_REAL));
 164      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_BITS));
 165  #endif
 166      return SIZE_ALIGNED (A68_UNION) + k;
 167    } else if (p == M_NUMBER) {
 168      int k = 0;
 169      MAXIMISE (k, A68_REF_SIZE);
 170      MAXIMISE (k, SIZE_ALIGNED (A68_INT));
 171      MAXIMISE (k, SIZE_ALIGNED (A68_REAL));
 172      MAXIMISE (k, (int) size_long_mp ());
 173  #if (A68_LEVEL >= 3)
 174      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_INT));
 175      MAXIMISE (k, SIZE_ALIGNED (A68_LONG_REAL));
 176  #else
 177      MAXIMISE (k, (int) size_mp ());
 178  #endif
 179      return SIZE_ALIGNED (A68_UNION) + k;
 180    } else if (p == M_SIMPLIN) {
 181      int k = 0;
 182      MAXIMISE (k, A68_REF_SIZE);
 183      MAXIMISE (k, SIZE_ALIGNED (A68_FORMAT));
 184      MAXIMISE (k, SIZE_ALIGNED (A68_PROCEDURE));
 185      MAXIMISE (k, SIZE_ALIGNED (A68_SOUND));
 186      return SIZE_ALIGNED (A68_UNION) + k;
 187    } else if (p == M_SIMPLOUT) {
 188      return SIZE_ALIGNED (A68_UNION) + A68 (max_simplout_size);
 189    } else if (IS_REF (p)) {
 190      return A68_REF_SIZE;
 191    } else if (IS (p, PROC_SYMBOL)) {
 192      return SIZE_ALIGNED (A68_PROCEDURE);
 193    } else if (IS_ROW (p) && p != M_ROWS) {
 194      return A68_REF_SIZE;
 195    } else if (p == M_ROWS) {
 196      return SIZE_ALIGNED (A68_UNION) + A68_REF_SIZE;
 197    } else if (IS_FLEX (p)) {
 198      return moid_size (SUB (p));
 199    } else if (IS_STRUCT (p)) {
 200      PACK_T *z = PACK (p);
 201      int size = 0;
 202      for (; z != NO_PACK; FORWARD (z)) {
 203        size += moid_size (MOID (z));
 204      }
 205      return size;
 206    } else if (IS_UNION (p)) {
 207      PACK_T *z = PACK (p);
 208      int size = 0;
 209      for (; z != NO_PACK; FORWARD (z)) {
 210        if (moid_size (MOID (z)) > size) {
 211          size = moid_size (MOID (z));
 212        }
 213      }
 214      return SIZE_ALIGNED (A68_UNION) + size;
 215    } else if (PACK (p) != NO_PACK) {
 216      PACK_T *z = PACK (p);
 217      int size = 0;
 218      for (; z != NO_PACK; FORWARD (z)) {
 219        size += moid_size (MOID (z));
 220      }
 221      return size;
 222    } else {
 223  // ?
 224      return 0;
 225    }
 226  }
 227  
 228  //! @brief Moid digits 2.
 229  
 230  int moid_digits_2 (MOID_T * p)
 231  {
 232    if (p == NO_MOID) {
 233      return 0;
 234    }
 235    if (EQUIVALENT (p) != NO_MOID) {
 236      return moid_digits_2 (EQUIVALENT (p));
 237    }
 238    if (p == M_LONG_INT) {
 239  #if (A68_LEVEL >= 3)
 240      return 0;
 241  #else
 242      return (int) mp_digits ();
 243  #endif
 244    }
 245    if (p == M_LONG_LONG_INT) {
 246      return (int) long_mp_digits ();
 247    }
 248    if (p == M_LONG_REAL) {
 249      return (int) mp_digits ();
 250    }
 251    if (p == M_LONG_LONG_REAL) {
 252      return (int) long_mp_digits ();
 253    }
 254    if (p == M_LONG_BITS) {
 255  #if (A68_LEVEL >= 3)
 256      return 0;
 257  #else
 258      return (int) mp_digits ();
 259  #endif
 260    }
 261    if (p == M_LONG_LONG_BITS) {
 262      return (int) long_mp_digits ();
 263    } else {
 264      return 0;
 265    }
 266  }
 267  
 268  //! @brief Moid size.
 269  
 270  int moid_size (MOID_T * p)
 271  {
 272    SIZE (p) = A68_ALIGN (moid_size_2 (p));
 273    return SIZE (p);
 274  }
 275  
 276  //! @brief Moid digits.
 277  
 278  int moid_digits (MOID_T * p)
 279  {
 280    DIGITS (p) = moid_digits_2 (p);
 281    return DIGITS (p);
 282  }