1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Generator for SIMPLE_IPA 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 simple_ipa_opt_pass _PASS_NAME_PASS = { 81*4882a593Smuzhiyun .pass = { 82*4882a593Smuzhiyun #endif 83*4882a593Smuzhiyun .type = SIMPLE_IPA_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 simple_ipa_opt_pass { 112*4882a593Smuzhiyun public: 113*4882a593Smuzhiyun _PASS_NAME_PASS() : simple_ipa_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