~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Target/X86/README-X86-64.txt

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===- README_X86_64.txt - Notes for X86-64 code gen ----------------------===//
 
2
 
 
3
Implement different PIC models? Right now we only support Mac OS X with small
 
4
PIC code model.
 
5
 
 
6
//===---------------------------------------------------------------------===//
 
7
 
 
8
For this:
 
9
 
 
10
extern void xx(void);
 
11
void bar(void) {
 
12
  xx();
 
13
}
 
14
 
 
15
gcc compiles to:
 
16
 
 
17
.globl _bar
 
18
_bar:
 
19
        jmp     _xx
 
20
 
 
21
We need to do the tailcall optimization as well.
 
22
 
 
23
//===---------------------------------------------------------------------===//
 
24
 
 
25
AMD64 Optimization Manual 8.2 has some nice information about optimizing integer
 
26
multiplication by a constant. How much of it applies to Intel's X86-64
 
27
implementation? There are definite trade-offs to consider: latency vs. register
 
28
pressure vs. code size.
 
29
 
 
30
//===---------------------------------------------------------------------===//
 
31
 
 
32
Are we better off using branches instead of cmove to implement FP to
 
33
unsigned i64?
 
34
 
 
35
_conv:
 
36
        ucomiss LC0(%rip), %xmm0
 
37
        cvttss2siq      %xmm0, %rdx
 
38
        jb      L3
 
39
        subss   LC0(%rip), %xmm0
 
40
        movabsq $-9223372036854775808, %rax
 
41
        cvttss2siq      %xmm0, %rdx
 
42
        xorq    %rax, %rdx
 
43
L3:
 
44
        movq    %rdx, %rax
 
45
        ret
 
46
 
 
47
instead of
 
48
 
 
49
_conv:
 
50
        movss LCPI1_0(%rip), %xmm1
 
51
        cvttss2siq %xmm0, %rcx
 
52
        movaps %xmm0, %xmm2
 
53
        subss %xmm1, %xmm2
 
54
        cvttss2siq %xmm2, %rax
 
55
        movabsq $-9223372036854775808, %rdx
 
56
        xorq %rdx, %rax
 
57
        ucomiss %xmm1, %xmm0
 
58
        cmovb %rcx, %rax
 
59
        ret
 
60
 
 
61
Seems like the jb branch has high likelyhood of being taken. It would have
 
62
saved a few instructions.
 
63
 
 
64
//===---------------------------------------------------------------------===//
 
65
 
 
66
Poor codegen:
 
67
 
 
68
int X[2];
 
69
int b;
 
70
void test(void) {
 
71
  memset(X, b, 2*sizeof(X[0]));
 
72
}
 
73
 
 
74
llc:
 
75
        movq _b@GOTPCREL(%rip), %rax
 
76
        movzbq (%rax), %rax
 
77
        movq %rax, %rcx
 
78
        shlq $8, %rcx
 
79
        orq %rax, %rcx
 
80
        movq %rcx, %rax
 
81
        shlq $16, %rax
 
82
        orq %rcx, %rax
 
83
        movq %rax, %rcx
 
84
        shlq $32, %rcx
 
85
        movq _X@GOTPCREL(%rip), %rdx
 
86
        orq %rax, %rcx
 
87
        movq %rcx, (%rdx)
 
88
        ret
 
89
 
 
90
gcc:
 
91
        movq    _b@GOTPCREL(%rip), %rax
 
92
        movabsq $72340172838076673, %rdx
 
93
        movzbq  (%rax), %rax
 
94
        imulq   %rdx, %rax
 
95
        movq    _X@GOTPCREL(%rip), %rdx
 
96
        movq    %rax, (%rdx)
 
97
        ret
 
98
 
 
99
//===---------------------------------------------------------------------===//
 
100
 
 
101
Vararg function prologue can be further optimized. Currently all XMM registers
 
102
are stored into register save area. Most of them can be eliminated since the
 
103
upper bound of the number of XMM registers used are passed in %al. gcc produces
 
104
something like the following:
 
105
 
 
106
        movzbl  %al, %edx
 
107
        leaq    0(,%rdx,4), %rax
 
108
        leaq    4+L2(%rip), %rdx
 
109
        leaq    239(%rsp), %rax
 
110
        jmp     *%rdx
 
111
        movaps  %xmm7, -15(%rax)
 
112
        movaps  %xmm6, -31(%rax)
 
113
        movaps  %xmm5, -47(%rax)
 
114
        movaps  %xmm4, -63(%rax)
 
115
        movaps  %xmm3, -79(%rax)
 
116
        movaps  %xmm2, -95(%rax)
 
117
        movaps  %xmm1, -111(%rax)
 
