1 //===---------------------------------------------------------------------===// 2 // Random ideas for the ARM backend. 3 //===---------------------------------------------------------------------===// 4 5 Reimplement 'select' in terms of 'SEL'. 6 7 * We would really like to support UXTAB16, but we need to prove that the 8 add doesn't need to overflow between the two 16-bit chunks. 9 10 * Implement pre/post increment support. (e.g. PR935) 11 * Implement smarter constant generation for binops with large immediates. 12 13 A few ARMv6T2 ops should be pattern matched: BFI, SBFX, and UBFX 14 15 Interesting optimization for PIC codegen on arm-linux: 16 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43129 17 18 //===---------------------------------------------------------------------===// 19 20 Crazy idea: Consider code that uses lots of 8-bit or 16-bit values. By the 21 time regalloc happens, these values are now in a 32-bit register, usually with 22 the top-bits known to be sign or zero extended. If spilled, we should be able 23 to spill these to a 8-bit or 16-bit stack slot, zero or sign extending as part 24 of the reload. 25 26 Doing this reduces the size of the stack frame (important for thumb etc), and 27 also increases the likelihood that we will be able to reload multiple values 28 from the stack with a single load. 29 30 //===---------------------------------------------------------------------===// 31 32 The constant island pass is in good shape. Some cleanups might be desirable, 33 but there is unlikely to be much improvement in the generated code. 34 35 1. There may be some advantage to trying to be smarter about the initial 36 placement, rather than putting everything at the end. 37 38 2. There might be some compile-time efficiency to be had by representing 39 consecutive islands as a single block rather than multiple blocks. 40 41 3. Use a priority queue to sort constant pool users in inverse order of 42 position so we always process the one closed to the end of functions 43 first. This may simply CreateNewWater. 44 45 //===---------------------------------------------------------------------===// 46 47 Eliminate copysign custom expansion. We are still generating crappy code with 48 default expansion + if-conversion. 49 50 //===---------------------------------------------------------------------===// 51 52 Eliminate one instruction from: 53 54 define i32 @_Z6slow4bii(i32 %x, i32 %y) { 55 %tmp = icmp sgt i32 %x, %y 56 %retval = select i1 %tmp, i32 %x, i32 %y 57 ret i32 %retval 58 } 59 60 __Z6slow4bii: 61 cmp r0, r1 62 movgt r1, r0 63 mov r0, r1 64 bx lr 65 => 66 67 __Z6slow4bii: 68 cmp r0, r1 69 movle r0, r1 70 bx lr 71 72 //===---------------------------------------------------------------------===// 73 74 Implement long long "X-3" with instructions that fold the immediate in. These 75 were disabled due to badness with the ARM carry flag on subtracts. 76 77 //===---------------------------------------------------------------------===// 78 79 More load / store optimizations: 80 1) Better representation for block transfer? This is from Olden/power: 81 82 fldd d0, [r4] 83 fstd d0, [r4, #+32] 84 fldd d0, [r4, #+8] 85 fstd d0, [r4, #+40] 86 fldd d0, [r4, #+16] 87 fstd d0, [r4, #+48] 88 fldd d0, [r4, #+24] 89 fstd d0, [r4, #+56] 90 91 If we can spare the registers, it would be better to use fldm and fstm here. 92 Need major register allocator enhancement though. 93 94 2) Can we recognize the relative position of constantpool entries? i.e. Treat 95 96 ldr r0, LCPI17_3 97 ldr r1, LCPI17_4 98 ldr r2, LCPI17_5 99 100 as 101 ldr r0, LCPI17 102 ldr r1, LCPI17+4 103 ldr r2, LCPI17+8 104 105 Then the ldr's can be combined into a single ldm. See Olden/power. 106 107 Note for ARM v4 gcc uses ldmia to load a pair of 32-bit values to represent a 108 double 64-bit FP constant: 109 110 adr r0, L6 111 ldmia r0, {r0-r1} 112 113 .align 2 114 L6: 115 .long -858993459 116 .long 1074318540 117 118 3) struct copies appear to be done field by field 119 instead of by words, at least sometimes: 120 121 struct foo { int x; short s; char c1; char c2; }; 122 void cpy(struct foo*a, struct foo*b) { *a = *b; } 123 124 llvm code (-O2) 125 ldrb r3, [r1, #+6] 126 ldr r2, [r1] 127 ldrb r12, [r1, #+7] 128 ldrh r1, [r1, #+4] 129 str r2, [r0] 130 strh r1, [r0, #+4] 131 strb r3, [r0, #+6] 132 strb r12, [r0, #+7] 133 gcc code (-O2) 134 ldmia r1, {r1-r2} 135 stmia r0, {r1-r2} 136 137 In this benchmark poor handling of aggregate copies has shown up as 138 having a large effect on size, and possibly speed as well (we don't have 139 a good way to measure on ARM). 140 141 //===---------------------------------------------------------------------===// 142 143 * Consider this silly example: 144 145 double bar(double x) { 146 double r = foo(3.1); 147 return x+r; 148 } 149 150 _bar: 151 stmfd sp!, {r4, r5, r7, lr} 152 add r7, sp, #8 153 mov r4, r0 154 mov r5, r1 155 fldd d0, LCPI1_0 156 fmrrd r0, r1, d0 157 bl _foo 158 fmdrr d0, r4, r5 159 fmsr s2, r0 160 fsitod d1, s2 161 faddd d0, d1, d0 162 fmrrd r0, r1, d0 163 ldmfd sp!, {r4, r5, r7, pc} 164 165 Ignore the prologue and epilogue stuff for a second. Note 166 mov r4, r0 167 mov r5, r1 168 the copys to callee-save registers and the fact they are only being used by the 169 fmdrr instruction. It would have been better had the fmdrr been scheduled 170 before the call and place the result in a callee-save DPR register. The two 171 mov ops would not have been necessary. 172 173 //===---------------------------------------------------------------------===// 174 175 Calling convention related stuff: 176 177 * gcc's parameter passing implementation is terrible and we suffer as a result: 178 179 e.g. 180 struct s { 181 double d1; 182 int s1; 183 }; 184 185 void foo(struct s S) { 186 printf("%g, %d\n", S.d1, S.s1); 187 } 188 189 'S' is passed via registers r0, r1, r2. But gcc stores them to the stack, and 190 then reload them to r1, r2, and r3 before issuing the call (r0 contains the 191 address of the format string): 192 193 stmfd sp!, {r7, lr} 194 add r7, sp, #0 195 sub sp, sp, #12 196 stmia sp, {r0, r1, r2} 197 ldmia sp, {r1-r2} 198 ldr r0, L5 199 ldr r3, [sp, #8] 200 L2: 201 add r0, pc, r0 202 bl L_printf$stub 203 204 Instead of a stmia, ldmia, and a ldr, wouldn't it be better to do three moves? 205 206 * Return an aggregate type is even worse: 207 208 e.g. 209 struct s foo(void) { 210 struct s S = {1.1, 2}; 211 return S; 212 } 213 214 mov ip, r0 215 ldr r0, L5 216 sub sp, sp, #12 217 L2: 218 add r0, pc, r0 219 @ lr needed for prologue 220 ldmia r0, {r0, r1, r2} 221 stmia sp, {r0, r1, r2} 222 stmia ip, {r0, r1, r2} 223 mov r0, ip 224 add sp, sp, #12 225 bx lr 226 227 r0 (and later ip) is the hidden parameter from caller to store the value in. The 228 first ldmia loads the constants into r0, r1, r2. The last stmia stores r0, r1, 229 r2 into the address passed in. However, there is one additional stmia that 230 stores r0, r1, and r2 to some stack location. The store is dead. 231 232 The llvm-gcc generated code looks like this: 233 234 csretcc void %foo(%struct.s* %agg.result) { 235 entry: 236 %S = alloca %struct.s, align 4 ; <%struct.s*> [#uses=1] 237 %memtmp = alloca %struct.s ; <%struct.s*> [#uses=1] 238 cast %struct.s* %S to sbyte* ; <sbyte*>:0 [#uses=2] 239 call void %llvm.memcpy.i32( sbyte* %0, sbyte* cast ({ double, int }* %C.0.904 to sbyte*), uint 12, uint 4 ) 240 cast %struct.s* %agg.result to sbyte* ; <sbyte*>:1 [#uses=2] 241 call void %llvm.memcpy.i32( sbyte* %1, sbyte* %0, uint 12, uint 0 ) 242 cast %struct.s* %memtmp to sbyte* ; <sbyte*>:2 [#uses=1] 243 call void %llvm.memcpy.i32( sbyte* %2, sbyte* %1, uint 12, uint 0 ) 244 ret void 245 } 246 247 llc ends up issuing two memcpy's (the first memcpy becomes 3 loads from 248 constantpool). Perhaps we should 1) fix llvm-gcc so the memcpy is translated 249 into a number of load and stores, or 2) custom lower memcpy (of small size) to 250 be ldmia / stmia. I think option 2 is better but the current register 251 allocator cannot allocate a chunk of registers at a time. 252 253 A feasible temporary solution is to use specific physical registers at the 254 lowering time for small (<= 4 words?) transfer size. 255 256 * ARM CSRet calling convention requires the hidden argument to be returned by 257 the callee. 258 259 //===---------------------------------------------------------------------===// 260 261 We can definitely do a better job on BB placements to eliminate some branches. 262 It's very common to see llvm generated assembly code that looks like this: 263 264 LBB3: 265 ... 266 LBB4: 267 ... 268 beq LBB3 269 b LBB2 270 271 If BB4 is the only predecessor of BB3, then we can emit BB3 after BB4. We can 272 then eliminate beq and and turn the unconditional branch to LBB2 to a bne. 273 274 See McCat/18-imp/ComputeBoundingBoxes for an example. 275 276 //===---------------------------------------------------------------------===// 277 278 Pre-/post- indexed load / stores: 279 280 1) We should not make the pre/post- indexed load/store transform if the base ptr 281 is guaranteed to be live beyond the load/store. This can happen if the base 282 ptr is live out of the block we are performing the optimization. e.g. 283 284 mov r1, r2 285 ldr r3, [r1], #4 286 ... 287 288 vs. 289 290 ldr r3, [r2] 291 add r1, r2, #4 292 ... 293 294 In most cases, this is just a wasted optimization. However, sometimes it can 295 negatively impact the performance because two-address code is more restrictive 296 when it comes to scheduling. 297 298 Unfortunately, liveout information is currently unavailable during DAG combine 299 time. 300 301 2) Consider spliting a indexed load / store into a pair of add/sub + load/store 302 to solve #1 (in TwoAddressInstructionPass.cpp). 303 304 3) Enhance LSR to generate more opportunities for indexed ops. 305 306 4) Once we added support for multiple result patterns, write indexed loads 307 patterns instead of C++ instruction selection code. 308 309 5) Use VLDM / VSTM to emulate indexed FP load / store. 310 311 //===---------------------------------------------------------------------===// 312 313 Implement support for some more tricky ways to materialize immediates. For 314 example, to get 0xffff8000, we can use: 315 316 mov r9, #&3f8000 317 sub r9, r9, #&400000 318 319 //===---------------------------------------------------------------------===// 320 321 We sometimes generate multiple add / sub instructions to update sp in prologue 322 and epilogue if the inc / dec value is too large to fit in a single immediate 323 operand. In some cases, perhaps it might be better to load the value from a 324 constantpool instead. 325 326 //===---------------------------------------------------------------------===// 327 328 GCC generates significantly better code for this function. 329 330 int foo(int StackPtr, unsigned char *Line, unsigned char *Stack, int LineLen) { 331 int i = 0; 332 333 if (StackPtr != 0) { 334 while (StackPtr != 0 && i < (((LineLen) < (32768))? (LineLen) : (32768))) 335 Line[i++] = Stack[--StackPtr]; 336 if (LineLen > 32768) 337 { 338 while (StackPtr != 0 && i < LineLen) 339 { 340 i++; 341 --StackPtr; 342 } 343 } 344 } 345 return StackPtr; 346 } 347 348 //===---------------------------------------------------------------------===// 349 350 This should compile to the mlas instruction: 351 int mlas(int x, int y, int z) { return ((x * y + z) < 0) ? 7 : 13; } 352 353 //===---------------------------------------------------------------------===// 354 355 At some point, we should triage these to see if they still apply to us: 356 357 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19598 358 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18560 359 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27016 360 361 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11831 362 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11826 363 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11825 364 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11824 365 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11823 366 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11820 367 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10982 368 369 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10242 370 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9831 371 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9760 372 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9759 373 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9703 374 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9702 375 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9663 376 377 http://www.inf.u-szeged.hu/gcc-arm/ 378 http://citeseer.ist.psu.edu/debus04linktime.html 379 380 //===---------------------------------------------------------------------===// 381 382 gcc generates smaller code for this function at -O2 or -Os: 383 384 void foo(signed char* p) { 385 if (*p == 3) 386 bar(); 387 else if (*p == 4) 388 baz(); 389 else if (*p == 5) 390 quux(); 391 } 392 393 llvm decides it's a good idea to turn the repeated if...else into a 394 binary tree, as if it were a switch; the resulting code requires -1 395 compare-and-branches when *p<=2 or *p==5, the same number if *p==4 396 or *p>6, and +1 if *p==3. So it should be a speed win 397 (on balance). However, the revised code is larger, with 4 conditional 398 branches instead of 3. 399 400 More seriously, there is a byte->word extend before 401 each comparison, where there should be only one, and the condition codes 402 are not remembered when the same two values are compared twice. 403 404 //===---------------------------------------------------------------------===// 405 406 More LSR enhancements possible: 407 408 1. Teach LSR about pre- and post- indexed ops to allow iv increment be merged 409 in a load / store. 410 2. Allow iv reuse even when a type conversion is required. For example, i8 411 and i32 load / store addressing modes are identical. 412 413 414 //===---------------------------------------------------------------------===// 415 416 This: 417 418 int foo(int a, int b, int c, int d) { 419 long long acc = (long long)a * (long long)b; 420 acc += (long long)c * (long long)d; 421 return (int)(acc >> 32); 422 } 423 424 Should compile to use SMLAL (Signed Multiply Accumulate Long) which multiplies 425 two signed 32-bit values to produce a 64-bit value, and accumulates this with 426 a 64-bit value. 427 428 We currently get this with both v4 and v6: 429 430 _foo: 431 smull r1, r0, r1, r0 432 smull r3, r2, r3, r2 433 adds r3, r3, r1 434 adc r0, r2, r0 435 bx lr 436 437 //===---------------------------------------------------------------------===// 438 439 This: 440 #include <algorithm> 441 std::pair<unsigned, bool> full_add(unsigned a, unsigned b) 442 { return std::make_pair(a + b, a + b < a); } 443 bool no_overflow(unsigned a, unsigned b) 444 { return !full_add(a, b).second; } 445 446 Should compile to: 447 448 _Z8full_addjj: 449 adds r2, r1, r2 450 movcc r1, #0 451 movcs r1, #1 452 str r2, [r0, #0] 453 strb r1, [r0, #4] 454 mov pc, lr 455 456 _Z11no_overflowjj: 457 cmn r0, r1 458 movcs r0, #0 459 movcc r0, #1 460 mov pc, lr 461 462 not: 463 464 __Z8full_addjj: 465 add r3, r2, r1 466 str r3, [r0] 467 mov r2, #1 468 mov r12, #0 469 cmp r3, r1 470 movlo r12, r2 471 str r12, [r0, #+4] 472 bx lr 473 __Z11no_overflowjj: 474 add r3, r1, r0 475 mov r2, #1 476 mov r1, #0 477 cmp r3, r0 478 movhs r1, r2 479 mov r0, r1 480 bx lr 481 482 //===---------------------------------------------------------------------===// 483 484 Some of the NEON intrinsics may be appropriate for more general use, either 485 as target-independent intrinsics or perhaps elsewhere in the ARM backend. 486 Some of them may also be lowered to target-independent SDNodes, and perhaps 487 some new SDNodes could be added. 488 489 For example, maximum, minimum, and absolute value operations are well-defined 490 and standard operations, both for vector and scalar types. 491 492 The current NEON-specific intrinsics for count leading zeros and count one 493 bits could perhaps be replaced by the target-independent ctlz and ctpop 494 intrinsics. It may also make sense to add a target-independent "ctls" 495 intrinsic for "count leading sign bits". Likewise, the backend could use 496 the target-independent SDNodes for these operations. 497 498 ARMv6 has scalar saturating and halving adds and subtracts. The same 499 intrinsics could possibly be used for both NEON's vector implementations of 500 those operations and the ARMv6 scalar versions. 501 502 //===---------------------------------------------------------------------===// 503 504 ARM::MOVCCr is commutable (by flipping the condition). But we need to implement 505 ARMInstrInfo::commuteInstruction() to support it. 506 507 //===---------------------------------------------------------------------===// 508 509 Split out LDR (literal) from normal ARM LDR instruction. Also consider spliting 510 LDR into imm12 and so_reg forms. This allows us to clean up some code. e.g. 511 ARMLoadStoreOptimizer does not need to look at LDR (literal) and LDR (so_reg) 512 while ARMConstantIslandPass only need to worry about LDR (literal). 513 514 //===---------------------------------------------------------------------===// 515 516 Constant island pass should make use of full range SoImm values for LEApcrel. 517 Be careful though as the last attempt caused infinite looping on lencod. 518 519 //===---------------------------------------------------------------------===// 520 521 Predication issue. This function: 522 523 extern unsigned array[ 128 ]; 524 int foo( int x ) { 525 int y; 526 y = array[ x & 127 ]; 527 if ( x & 128 ) 528 y = 123456789 & ( y >> 2 ); 529 else 530 y = 123456789 & y; 531 return y; 532 } 533 534 compiles to: 535 536 _foo: 537 and r1, r0, #127 538 ldr r2, LCPI1_0 539 ldr r2, [r2] 540 ldr r1, [r2, +r1, lsl #2] 541 mov r2, r1, lsr #2 542 tst r0, #128 543 moveq r2, r1 544 ldr r0, LCPI1_1 545 and r0, r2, r0 546 bx lr 547 548 It would be better to do something like this, to fold the shift into the 549 conditional move: 550 551 and r1, r0, #127 552 ldr r2, LCPI1_0 553 ldr r2, [r2] 554 ldr r1, [r2, +r1, lsl #2] 555 tst r0, #128 556 movne r1, r1, lsr #2 557 ldr r0, LCPI1_1 558 and r0, r1, r0 559 bx lr 560 561 it saves an instruction and a register. 562 563 //===---------------------------------------------------------------------===// 564 565 It might be profitable to cse MOVi16 if there are lots of 32-bit immediates 566 with the same bottom half. 567 568 //===---------------------------------------------------------------------===// 569 570 Robert Muth started working on an alternate jump table implementation that 571 does not put the tables in-line in the text. This is more like the llvm 572 default jump table implementation. This might be useful sometime. Several 573 revisions of patches are on the mailing list, beginning at: 574 http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/022763.html 575 576 //===---------------------------------------------------------------------===// 577 578 Make use of the "rbit" instruction. 579 580 //===---------------------------------------------------------------------===// 581 582 Take a look at test/CodeGen/Thumb2/machine-licm.ll. ARM should be taught how 583 to licm and cse the unnecessary load from cp#1. 584 585 //===---------------------------------------------------------------------===// 586 587 The CMN instruction sets the flags like an ADD instruction, while CMP sets 588 them like a subtract. Therefore to be able to use CMN for comparisons other 589 than the Z bit, we'll need additional logic to reverse the conditionals 590 associated with the comparison. Perhaps a pseudo-instruction for the comparison, 591 with a post-codegen pass to clean up and handle the condition codes? 592 See PR5694 for testcase. 593 594 //===---------------------------------------------------------------------===// 595 596 Given the following on armv5: 597 int test1(int A, int B) { 598 return (A&-8388481)|(B&8388480); 599 } 600 601 We currently generate: 602 ldr r2, .LCPI0_0 603 and r0, r0, r2 604 ldr r2, .LCPI0_1 605 and r1, r1, r2 606 orr r0, r1, r0 607 bx lr 608 609 We should be able to replace the second ldr+and with a bic (i.e. reuse the 610 constant which was already loaded). Not sure what's necessary to do that. 611 612 //===---------------------------------------------------------------------===// 613 614 The code generated for bswap on armv4/5 (CPUs without rev) is less than ideal: 615 616 int a(int x) { return __builtin_bswap32(x); } 617 618 a: 619 mov r1, #255, 24 620 mov r2, #255, 16 621 and r1, r1, r0, lsr #8 622 and r2, r2, r0, lsl #8 623 orr r1, r1, r0, lsr #24 624 orr r0, r2, r0, lsl #24 625 orr r0, r0, r1 626 bx lr 627 628 Something like the following would be better (fewer instructions/registers): 629 eor r1, r0, r0, ror #16 630 bic r1, r1, #0xff0000 631 mov r1, r1, lsr #8 632 eor r0, r1, r0, ror #8 633 bx lr 634 635 A custom Thumb version would also be a slight improvement over the generic 636 version. 637 638 //===---------------------------------------------------------------------===// 639 640 Consider the following simple C code: 641 642 void foo(unsigned char *a, unsigned char *b, int *c) { 643 if ((*a | *b) == 0) *c = 0; 644 } 645 646 currently llvm-gcc generates something like this (nice branchless code I'd say): 647 648 ldrb r0, [r0] 649 ldrb r1, [r1] 650 orr r0, r1, r0 651 tst r0, #255 652 moveq r0, #0 653 streq r0, [r2] 654 bx lr 655 656 Note that both "tst" and "moveq" are redundant. 657 658 //===---------------------------------------------------------------------===// 659 660 When loading immediate constants with movt/movw, if there are multiple 661 constants needed with the same low 16 bits, and those values are not live at 662 the same time, it would be possible to use a single movw instruction, followed 663 by multiple movt instructions to rewrite the high bits to different values. 664 For example: 665 666 volatile store i32 -1, i32* inttoptr (i32 1342210076 to i32*), align 4, 667 !tbaa 668 !0 669 volatile store i32 -1, i32* inttoptr (i32 1342341148 to i32*), align 4, 670 !tbaa 671 !0 672 673 is compiled and optimized to: 674 675 movw r0, #32796 676 mov.w r1, #-1 677 movt r0, #20480 678 str r1, [r0] 679 movw r0, #32796 @ <= this MOVW is not needed, value is there already 680 movt r0, #20482 681 str r1, [r0] 682 683 //===---------------------------------------------------------------------===// 684 685 Improve codegen for select's: 686 if (x != 0) x = 1 687 if (x == 1) x = 1 688 689 ARM codegen used to look like this: 690 mov r1, r0 691 cmp r1, #1 692 mov r0, #0 693 moveq r0, #1 694 695 The naive lowering select between two different values. It should recognize the 696 test is equality test so it's more a conditional move rather than a select: 697 cmp r0, #1 698 movne r0, #0 699 700 Currently this is a ARM specific dag combine. We probably should make it into a 701 target-neutral one. 702