brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · d9cc086 Raw
262 lines · plain
1//===---------------------------------------------------------------------===//2// Random ideas for the ARM backend (Thumb specific).3//===---------------------------------------------------------------------===//4 5* Add support for compiling functions in both ARM and Thumb mode, then taking6  the smallest.7 8* Add support for compiling individual basic blocks in thumb mode, when in a 9  larger ARM function.  This can be used for presumed cold code, like paths10  to abort (failure path of asserts), EH handling code, etc.11 12* Thumb doesn't have normal pre/post increment addressing modes, but you can13  load/store 32-bit integers with pre/postinc by using load/store multiple14  instrs with a single register.15 16* Make better use of high registers r8, r10, r11, r12 (ip). Some variants of add17  and cmp instructions can use high registers. Also, we can use them as18  temporaries to spill values into.19 20* In thumb mode, short, byte, and bool preferred alignments are currently set21  to 4 to accommodate ISA restriction (i.e. add sp, #imm, imm must be multiple22  of 4).23 24//===---------------------------------------------------------------------===//25 26Potential jumptable improvements:27 28* If we know function size is less than (1 << 16) * 2 bytes, we can use 16-bit29  jumptable entries (e.g. (L1 - L2) >> 1). Or even smaller entries if the30  function is even smaller. This also applies to ARM.31 32* Thumb jumptable codegen can improve given some help from the assembler. This33  is what we generate right now:34 35	.set PCRELV0, (LJTI1_0_0-(LPCRELL0+4))36LPCRELL0:37	mov r1, #PCRELV038	add r1, pc39	ldr r0, [r0, r1]40	mov pc, r0 41	.align	242LJTI1_0_0:43	.long	 LBB1_344        ...45 46Note there is another pc relative add that we can take advantage of.47     add r1, pc, #imm_8 * 448 49We should be able to generate:50 51LPCRELL0:52	add r1, LJTI1_0_053	ldr r0, [r0, r1]54	mov pc, r0 55	.align	256LJTI1_0_0:57	.long	 LBB1_358 59if the assembler can translate the add to:60       add r1, pc, #((LJTI1_0_0-(LPCRELL0+4))&0xfffffffc)61 62Note the assembler also does something similar to constpool load:63LPCRELL0:64     ldr r0, LCPI1_065=>66     ldr r0, pc, #((LCPI1_0-(LPCRELL0+4))&0xfffffffc)67 68 69//===---------------------------------------------------------------------===//70 71We compile the following:72 73define i16 @func_entry_2E_ce(i32 %i) {74        switch i32 %i, label %bb12.exitStub [75                 i32 0, label %bb4.exitStub76                 i32 1, label %bb9.exitStub77                 i32 2, label %bb4.exitStub78                 i32 3, label %bb4.exitStub79                 i32 7, label %bb9.exitStub80                 i32 8, label %bb.exitStub81                 i32 9, label %bb9.exitStub82        ]83 84bb12.exitStub:85        ret i16 086 87bb4.exitStub:88        ret i16 189 90bb9.exitStub:91        ret i16 292 93bb.exitStub:94        ret i16 395}96 97into:98 99_func_entry_2E_ce:100        mov r2, #1101        lsl r2, r0102        cmp r0, #9103        bhi LBB1_4      @bb12.exitStub104LBB1_1: @newFuncRoot105        mov r1, #13106        tst r2, r1107        bne LBB1_5      @bb4.exitStub108LBB1_2: @newFuncRoot109        ldr r1, LCPI1_0110        tst r2, r1111        bne LBB1_6      @bb9.exitStub112LBB1_3: @newFuncRoot113        mov r1, #1114        lsl r1, r1, #8115        tst r2, r1116        bne LBB1_7      @bb.exitStub117LBB1_4: @bb12.exitStub118        mov r0, #0119        bx lr120LBB1_5: @bb4.exitStub121        mov r0, #1122        bx lr123LBB1_6: @bb9.exitStub124        mov r0, #2125        bx lr126LBB1_7: @bb.exitStub127        mov r0, #3128        bx lr129LBB1_8:130        .align  2131LCPI1_0:132        .long   642133 134 135gcc compiles to:136 137	cmp	r0, #9138	@ lr needed for prologue139	bhi	L2140	ldr	r3, L11141	mov	r2, #1142	mov	r1, r2, asl r0143	ands	r0, r3, r2, asl r0144	movne	r0, #2145	bxne	lr146	tst	r1, #13147	beq	L9148L3:149	mov	r0, r2150	bx	lr151L9:152	tst	r1, #256153	movne	r0, #3154	bxne	lr155L2:156	mov	r0, #0157	bx	lr158L12:159	.align 2160L11:161	.long	642162        163 164GCC is doing a couple of clever things here:165  1. It is predicating one of the returns.  This isn't a clear win though: in166     cases where that return isn't taken, it is replacing one condbranch with167     two 'ne' predicated instructions.168  2. It is sinking the shift of "1 << i" into the tst, and using ands instead of169     tst.  This will probably require whole function isel.170  3. GCC emits:171  	tst	r1, #256172     we emit:173        mov r1, #1174        lsl r1, r1, #8175        tst r2, r1176 177//===---------------------------------------------------------------------===//178 179When spilling in thumb mode and the sp offset is too large to fit in the ldr /180str offset field, we load the offset from a constpool entry and add it to sp:181 182ldr r2, LCPI183add r2, sp184ldr r2, [r2]185 186These instructions preserve the condition code which is important if the spill187is between a cmp and a bcc instruction. However, we can use the (potentially)188cheaper sequence if we know it's ok to clobber the condition register.189 190add r2, sp, #255 * 4191add r2, #132192ldr r2, [r2, #7 * 4]193 194This is especially bad when dynamic alloca is used. The all fixed size stack195objects are referenced off the frame pointer with negative offsets. See196oggenc for an example.197 198//===---------------------------------------------------------------------===//199 200Poor codegen test/CodeGen/ARM/select.ll f7:201 202	ldr r5, LCPI1_0203LPC0:204	add r5, pc205	ldr r6, LCPI1_1206	ldr r2, LCPI1_2207	mov r3, r6208	mov lr, pc209	bx r5210 211//===---------------------------------------------------------------------===//212 213Make register allocator / spiller smarter so we can re-materialize "mov r, imm",214etc. Almost all Thumb instructions clobber condition code.215 216//===---------------------------------------------------------------------===//217 218Thumb load / store address mode offsets are scaled. The values kept in the219instruction operands are pre-scale values. This probably ought to be changed220to avoid extra work when we convert Thumb2 instructions to Thumb1 instructions.221 222//===---------------------------------------------------------------------===//223 224We need to make (some of the) Thumb1 instructions predicable. That will allow225shrinking of predicated Thumb2 instructions. To allow this, we need to be able226to toggle the 's' bit since they do not set CPSR when they are inside IT blocks.227 228//===---------------------------------------------------------------------===//229 230Make use of hi register variants of cmp: tCMPhir / tCMPZhir.231 232//===---------------------------------------------------------------------===//233 234Thumb1 immediate field sometimes keep pre-scaled values. See235ThumbRegisterInfo::eliminateFrameIndex. This is inconsistent from ARM and236Thumb2.237 238//===---------------------------------------------------------------------===//239 240Rather than having tBR_JTr print a ".align 2" and constant island pass pad it,241add a target specific ALIGN instruction instead. That way, getInstSizeInBytes242won't have to over-estimate. It can also be used for loop alignment pass.243 244//===---------------------------------------------------------------------===//245 246We generate conditional code for icmp when we don't need to. This code:247 248  int foo(int s) {249    return s == 1;250  }251 252produces:253 254foo:255        cmp     r0, #1256        mov.w   r0, #0257        it      eq258        moveq   r0, #1259        bx      lr260 261when it could use subs + adcs. This is GCC PR46975.262