118
        movaps  %xmm0, -127(%rax)
 
119
L2:
 
120
 
 
121
It jumps over the movaps that do not need to be stored. Hard to see this being
 
122
significant as it added 5 instruciton (including a indirect branch) to avoid
 
123
executing 0 to 8 stores in the function prologue.
 
124
 
 
125
Perhaps we can optimize for the common case where no XMM registers are used for
 
126
parameter passing. i.e. is %al == 0 jump over all stores. Or in the case of a
 
127
leaf function where we can determine that no XMM input parameter is need, avoid
 
128
emitting the stores at all.
 
129
 
 
130
//===---------------------------------------------------------------------===//
 
131
 
 
132
AMD64 has a complex calling convention for aggregate passing by value:
 
133
 
 
134
1. If the size of an object is larger than two eightbytes, or in C++, is a non- 
 
135
   POD structure or union type, or contains unaligned fields, it has class 
 
136
   MEMORY.
 
137
2. Both eightbytes get initialized to class NO_CLASS. 
 
138
3. Each field of an object is classified recursively so that always two fields
 
139
   are considered. The resulting class is calculated according to the classes
 
140
   of the fields in the eightbyte: 
 
141
   (a) If both classes are equal, this is the resulting class. 
 
142
   (b) If one of the classes is NO_CLASS, the resulting class is the other 
 
143
       class. 
 
144
   (c) If one of the classes is MEMORY, the result is the MEMORY class. 
 
145
   (d) If one of the classes is INTEGER, the result is the INTEGER. 
 
146
   (e) If one of the classes is X87, X87UP, COMPLEX_X87 class, MEMORY is used as
 
147
      class. 
 
148
   (f) Otherwise class SSE is used. 
 
149
4. Then a post merger cleanup is done: 
 
150
   (a) If one of the classes is MEMORY, the whole argument is passed in memory. 
 
151
   (b) If SSEUP is not preceeded by SSE, it is converted to SSE.
 
152
 
 
153
Currently llvm frontend does not handle this correctly.
 
154
 
 
155
Problem 1:
 
156
    typedef struct { int i; double d; } QuadWordS;
 
157
It is currently passed in two i64 integer registers. However, gcc compiled
 
158
callee expects the second element 'd' to be passed in XMM0.
 
159
 
 
160
Problem 2:
 
161
    typedef struct { int32_t i; float j; double d; } QuadWordS;
 
162
The size of the first two fields == i64 so they will be combined and passed in
 
163
a integer register RDI. The third field is still passed in XMM0.
 
164
 
 
165
Problem 3:
 
166
    typedef struct { int64_t i; int8_t j; int64_t d; } S;
 
167
    void test(S s)
 
168
The size of this aggregate is greater than two i64 so it should be passed in 
 
169
memory. Currently llvm breaks this down and passed it in three integer
 
170
registers.
 
171
 
 
172
Problem 4:
 
173
Taking problem 3 one step ahead where a function expects a aggregate value
 
174
in memory followed by more parameter(s) passed in register(s).
 
175
    void test(S s, int b)
 
176
 
 
177
LLVM IR does not allow parameter passing by aggregates, therefore it must break
 
178
the aggregates value (in problem 3 and 4) into a number of scalar values:
 
179
    void %test(long %s.i, byte %s.j, long %s.d);
 
180
 
 
181
However, if the backend were to lower this code literally it would pass the 3
 
182
values in integer registers. To force it be passed in memory, the frontend
 
183
should change the function signiture to:
 
184
    void %test(long %undef1, long %undef2, long %undef3, long %undef4, 
 
185
               long %undef5, long %undef6,
 
186
               long %s.i, byte %s.j, long %s.d);
 
187
And the callee would look something like this:
 
188
    call void %test( undef, undef, undef, undef, undef, undef,
 
189
                     %tmp.s.i, %tmp.s.j, %tmp.s.d );
 
190
The first 6 undef parameters would exhaust the 6 integer registers used for
 
191
parameter passing. The following three integer values would then be forced into
 
192
memory.
 
193
 
 
194
For problem 4, the parameter 'd' would be moved to the front of the parameter
 
195
list so it will be passed in register:
 
196
    void %test(int %d,
 
197
               long %undef1, long %undef2, long %undef3, long %undef4, 
 
198
               long %undef5, long %undef6,
 
199
               long %s.i, byte %s.j, long %s.d);
 
200
 
 
201
//===---------------------------------------------------------------------===//
 
202
 
 
203
Right now the asm printer assumes GlobalAddress are accessed via RIP relative
 
204
addressing. Therefore, it is not possible to generate this:
 
