summaryrefslogtreecommitdiff
path: root/gcc/ipa-structure-reorg.h
blob: 34cd271c4c80769216d7b88334ec891a61ad593b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/* Interprocedural scalar replacement of aggregates
   Copyright (C) 2019-2020 Free Software Foundation, Inc.

  Contributed by Gary Oblock <goblock@marvell.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#define USE_NEW_INTERFACE 1

typedef struct RT_Elim       RT_Elim;
typedef struct RT_Reorder    RT_Reorder;
typedef struct RT_Interleave RT_Interleave;

struct RT_Elim {
  int dummy;
};

struct RT_Reorder {
  int dummy;
};

struct RT_Interleave {
  int        numbOfGlobalArrays; // Statically allocated only
  int        numbOfLocalArrays;  // Statically allocated only
  int        numbOfDynmAllocs;
  double     reorg_perf;         
  double     regular_perf;
  bool       multi_pool;         // single pool if not set
  int dummy;
};

typedef struct ReorgType ReorgType_t;
struct ReorgType {
  unsigned      id;
  tree          gcc_type;
  bool          delete_me;
  // TBD will field reordering and/or dead field elimination use
  // use the clone? I think it's likely that they can.
  tree          clone;              // the base
  tree          pointer_rep;        // new pointer format (multi-pool)
  bool          do_dead_field_elim;
  bool          do_field_reorder;
  bool          do_instance_interleave;
  RT_Elim       dead_field_elim;
  RT_Reorder    field_reorder;
  RT_Interleave instance_interleave;
};

typedef struct ProgDecl ProgDecl_t;
struct ProgDecl {
  tree       gcc_decl;
};

enum ReorgOpTrans {
  // Let's try to use scalar insead of this... nope!
  ReorgOpT_Temp,         // SSA temp
  ReorgOpT_Address,     // "&x[i]"
  ReorgOpT_Pointer,     // "a"
  ReorgOpT_Struct,      // "s"
  ReorgOpT_Deref,       // "*a"
  ReorgOpT_Array,       // "x[i]"
  ReorgOpT_Scalar,      // "z"
  ReorgOpT_Indirect,    // "a->f"
  ReorgOpT_AryDir       // "x[i].f"
};

enum CompressionControl {
  Initial,
  Subsequent
};

enum ReorgTransformation {
  ReorgT_StrAssign,    // "*a = x[i]", "x[i] = y[j]", "s = *a", etc.
  ReorgT_ElemAssign,   // "a->f = z", "z = x[i].f", etc.
  ReorgT_If_Null,      // "if(a == 0)..."
  ReorgT_If_NotNull,   // "if(a != 0)..."
  ReorgT_IfPtrEQ,      // "if(a == b)..."
  ReorgT_IfPtrNE,      // "if(a != b)..."
  ReorgT_IfPtrLT,      // "if(a < b)..."
  ReorgT_IfPtrGT,      // "if(a > b)..."
  ReorgT_IfPtrLE,      // "if(a <= b)..."
  ReorgT_IfPtrGE,      // "if(a >= b)..."
  ReorgT_PtrPlusInt,   // "a = b + i"
  ReorgT_Ptr2Zero,     // "a = 0"
  ReorgT_PtrDiff,      // "i = a - b"
  ReorgT_Adr2Ptr,      // "a = &x[i]"
  ReorgT_PtrNull,      // "x = a == 0"
  ReorgT_PtrNotNull,   // "x = a != 0"
  ReorgT_PtrEQ,        // "x = a == b"
  ReorgT_PtrNE,        // "x = a != b"
  ReorgT_PtrLT,        // "x = a < b"
  ReorgT_PtrLE,        // "x = a <= b"
  ReorgT_PtrGT,        // "x = a > b"
  ReorgT_PtrGE,        // "x = a >= b"
  ReorgT_Malloc,       //
  ReorgT_Calloc,       //
  ReorgT_Realloc,      //
  ReorgT_Free,         //
  Not_Supported
};

// Added as design bug fix
typedef struct BoolPair BoolPair_t;
struct BoolPair {
  bool processed;
  bool layout_changed;
};

typedef struct Info Info_t;
struct Info {
  std::vector <ReorgType_t>      *reorg_type;
  // Added to by remove_deleted_types
  std::vector <ReorgType_t>      *saved_reorg_type;
  std::vector <ProgDecl_t>       *prog_decl;
  // Gcc doesn't have global decls readily available
  // so this holds them
  std::map <tree,BoolPair_t>     *struct_types; // desing bug fix
  int                             num_deleted;
  double                          total_cache_accesses;
  FILE                           *reorg_dump_file;
  // Debug flags
  bool                            show_all_reorg_cands;
  bool                            show_all_reorg_cands_in_detail;
  bool                            show_prog_decls;
  bool                            show_delete;
  bool                            show_new_BBs;
  bool                            show_transforms;
  bool                            show_bounds;
};

// This will perform a function on the supplied
// reorg type. It's primarily to support debugging.
typedef void (*ReorgFn)( Info *, ReorgType_t *);

#if USE_NEW_INTERFACE
extern int str_reorg_dead_field_eliminate_qual ( Info *);
extern int str_reorg_dead_field_eliminate_trans ( Info *);
extern int str_reorg_field_reorder_qual ( Info *);
extern int str_reorg_field_reorder_trans ( Info *);
extern int str_reorg_instance_interleave_qual ( Info *);
extern int str_reorg_instance_interleave_trans ( Info *);
#else
extern int str_reorg_dead_field_eliminate ( Info *);
extern int str_reorg_field_reorder ( Info *);
extern int str_reorg_instance_interleave ( Info *);
#endif

extern void delete_reorgtype ( ReorgType_t *, Info_t *);
extern void undelete_reorgtype ( ReorgType_t *, Info_t *);
extern void clear_deleted_types( Info *);
extern void restore_deleted_types ( Info *);
extern void remove_deleted_types ( Info *, ReorgFn);
extern enum ReorgOpTrans recognize_op ( tree,  Info_t *);
extern ReorgTransformation reorg_recognize ( gimple *, Info_t *);
extern ReorgType_t *get_reorgtype_info ( tree, Info_t *);
extern ReorgType_t *contains_a_reorgtype ( gimple *, Info *);
extern bool is_reorg_type ( tree, Info_t *);
extern tree base_type_of ( tree);
extern void print_reorg ( FILE *, int, ReorgType_t *);
extern void print_type ( FILE *, tree);
  
//#define MAX(a,b) ((a) > (b) ? (a) : (b))

// I have no intention of leaving this or uses of the
// defined marcos in the code. However, some of uses
// should obviously be converted to dump file information.

#define DEBUGGING 0
#if DEBUGGING
// Line numbered
#define DEBUG_L(...) { fprintf( stderr, "L# %4d: %*s", __LINE__, debug_indenting, ""); fprintf( stderr, __VA_ARGS__); }
// Alinged with line numbered
#define DEBUG_A(...) { fprintf( stderr, "%*s", debug_indenting + 7, ""); fprintf( stderr, __VA_ARGS__); }
//With no indenting
#define DEBUG(...) { fprintf( stderr, __VA_ARGS__); }
#define DEBUG_F(f,...) f( __VA_ARGS__)
#define INDENT(a) handle_debug_indenting(a)
#else
#define DEBUG_L(...)
#define DEBUG_A(...)
#define DEBUG(...)
#define DEBUG_F(...)
#define INDENT(a)
#endif