How to locate the gimple precisely and change it?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear GCC developers:

Hi, I'm trying to write a pass in gcc to implement structure
splitting. And I'm having a problem that I don't know how to locate
the gimple that I want and I need to change it of course.

This is the origin C code and the gimple:
```
struct node {
    float _Complex al;
    unsigned long long state;
};

struct reg {
    int size;
    struct node *node;
};
// example function
void func(int c1, int c2, int target, struct reg* r) {
    for (int i = 0; i < r->size; i++) {
        if (c1) {
            r->node[i].state += 3;
        }
    }
}
```
```
void func (int c1, int c2, int target, struct reg * r)
{
  {
    int i;

    i = 0;
    goto <D.2885>;
    <D.2884>:
    if (c1 != 0) goto <D.2895>; else goto <D.2896>;
    <D.2895>:
    _1 = r->node;
    _2 = (long unsigned int) i;
    _3 = _2 * 16;
    _4 = _1 + _3;
    _5 = _4->state;
    _6 = r->node;
    // ...
  }
}
```
And Here's C code and gimple that I want to change to:
```
struct node {
    float _Complex *al; // changed
    unsigned long long *state; // changed
};

struct reg {
    int size;
    struct node *node;
};

void func(int c1, int c2, int target, struct reg* r) {
    for (int i = 0; i < r->size; i++) {
        if (c1) {
            r->node->state[i] += 3; // changed
        }
    }
}
```
```
void func (int c1, int c2, int target, struct reg * r)
{
  {
    int i;
    i = 0;
    goto <D.2884>;
    <D.2883>:
    if (c1 != 0) goto <D.2894>; else goto <D.2895>;
    <D.2894>:
    _1 = r->node;
    _2 = _1->state;
    _3 = (long unsigned int) i;
    _4 = _3 * 8;
    _5 = _2 + _4;
    _6 = *_5;
    _7 = r->node;
    // ...
  }
}
```
And I put my pass at ipa-late-pass and declared it as a
SIMPLE_IPA_PASS. Here is my code in the pass:

unsigned int
pass_struct_split::execute (function *)
{
  // 1. get desire struct type
  tree desire_type = get_split_types(); // `struct node`
  if (!desire_type) return 0;

  // 2. find the struct type and split it
  struct cgraph_node *node;
  FOR_EACH_DEFINED_FUNCTION(node) {
    printf("===start func===\n");
    struct function *func = DECL_STRUCT_FUNCTION (node->decl);
    basic_block bb;
    FOR_EACH_BB_FN (bb, func) {
      gimple_stmt_iterator start, end;
        for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p
(gsi); gsi_next (&gsi)) {
          gimple *stmt = gsi_stmt (gsi);
        // find xx = r->node
        if (gimple_code(stmt) == GIMPLE_ASSIGN) {
          if (gimple_assign_rhs_code(stmt) == COMPONENT_REF) {
            tree lhsop = gimple_assign_lhs (stmt);
            tree rhsop = gimple_assign_rhs1 (stmt);
            if (TREE_CODE(TREE_TYPE(rhsop)) == POINTER_TYPE &&
TREE_CODE(TREE_TYPE(TREE_TYPE(rhsop))) == RECORD_TYPE) {
              tree pointee_type = TREE_TYPE(TREE_TYPE(rhsop));
              if (pointee_type == desire_type) {
                // record start
                start = gsi;
              }
            }
          }
        }
        // find the end place: find xx = xx->state

      }
    }


  }


  return 0;
}

I can't locate the r->node[i].state parts. I only get the start point
which I don't know if it's the right way to record the start point.
And I'm stuck with locating the end point. And this is just an ASSIGN
statement. I'm not sure if I can handle other kinds of statements like
malloc and some tricky ones. So how can I locate it? Or is there a
better way or some interfaces to make it work?

Thanks for your help!



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux