Print this page
new smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/example.c
          +++ new/usr/src/tools/smatch/src/example.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18          [OP_BADOP] = "bad_op",
  19   19  
  20   20          /* Fn entrypoint */
  21   21          [OP_ENTRY] = "<entry-point>",
  22   22  
  23   23          /* Terminator */
  24   24          [OP_RET] = "ret",
  25   25          [OP_BR] = "br",
  26   26          [OP_CBR] = "cbr",
  27   27          [OP_SWITCH] = "switch",
  28      -        [OP_INVOKE] = "invoke",
  29   28          [OP_COMPUTEDGOTO] = "jmp *",
  30      -        [OP_UNWIND] = "unwind",
  31   29          
  32   30          /* Binary */
  33   31          [OP_ADD] = "add",
  34   32          [OP_SUB] = "sub",
  35      -        [OP_MULU] = "mulu",
  36      -        [OP_MULS] = "muls",
       33 +        [OP_MUL] = "mul",
  37   34          [OP_DIVU] = "divu",
  38   35          [OP_DIVS] = "divs",
  39   36          [OP_MODU] = "modu",
  40   37          [OP_MODS] = "mods",
  41   38          [OP_SHL] = "shl",
  42   39          [OP_LSR] = "lsr",
  43   40          [OP_ASR] = "asr",
  44   41          
  45   42          /* Logical */
  46   43          [OP_AND] = "and",
  47   44          [OP_OR] = "or",
  48   45          [OP_XOR] = "xor",
  49      -        [OP_AND_BOOL] = "and-bool",
  50      -        [OP_OR_BOOL] = "or-bool",
  51   46  
  52   47          /* Binary comparison */
  53   48          [OP_SET_EQ] = "seteq",
  54   49          [OP_SET_NE] = "setne",
  55   50          [OP_SET_LE] = "setle",
  56   51          [OP_SET_GE] = "setge",
  57   52          [OP_SET_LT] = "setlt",
  58   53          [OP_SET_GT] = "setgt",
  59   54          [OP_SET_B] = "setb",
  60   55          [OP_SET_A] = "seta",
↓ open down ↓ 1 lines elided ↑ open up ↑
  62   57          [OP_SET_AE] = "setae",
  63   58  
  64   59          /* Uni */
  65   60          [OP_NOT] = "not",
  66   61          [OP_NEG] = "neg",
  67   62  
  68   63          /* Special three-input */
  69   64          [OP_SEL] = "select",
  70   65          
  71   66          /* Memory */
  72      -        [OP_MALLOC] = "malloc",
  73      -        [OP_FREE] = "free",
  74      -        [OP_ALLOCA] = "alloca",
  75   67          [OP_LOAD] = "load",
  76   68          [OP_STORE] = "store",
  77   69          [OP_SETVAL] = "set",
  78      -        [OP_GET_ELEMENT_PTR] = "getelem",
  79   70  
  80   71          /* Other */
  81   72          [OP_PHI] = "phi",
  82   73          [OP_PHISOURCE] = "phisrc",
  83   74          [OP_COPY] = "copy",
  84      -        [OP_CAST] = "cast",
  85      -        [OP_SCAST] = "scast",
  86      -        [OP_FPCAST] = "fpcast",
       75 +        [OP_SEXT] = "sext",
       76 +        [OP_ZEXT] = "zext",
       77 +        [OP_TRUNC] = "trunc",
       78 +        [OP_FCVTU] = "fcvtu",
       79 +        [OP_FCVTS] = "fcvts",
       80 +        [OP_UCVTF] = "ucvtf",
       81 +        [OP_SCVTF] = "scvtf",
       82 +        [OP_FCVTF] = "fcvtf",
       83 +        [OP_UTPTR] = "utptr",
       84 +        [OP_PTRTU] = "utptr",
  87   85          [OP_PTRCAST] = "ptrcast",
  88   86          [OP_CALL] = "call",
  89      -        [OP_VANEXT] = "va_next",
  90      -        [OP_VAARG] = "va_arg",
  91   87          [OP_SLICE] = "slice",
  92      -        [OP_SNOP] = "snop",
  93      -        [OP_LNOP] = "lnop",
  94   88          [OP_NOP] = "nop",
  95   89          [OP_DEATHNOTE] = "dead",
  96   90          [OP_ASM] = "asm",
  97   91  
  98   92          /* Sparse tagging (line numbers, context, whatever) */
  99   93          [OP_CONTEXT] = "context",
 100   94  };
 101   95  
 102   96  static int last_reg, stack_offset;
 103   97  
