xref: /linux/scripts/gcc-plugins/gcc-generate-rtl-pass.h (revision 0bb33e25e5c91f69304f3799609a52354dca1af4)
1  /*
2   * Generator for RTL pass related boilerplate code/data
3   *
4   * Supports gcc 4.5-6
5   *
6   * Usage:
7   *
8   * 1. before inclusion define PASS_NAME
9   * 2. before inclusion define NO_* for unimplemented callbacks
10   *    NO_GATE
11   *    NO_EXECUTE
12   * 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override
13   *    the default 0 values
14   * 4. for convenience, all the above will be undefined after inclusion!
15   * 5. the only exported name is make_PASS_NAME_pass() to register with gcc
16   */
17  
18  #ifndef PASS_NAME
19  #error at least PASS_NAME must be defined
20  #else
21  #define __GCC_PLUGIN_STRINGIFY(n)	#n
22  #define _GCC_PLUGIN_STRINGIFY(n)	__GCC_PLUGIN_STRINGIFY(n)
23  #define _GCC_PLUGIN_CONCAT2(x, y)	x ## y
24  #define _GCC_PLUGIN_CONCAT3(x, y, z)	x ## y ## z
25  
26  #define __PASS_NAME_PASS_DATA(n)	_GCC_PLUGIN_CONCAT2(n, _pass_data)
27  #define _PASS_NAME_PASS_DATA		__PASS_NAME_PASS_DATA(PASS_NAME)
28  
29  #define __PASS_NAME_PASS(n)		_GCC_PLUGIN_CONCAT2(n, _pass)
30  #define _PASS_NAME_PASS			__PASS_NAME_PASS(PASS_NAME)
31  
32  #define _PASS_NAME_NAME			_GCC_PLUGIN_STRINGIFY(PASS_NAME)
33  
34  #define __MAKE_PASS_NAME_PASS(n)	_GCC_PLUGIN_CONCAT3(make_, n, _pass)
35  #define _MAKE_PASS_NAME_PASS		__MAKE_PASS_NAME_PASS(PASS_NAME)
36  
37  #ifdef NO_GATE
38  #define _GATE NULL
39  #define _HAS_GATE false
40  #else
41  #define __GATE(n)			_GCC_PLUGIN_CONCAT2(n, _gate)
42  #define _GATE				__GATE(PASS_NAME)
43  #define _HAS_GATE true
44  #endif
45  
46  #ifdef NO_EXECUTE
47  #define _EXECUTE NULL
48  #define _HAS_EXECUTE false
49  #else
50  #define __EXECUTE(n)			_GCC_PLUGIN_CONCAT2(n, _execute)
51  #define _EXECUTE			__EXECUTE(PASS_NAME)
52  #define _HAS_EXECUTE true
53  #endif
54  
55  #ifndef PROPERTIES_REQUIRED
56  #define PROPERTIES_REQUIRED 0
57  #endif
58  
59  #ifndef PROPERTIES_PROVIDED
60  #define PROPERTIES_PROVIDED 0
61  #endif
62  
63  #ifndef PROPERTIES_DESTROYED
64  #define PROPERTIES_DESTROYED 0
65  #endif
66  
67  #ifndef TODO_FLAGS_START
68  #define TODO_FLAGS_START 0
69  #endif
70  
71  #ifndef TODO_FLAGS_FINISH
72  #define TODO_FLAGS_FINISH 0
73  #endif
74  
75  #if BUILDING_GCC_VERSION >= 4009
76  namespace {
77  static const pass_data _PASS_NAME_PASS_DATA = {
78  #else
79  static struct rtl_opt_pass _PASS_NAME_PASS = {
80  	.pass = {
81  #endif
82  		.type			= RTL_PASS,
83  		.name			= _PASS_NAME_NAME,
84  #if BUILDING_GCC_VERSION >= 4008
85  		.optinfo_flags		= OPTGROUP_NONE,
86  #endif
87  #if BUILDING_GCC_VERSION >= 5000
88  #elif BUILDING_GCC_VERSION == 4009
89  		.has_gate		= _HAS_GATE,
90  		.has_execute		= _HAS_EXECUTE,
91  #else
92  		.gate			= _GATE,
93  		.execute		= _EXECUTE,
94  		.sub			= NULL,
95  		.next			= NULL,
96  		.static_pass_number	= 0,
97  #endif
98  		.tv_id			= TV_NONE,
99  		.properties_required	= PROPERTIES_REQUIRED,
100  		.properties_provided	= PROPERTIES_PROVIDED,
101  		.properties_destroyed	= PROPERTIES_DESTROYED,
102  		.todo_flags_start	= TODO_FLAGS_START,
103  		.todo_flags_finish	= TODO_FLAGS_FINISH,
104  #if BUILDING_GCC_VERSION < 4009
105  	}
106  #endif
107  };
108  
109  #if BUILDING_GCC_VERSION >= 4009
110  class _PASS_NAME_PASS : public rtl_opt_pass {
111  public:
112  	_PASS_NAME_PASS() : rtl_opt_pass(_PASS_NAME_PASS_DATA, g) {}
113  
114  #ifndef NO_GATE
115  #if BUILDING_GCC_VERSION >= 5000
116  	virtual bool gate(function *) { return _GATE(); }
117  #else
118  	virtual bool gate(void) { return _GATE(); }
119  #endif
120  #endif
121  
122  	virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
123  
124  #ifndef NO_EXECUTE
125  #if BUILDING_GCC_VERSION >= 5000
126  	virtual unsigned int execute(function *) { return _EXECUTE(); }
127  #else
128  	virtual unsigned int execute(void) { return _EXECUTE(); }
129  #endif
130  #endif
131  };
132  }
133  
134  opt_pass *_MAKE_PASS_NAME_PASS(void)
135  {
136  	return new _PASS_NAME_PASS();
137  }
138  #else
139  struct opt_pass *_MAKE_PASS_NAME_PASS(void)
140  {
141  	return &_PASS_NAME_PASS.pass;
142  }
143  #endif
144  
145  /* clean up user provided defines */
146  #undef PASS_NAME
147  #undef NO_GATE
148  #undef NO_EXECUTE
149  
150  #undef PROPERTIES_DESTROYED
151  #undef PROPERTIES_PROVIDED
152  #undef PROPERTIES_REQUIRED
153  #undef TODO_FLAGS_FINISH
154  #undef TODO_FLAGS_START
155  
156  /* clean up generated defines */
157  #undef _EXECUTE
158  #undef __EXECUTE
159  #undef _GATE
160  #undef __GATE
161  #undef _GCC_PLUGIN_CONCAT2
162  #undef _GCC_PLUGIN_CONCAT3
163  #undef _GCC_PLUGIN_STRINGIFY
164  #undef __GCC_PLUGIN_STRINGIFY
165  #undef _HAS_EXECUTE
166  #undef _HAS_GATE
167  #undef _MAKE_PASS_NAME_PASS
168  #undef __MAKE_PASS_NAME_PASS
169  #undef _PASS_NAME_NAME
170  #undef _PASS_NAME_PASS
171  #undef __PASS_NAME_PASS
172  #undef _PASS_NAME_PASS_DATA
173  #undef __PASS_NAME_PASS_DATA
174  
175  #endif /* PASS_NAME */
176