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