↓ open down ↓ 283 lines elided ↑ open up ↑
 387  381  static void flush_reg(struct bb_state *state, struct hardreg *reg)
 388  382  {
 389  383          pseudo_t pseudo;
 390  384  
 391  385          if (reg->busy)
 392  386                  output_comment(state, "reg %s flushed while busy is %d!", reg->name, reg->busy);
 393  387          if (!reg->contains)
 394  388                  return;
 395  389          reg->dead = 0;
 396  390          reg->used = 1;
 397      -        FOR_EACH_PTR(reg->contains, pseudo) {
      391 +        FOR_EACH_PTR_TAG(reg->contains, pseudo) {
 398  392                  if (CURRENT_TAG(pseudo) & TAG_DEAD)
 399  393                          continue;
 400  394                  if (!(CURRENT_TAG(pseudo) & TAG_DIRTY))
 401  395                          continue;
 402  396                  flush_one_pseudo(state, reg, pseudo);
 403  397          } END_FOR_EACH_PTR(pseudo);
 404  398          free_ptr_list(&reg->contains);
 405  399  }
 406  400  
 407  401  static struct storage_hash *find_pseudo_storage(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
↓ open down ↓ 32 lines elided ↑ open up ↑
 440  434                  }
 441  435                  alloc_stack(state, src->storage);
 442  436          }
 443  437          return src;
 444  438  }
 445  439  
 446  440  static void mark_reg_dead(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
 447  441  {
 448  442          pseudo_t p;
 449  443  
 450      -        FOR_EACH_PTR(reg->contains, p) {
      444 +        FOR_EACH_PTR_TAG(reg->contains, p) {
 451  445                  if (p != pseudo)
 452  446                          continue;
 453  447                  if (CURRENT_TAG(p) & TAG_DEAD)
 454  448                          continue;
 455  449                  output_comment(state, "marking pseudo %s in reg %s dead", show_pseudo(pseudo), reg->name);
 456  450                  TAG_CURRENT(p, TAG_DEAD);
 457  451                  reg->dead++;
 458  452          } END_FOR_EACH_PTR(p);
 459  453  }
 460  454  
↓ open down ↓ 64 lines elided ↑ open up ↑
 525  519  
 526  520  static struct hardreg *find_in_reg(struct bb_state *state, pseudo_t pseudo)
 527  521  {
 528  522          int i;
 529  523          struct hardreg *reg;
 530  524  
 531  525          for (i = 0; i < REGNO; i++) {
 532  526                  pseudo_t p;
 533  527  
 534  528                  reg = hardregs + i;
 535      -                FOR_EACH_PTR(reg->contains, p) {
      529 +                FOR_EACH_PTR_TAG(reg->contains, p) {
 536  530                          if (p == pseudo) {
 537  531                                  last_reg = i;
 538  532                                  output_comment(state, "found pseudo %s in reg %s (busy=%d)", show_pseudo(pseudo), reg->name, reg->busy);
 539  533                                  return reg;
 540  534                          }
 541  535                  } END_FOR_EACH_PTR(p);
 542  536          }
 543  537          return NULL;
 544  538  }
 545  539  
↓ open down ↓ 319 lines elided ↑ open up ↑
 865  859          default:
 866  860                  return getreg(state, pseudo, NULL)->name;
 867  861          }
 868  862  }
 869  863  
 870  864  static void kill_dead_reg(struct hardreg *reg)
 871  865  {
 872  866          if (reg->dead) {
 873  867                  pseudo_t p;
 874  868                  
 875      -                FOR_EACH_PTR(reg->contains, p) {
      869 +                FOR_EACH_PTR_TAG(reg->contains, p) {
 876  870                          if (CURRENT_TAG(p) & TAG_DEAD) {
 877  871                                  DELETE_CURRENT_PTR(p);
 878  872                                  reg->dead--;
 879  873                          }
 880  874                  } END_FOR_EACH_PTR(p);
 881  875                  PACK_PTR_LIST(&reg->contains);
 882  876                  assert(!reg->dead);
 883  877          }
 884  878  }
 885  879  
↓ open down ↓ 19 lines elided ↑ open up ↑
 905  899  
 906  900  static void generate_binop(struct bb_state *state, struct instruction *insn)
 907  901  {
 908  902          flush_cc_cache(state);
 909  903          do_binop(state, insn, insn->src1, insn->src2);
 910  904  }
 911  905  
 912  906  static int is_dead_reg(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
 913  907  {
 914  908          pseudo_t p;
 915      -        FOR_EACH_PTR(reg->contains, p) {
      909 +        FOR_EACH_PTR_TAG(reg->contains, p) {
 916  910                  if (p == pseudo)
 917  911                          return CURRENT_TAG(p) & TAG_DEAD;
 918  912          } END_FOR_EACH_PTR(p);
 919  913          return 0;
 920  914  }
 921  915  
 922  916  /*
 923  917   * Commutative binops are much more flexible, since we can switch the
 924  918   * sources around to satisfy the target register, or to avoid having
 925  919   * to load one of them into a register..
↓ open down ↓ 74 lines elided ↑ open up ↑
1000  994  static void kill_pseudo(struct bb_state *state, pseudo_t pseudo)
1001  995  {
1002  996          int i;
1003  997          struct hardreg *reg;
1004  998  
1005  999          output_comment(state, "killing pseudo %s", show_pseudo(pseudo));
1006 1000          for (i = 0; i < REGNO; i++) {
1007 1001                  pseudo_t p;
1008 1002  
1009 1003                  reg = hardregs + i;
1010      -                FOR_EACH_PTR(reg->contains, p) {
     1004 +                FOR_EACH_PTR_TAG(reg->contains, p) {
1011 1005                          if (p != pseudo)
1012 1006                                  continue;
1013 1007                          if (CURRENT_TAG(p) & TAG_DEAD)
1014 1008                                  reg->dead--;
1015 1009                          output_comment(state, "removing pseudo %s from reg %s", 
1016 1010                                  show_pseudo(pseudo), reg->name);
1017 1011                          DELETE_CURRENT_PTR(p);
1018 1012                  } END_FOR_EACH_PTR(p);
1019 1013                  PACK_PTR_LIST(&reg->contains);
1020 1014          }
↓ open down ↓ 376 lines elided ↑ open up ↑
1397 1391                  break;
1398 1392  
1399 1393          case OP_DEATHNOTE:
1400 1394                  mark_pseudo_dead(state, insn->target);
1401 1395                  return;
1402 1396  
1403 1397          case OP_COPY:
1404 1398                  generate_copy(state, insn);
1405 1399                  break;
1406 1400  
1407      -        case OP_ADD: case OP_MULU: case OP_MULS:
     1401 +        case OP_ADD: case OP_MUL:
1408 1402          case OP_AND: case OP_OR: case OP_XOR:
1409      -        case OP_AND_BOOL: case OP_OR_BOOL:
1410 1403                  generate_commutative_binop(state, insn);
1411 1404                  break;
1412 1405  
1413 1406          case OP_SUB: case OP_DIVU: case OP_DIVS:
1414 1407          case OP_MODU: case OP_MODS:
1415 1408          case OP_SHL: case OP_LSR: case OP_ASR:
1416 1409                  generate_binop(state, insn);
1417 1410                  break;
1418 1411  
1419 1412          case OP_BINCMP ... OP_BINCMP_END:
1420 1413                  generate_compare(state, insn);
1421 1414                  break;
1422 1415  
1423      -        case OP_CAST: case OP_SCAST: case OP_FPCAST: case OP_PTRCAST:
     1416 +        case OP_SEXT: case OP_ZEXT:
     1417 +        case OP_TRUNC:
     1418 +        case OP_PTRCAST:
     1419 +        case OP_UTPTR:
     1420 +        case OP_PTRTU:
     1421 +        case OP_FCVTU: case OP_FCVTS:
     1422 +        case OP_UCVTF: case OP_SCVTF:
     1423 +        case OP_FCVTF:
1424 1424                  generate_cast(state, insn);
1425 1425                  break;
1426 1426  
1427 1427          case OP_SEL:
1428 1428                  generate_select(state, insn);
1429 1429                  break;
1430 1430  
1431 1431          case OP_BR:
1432 1432          case OP_CBR:
1433 1433                  generate_branch(state, insn);
↓ open down ↓ 103 lines elided ↑ open up ↑
1537 1537                  }
1538 1538          default:
1539 1539                  break;
1540 1540          }
1541 1541  
1542 1542          /* See if we have that pseudo in a register.. */
1543 1543          for (i = 0; i < REGNO; i++) {
1544 1544                  struct hardreg *reg = hardregs + i;
1545 1545                  pseudo_t p;
1546 1546  
1547      -                FOR_EACH_PTR(reg->contains, p) {
     1547 +                FOR_EACH_PTR_TAG(reg->contains, p) {
1548 1548                          if (p == pseudo) {
1549 1549                                  write_reg_to_storage(state, reg, pseudo, out);
1550 1550                                  return;
1551 1551                          }
1552 1552                  } END_FOR_EACH_PTR(p);
1553 1553          }
1554 1554  
1555 1555          /* Do we have it in another storage? */
1556 1556          in = find_storage_hash(pseudo, state->internal);
1557 1557          if (!in) {
↓ open down ↓ 87 lines elided ↑ open up ↑
1645 1645  
1646 1646          /* Go through the fixed outputs, making sure we have those regs free */
1647 1647          FOR_EACH_PTR(state->outputs, entry) {
1648 1648                  struct storage *out = entry->storage;
1649 1649                  if (out->type == REG_REG) {
1650 1650                          struct hardreg *reg = hardregs + out->regno;
1651 1651                          pseudo_t p;
1652 1652                          int flushme = 0;
1653 1653  
1654 1654                          reg->busy = REG_FIXED;
1655      -                        FOR_EACH_PTR(reg->contains, p) {
     1655 +                        FOR_EACH_PTR_TAG(reg->contains, p) {
1656 1656                                  if (p == entry->pseudo) {
1657 1657                                          flushme = -100;
1658 1658                                          continue;
1659 1659                                  }
1660 1660                                  if (CURRENT_TAG(p) & TAG_DEAD)
1661 1661                                          continue;
1662 1662  
1663 1663                                  /* Try to write back the pseudo to where it should go ... */
1664 1664                                  if (final_pseudo_flush(state, p, reg)) {
1665 1665                                          DELETE_CURRENT_PTR(p);
↓ open down ↓ 276 lines elided ↑ open up ↑
1942 1942          return 0;
1943 1943  }
1944 1944  
1945 1945  int main(int argc, char **argv)
1946 1946  {
1947 1947          struct string_list *filelist = NULL;
1948 1948          char *file;
1949 1949  
1950 1950          compile(sparse_initialize(argc, argv, &filelist));
1951 1951          dbg_dead = 1;
1952      -        FOR_EACH_PTR_NOTAG(filelist, file) {
     1952 +        FOR_EACH_PTR(filelist, file) {
1953 1953                  compile(sparse(file));
1954      -        } END_FOR_EACH_PTR_NOTAG(file);
     1954 +        } END_FOR_EACH_PTR(file);
1955 1955          return 0;
1956 1956  }
1957 1957  
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX