आइए GCC 5.1 के स्रोत कोड की व्याख्या करें कि -O100यह देखने के लिए क्या होता है क्योंकि यह मैन पेज पर स्पष्ट नहीं है।
हम यह निष्कर्ष निकालेंगे:
- ऊपर कुछ भी
-O3करने के लिए INT_MAXके रूप में ही है -O3, लेकिन यह आसानी से, भविष्य में बदल सकता है तो यह पर भरोसा नहीं करते।
- यदि आप पूर्णांकों से बड़ा दर्ज करते हैं तो GCC 5.1 अपरिभाषित व्यवहार करता है
INT_MAX।
- तर्क में केवल अंक हो सकते हैं, या यह इनायत से विफल होता है। विशेष रूप से, यह नकारात्मक पूर्णांकों को शामिल नहीं करता है
-O-1
उपप्रोग्राम पर ध्यान दें
सबसे पहले तो याद रखें कि जीसीसी के लिए सिर्फ एक सामने के अंत है cpp, as, cc1, collect2। एक त्वरित ./XXX --helpकहता है कि केवल collect2और cc1ले लो -O, तो चलो उन पर ध्यान केंद्रित करें।
तथा:
gcc -v -O100 main.c |& grep 100
देता है:
COLLECT_GCC_OPTIONS='-O100' '-v' '-mtune=generic' '-march=x86-64'
/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/5.1.0/cc1 [[noise]] hello_world.c -O100 -o /tmp/ccetECB5.
तो -Oदोनों के लिए भेजा गया था cc1और collect2।
ओ में आम
common.opt एक GCC विशिष्ट CLI विकल्प वर्णन प्रारूप है जिसे इंटर्नल डॉक्यूमेंटेशन में वर्णित किया गया है और C को opth-gen.awk और optc-gen.awk द्वारा अनुवादित किया गया है ।
इसमें निम्नलिखित दिलचस्प लाइनें शामिल हैं:
O
Common JoinedOrMissing Optimization
-O<number> Set optimization level to <number>
Os
Common Optimization
Optimize for space rather than speed
Ofast
Common Optimization
Optimize for speed disregarding exact standards compliance
Og
Common Optimization
Optimize for debugging experience rather than speed or size
जो सभी Oविकल्पों को निर्दिष्ट करते हैं। ध्यान दें कि -O<n>दूसरे से एक अलग परिवार में कैसे है Os, OfastऔरOg ।
जब हम निर्माण करते हैं, तो options.hइसमें एक फ़ाइल उत्पन्न होती है:
OPT_O = 139, /* -O */
OPT_Ofast = 140, /* -Ofast */
OPT_Og = 141, /* -Og */
OPT_Os = 142, /* -Os */
एक बोनस के रूप में, जबकि हम \bO\nअंदर की ओर इशारा कर रहे हैं common.optहम लाइनों को नोटिस करते हैं:
-optimize
Common Alias(O)
जो हमें सिखाता है कि --optimize(डबल डैश क्योंकि यह फ़ाइल -optimizeपर एक डैश के साथ शुरू होता है .opt) एक अनजाने उपनाम है -Oजिसके लिए इसका उपयोग किया जा सकता है--optimize=3 !
जहां OPT_O का उपयोग किया जाता है
अब हम grep:
git grep -E '\bOPT_O\b'
जो हमें दो फाइलों की ओर इशारा करता है:
चलो पहले नीचे ट्रैक करते हैं opts.c
opts.c: default_options_optimization
सभी opts.cउपयोग अंदर होते हैं:default_options_optimization।
हम यह देखने के लिए पीछे हटते हैं कि इस फ़ंक्शन को कौन कॉल करता है, और हम देखते हैं कि एकमात्र कोड पथ है:
main.c:main
toplev.c:toplev::main
opts-global.c:decode_opts
opts.c:default_options_optimization
और main.cका प्रवेश बिंदु हैcc1 । अच्छा!
इस समारोह का पहला भाग:
integral_argumentजो atoiस्ट्रिंग पर कॉल करता हैOPT_Oइनपुट तर्क को पार्स लिए है
opts->x_optimizeजहां optsएक है के अंदर मूल्य संग्रहीत करता है struct gcc_opts।
संरचना gcc_opts
व्यर्थ में टटोलने के बाद, हम देखते हैं कि यह structभी उत्पन्न होता है options.h:
struct gcc_options {
int x_optimize;
[...]
}
x_optimizeलाइनों से कहाँ आता है:
Variable
int optimize
वर्तमान में common.opt, और वह options.c:
struct gcc_options global_options;
इसलिए हम अनुमान लगाते हैं कि यह वही है जो संपूर्ण कॉन्फ़िगरेशन वैश्विक स्थिति में है, और int x_optimize अनुकूलन मान है।
255 एक आंतरिक अधिकतम है
में opts.c:integral_argument, atoiइनपुट तर्क पर लागू किया जाता है, इसलिए INT_MAXएक ऊपरी बाध्य है। और अगर आप कुछ भी बड़ा करते हैं, तो ऐसा लगता है कि जीसीसी सी अपरिभाषित व्यवहार करता है। आउच?
integral_argumentatoiयदि कोई वर्ण कोई अंक नहीं है, तो भी तर्क को बारीकी से लपेटता है और अस्वीकार करता है। इसलिए नकारात्मक मूल्य अनुग्रहपूर्वक विफल होते हैं।
वापस opts.c:default_options_optimization, हम लाइन देखते हैं:
if ((unsigned int) opts->x_optimize > 255)
opts->x_optimize = 255;
ताकि ऑप्टिमाइज़ेशन लेवल को छोटा कर दिया जाए 255। पढ़ते समय opth-gen.awkमैं भर आया था:
# All of the optimization switches gathered together so they can be saved and restored.
# This will allow attribute((cold)) to turn on space optimization.
और उत्पन्न पर options.h:
struct GTY(()) cl_optimization
{
unsigned char x_optimize;
जो बताता है कि क्यों छंटनी: विकल्पों को भी अग्रेषित किया जाना चाहिए cl_optimization, जो एक का उपयोग करता हैchar अंतरिक्ष को बचाने के लिए है। तो 255 वास्तव में एक आंतरिक अधिकतम है।
opts.c: maybe_default_options
पर वापस opts.c:default_options_optimization, हम maybe_default_optionsजो दिलचस्प लगता है भर में आते हैं। हम इसे दर्ज करते हैं, और फिर maybe_default_optionजहां हम एक बड़े स्विच तक पहुंचते हैं:
switch (default_opt->levels)
{
[...]
case OPT_LEVELS_1_PLUS:
enabled = (level >= 1);
break;
[...]
case OPT_LEVELS_3_PLUS:
enabled = (level >= 3);
break;
कोई >= 4जांच नहीं है , जो इंगित करता है कि 3सबसे बड़ा संभव है।
फिर हम की परिभाषा के लिए खोज OPT_LEVELS_3_PLUSमें common-target.h:
enum opt_levels
{
OPT_LEVELS_NONE, /* No levels (mark end of array). */
OPT_LEVELS_ALL, /* All levels (used by targets to disable options
enabled in target-independent code). */
OPT_LEVELS_0_ONLY, /* -O0 only. */
OPT_LEVELS_1_PLUS, /* -O1 and above, including -Os and -Og. */
OPT_LEVELS_1_PLUS_SPEED_ONLY, /* -O1 and above, but not -Os or -Og. */
OPT_LEVELS_1_PLUS_NOT_DEBUG, /* -O1 and above, but not -Og. */
OPT_LEVELS_2_PLUS, /* -O2 and above, including -Os. */
OPT_LEVELS_2_PLUS_SPEED_ONLY, /* -O2 and above, but not -Os or -Og. */
OPT_LEVELS_3_PLUS, /* -O3 and above. */
OPT_LEVELS_3_PLUS_AND_SIZE, /* -O3 and above and -Os. */
OPT_LEVELS_SIZE, /* -Os only. */
OPT_LEVELS_FAST /* -Ofast only. */
};
हा! यह एक मजबूत संकेतक है कि केवल 3 स्तर हैं।
opts.c: default_options_table
opt_levelsइतना दिलचस्प है, कि हम मचलते हैं OPT_LEVELS_3_PLUS, और सामने आते हैं opts.c:default_options_table:
static const struct default_options default_options_table[] = {
/* -O1 optimizations. */
{ OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
[...]
/* -O3 optimizations. */
{ OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
[...]
}
इसलिए यह वह जगह है जहां -Onडॉक्स में उल्लिखित विशिष्ट अनुकूलन मानचित्रण एन्कोडेड है। अच्छा!
आश्वासन दें कि x_optimize के लिए और अधिक उपयोग नहीं हैं
का मुख्य उपयोग मैन पेज पर प्रलेखित x_optimizeअन्य विशिष्ट अनुकूलन विकल्पों को सेट करना था -fdefer_pop। क्या कोई और है?
हम grep, और कुछ और पाते हैं। संख्या छोटी है, और मैनुअल निरीक्षण पर हम देखते हैं कि हर उपयोग केवल एक ही पर होता है x_optimize >= 3, इसलिए हमारा निष्कर्ष है।
LTO-wrapper.c
अब हम दूसरी घटना के लिए जाते हैं OPT_O, जो अंदर थी lto-wrapper.c।
एलटीओ का अर्थ है लिंक टाइम ऑप्टिमाइज़ेशन, जैसा कि नाम से पता चलता है कि एक -Oविकल्प की आवश्यकता है, और इसे collec2(जो मूल रूप से एक लिंक है) से जोड़ा जाएगा ।
वास्तव में, पहली पंक्ति lto-wrapper.cकहती है:
/* Wrapper to call lto. Used by collect2 and the linker plugin.
इस फ़ाइल में, OPT_Oआवृत्तियाँ केवल Oइसे आगे पास करने के लिए मान को सामान्य करती हैं, इसलिए हमें ठीक होना चाहिए।
man gccCygwin (12000 अजीब लाइनों) पर आप के लिए खोज कर सकते हैं-Oऔर सब कुछ राज्य नीचे जवाब मिल, और फिर कुछ।