205
        movabsq $__ZTV10polynomialIdE+16, %rax
 
206
 
 
207
That is ok for now since we currently only support small model. So the above
 
208
is selected as
 
209
        leaq __ZTV10polynomialIdE+16(%rip), %rax
 
210
 
 
211
This is probably slightly slower but is much shorter than movabsq. However, if
 
212
we were to support medium or larger code models, we need to use the movabs
 
213
instruction. We should probably introduce something like AbsoluteAddress to
 
214
distinguish it from GlobalAddress so the asm printer and JIT code emitter can
 
215
do the right thing.
 
216
 
 
217
//===---------------------------------------------------------------------===//
 
218
 
 
219
It's not possible to reference AH, BH, CH, and DH registers in an instruction
 
220
requiring REX prefix. However, divb and mulb both produce results in AH. If isel
 
221
emits a CopyFromReg which gets turned into a movb and that can be allocated a
 
222
r8b - r15b.
 
223
 
 
224
To get around this, isel emits a CopyFromReg from AX and then right shift it
 
225
down by 8 and truncate it. It's not pretty but it works. We need some register
 
226
allocation magic to make the hack go away (e.g. putting additional constraints
 
227
on the result of the movb).
 
228
 
 
229
//===---------------------------------------------------------------------===//
 
230
 
 
231
The x86-64 ABI for hidden-argument struct returns requires that the
 
232
incoming value of %rdi be copied into %rax by the callee upon return.
 
233
 
 
234
The idea is that it saves callers from having to remember this value,
 
235
which would often require a callee-saved register. Callees usually
 
236
need to keep this value live for most of their body anyway, so it
 
237
doesn't add a significant burden on them.
 
238
 
 
239
We currently implement this in codegen, however this is suboptimal
 
240
because it means that it would be quite awkward to implement the
 
241
optimization for callers.
 
242
 
 
243
A better implementation would be to relax the LLVM IR rules for sret
 
244
arguments to allow a function with an sret argument to have a non-void
 
245
return type, and to have the front-end to set up the sret argument value
 
246
as the return value of the function. The front-end could more easily
 
247
emit uses of the returned struct value to be in terms of the function's
 
248
lowered return value, and it would free non-C frontends from a
 
249
complication only required by a C-based ABI.
 
250
 
 
251
//===---------------------------------------------------------------------===//
 
252
 
 
253
We get a redundant zero extension for code like this:
 
254
 
 
255
int mask[1000];
 
256
int foo(unsigned x) {
 
257
 if (x < 10)
 
258
   x = x * 45;
 
259
 else
 
260
   x = x * 78;
 
261
 return mask[x];
 
262
}
 
263
 
 
264
_foo:
 
265
LBB1_0: ## entry
 
266
        cmpl    $9, %edi
 
267
        jbe     LBB1_3  ## bb
 
268
LBB1_1: ## bb1
 
269
        imull   $78, %edi, %eax
 
270
LBB1_2: ## bb2
 
271
        movl    %eax, %eax                    <----
 
272
        movq    _mask@GOTPCREL(%rip), %rcx
 
273
        movl    (%rcx,%rax,4), %eax
 
274
        ret
 
275
LBB1_3: ## bb
 
276
        imull   $45, %edi, %eax
 
277
        jmp     LBB1_2  ## bb2
 
278
  
 
279
Before regalloc, we have:
 
280
 
 
281
        %reg1025<def> = IMUL32rri8 %reg1024, 45, %EFLAGS<imp-def>
 
282
        JMP mbb<bb2,0x203afb0>
 
283
    Successors according to CFG: 0x203afb0 (#3)
 
284
 
 
285
bb1: 0x203af60, LLVM BB @0x1e02310, ID#2:
 
286
    Predecessors according to CFG: 0x203aec0 (#0)
 
287
        %reg1026<def> = IMUL32rri8 %reg1024, 78, %EFLAGS<imp-def>
 
288
    Successors according to CFG: 0x203afb0 (#3)
 
289
 
 
290
bb2: 0x203afb0, LLVM BB @0x1e02340, ID#3:
 
291
    Predecessors according to CFG: 0x203af10 (#1) 0x203af60 (#2)
 
292
        %reg1027<def> = PHI %reg1025, mbb<bb,0x203af10>,
 
293
                            %reg1026, mbb<bb1,0x203af60>
 
294
        %reg1029<def> = MOVZX64rr32 %reg1027
 
295
 
 
296
so we'd have to know that IMUL32rri8 leaves the high word zero extended and to
 
297
be able to recognize the zero extend.  This could also presumably be implemented
 
298
if we have whole-function selectiondags.
 
299
 
 
300
//===---------------------------------------------------------------------===//