Gentoo Archives: gentoo-dev

From: Konstantin Tokarev <annulen@××××××.ru>
To: gentoo-dev@l.g.o
Subject: Re: [gentoo-dev] Re: Move x86/amd64 CPU extensions USE flags to a new USE_EXPAND variable
Date: Mon, 13 Dec 2010 16:02:48
Message-Id: 75111292256132@web21.yandex.ru
In Reply to: Re: [gentoo-dev] Re: Move x86/amd64 CPU extensions USE flags to a new USE_EXPAND variable by Francesco R
1 13.12.2010, 18:53, "Francesco R" <vivo75@×××××.com>:
2 > 2010/12/13 Ryan Hill <dirtyepic@g.o>
3 >> On Sun, 12 Dec 2010 09:01:13 -0400
4 >> "Sergio D. Rodríguez Inclan" <srinclan@×××××.com> wrote:
5 >>
6 >>>   El 12/12/2010 02:46 a.m., Ryan Hill escribió:
7 >>> > I think the fewer sources of magic USE flags the better.  Maybe we could
8 >>> > document how to figure out what instruction sets a processor supports in the
9 >>> > handbook instead.
10 >>
11 >>> A good manual would be greatly appreciated :)
12 >>
13 >> I wrote a guide a couple weeks ago that might be a good starting point.
14 >>
15 >> http://en.gentoo-wiki.com/wiki/Hardware_CFLAGS
16 >
17 > if I read correctly the article on the wiki it does circa what the script reported below does.
18 > would be possible to adopt something similar for automatic C*FLAGS selection if someone step in willing to take the pain to mantain it.
19 >
20 > #!/usr/bin/python
21 > # Copyright 2010 Gentoo Foundation
22 > # Distributed under the terms of the GNU General Public License v2
23 > # Author: Francesco Riosa
24 > # extrapolated from http://en.gentoo-wiki.com/wiki/Hardware_CFLAGS, errors are mine
25 >
26 > # kate: encoding utf-8; eol unix
27 > # kate: indent-width 4; mixedindent off; replace-tabs on;
28 > # kate: remove-trailing-space on; space-indent on
29 >
30 > # echo "int main() { return 0; }" | gcc -march=native -v -E - 2>&1 | grep march
31 > # echo "int main() { return 0; }" | gcc -march=core2 -v -Q -x c - 2>&1
32 >
33 > """
34 > example output:
35 > ./hw-cflags.py
36 > extrapolating flags for gcc-4.4.5
37 >   useful flags: -march=core2 -msse4.1 --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=2048 -mtune=generic
38 >   redundant:    -mcx16 -msahf
39 >
40 > extrapolating flags for gcc-4.5.1
41 >   useful flags: -march=core2 -msse4.1 --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=2048 -mtune=core2
42 >   redundant:    -mcx16 -msahf
43 > """
44 >
45 > import os
46 > import time
47 > import fnmatch
48 > from subprocess import Popen, PIPE
49 >
50 > GCC_PATH = '/usr/bin/'
51 > GCC_LIST = fnmatch.filter(os.listdir(GCC_PATH), 'gcc-[0-9].*')
52 > GCC_LIST.sort()
53 >
54 > def extract_flags(gcccmd, header):
55 >     # get output from gcc
56 >     buf = ''
57 >     devnul = open('/dev/null', 'w')
58 >     p = Popen(gcccmd, stdin=PIPE, stdout=devnul, stderr=PIPE)
59 >     p.stdin.write("""int main() { return 0; }""")
60 >     p.stdin.close()
61 >     while p.poll() is None:
62 >         t = p.stderr.read()
63 >         buf = "buf%s" % t
64 >         time.sleep(0.01)
65 >     p.stderr.close()
66 >     devnul.close()
67 >
68 >     # parse it
69 >     flags = []
70 >     add = False
71 >     for line in buf.split('\n'):
72 >         if line.startswith(header):
73 >             add = True
74 >             flags += line.strip().split(' ')
75 >             continue
76 >         if add:
77 >             if line.startswith(' '):
78 >                 flags += line.strip().split(' ')
79 >             else:
80 >                 break
81 >
82 >     # extract flags we are interested in
83 >     t = []
84 >     march = ''
85 >     mtune = '-mtune=generic'
86 >     for i in xrange(len(flags)):
87 >         if flags[i].startswith('-m'):
88 >             if flags[i].startswith('-mtune'):
89 >                 mtune = flags[i]
90 >             elif flags[i].startswith('-march'):
91 >                 march = flags[i]
92 >             else:
93 >                 t.append(flags[i])
94 >         elif flags[i] == '--param':
95 >             t.append("%s %s" % (flags[i], flags[i+1]))
96 >     flags = t
97 >
98 >     return march, mtune, flags
99 >
100 > for gcc in GCC_LIST:
101 >
102 >     print "extrapolating flags for %s" % gcc
103 >
104 >     gcccmd = [ GCC_PATH + gcc, '-march=native', '-v', '-E', '-', ]
105 >     header='COLLECT_GCC_OPTIONS'
106 >     march, mtune, flags_native = extract_flags(gcccmd, header)
107 >
108 >     gcccmd = [ GCC_PATH + gcc, march, '-v', '-Q', '-x', 'c', '-', ]
109 >     header='options enabled:'
110 >     t, t, flags_enabled = extract_flags(gcccmd, header)
111 >
112 >     redundant_flags = []
113 >     useful_flags = []
114 >
115 >     for x in flags_native:
116 >         if x in flags_enabled:
117 >             redundant_flags.append(x)
118 >         else:
119 >             useful_flags.append(x)
120 >
121 >     if gcc < "gcc-4.5.0":
122 >         mtune = '-mtune=generic'
123 >
124 >     print "  useful flags: %s %s %s " % (march, " ".join(useful_flags), mtune)
125 >     print "  redundant:    %s" % " ".join(redundant_flags)
126 >     print
127
128 Note that for some architectures (e.g, PowerPC) you need to add "-mcpu" case
129 (-mcpu has the same meaning as -march on x86)
130
131
132 --
133 Regards,
134 Konstantin

Replies