* Add support for compiling functions in both ARM and Thumb mode, then taking
the smallest.
+
* Add support for compiling individual basic blocks in thumb mode, when in a
larger ARM function. This can be used for presumed cold code, like paths
to abort (failure path of asserts), EH handling code, etc.
//===---------------------------------------------------------------------===//
-We compiles the following using a jump table.
+We compiles the following:
define i16 @func_entry_2E_ce(i32 %i) {
-newFuncRoot:
- br label %entry.ce
-
-bb12.exitStub: ; preds = %entry.ce
- ret i16 0
-
-bb4.exitStub: ; preds = %entry.ce, %entry.ce, %entry.ce
- ret i16 1
-
-bb9.exitStub: ; preds = %entry.ce, %entry.ce, %entry.ce
- ret i16 2
-
-bb.exitStub: ; preds = %entry.ce
- ret i16 3
-
-entry.ce: ; preds = %newFuncRoot
switch i32 %i, label %bb12.exitStub [
i32 0, label %bb4.exitStub
i32 1, label %bb9.exitStub
i32 8, label %bb.exitStub
i32 9, label %bb9.exitStub
]
+
+bb12.exitStub:
+ ret i16 0
+
+bb4.exitStub:
+ ret i16 1
+
+bb9.exitStub:
+ ret i16 2
+
+bb.exitStub:
+ ret i16 3
}
+into:
+
+_func_entry_2E_ce:
+ mov r2, #1
+ lsl r2, r0
+ cmp r0, #9
+ bhi LBB1_4 @bb12.exitStub
+LBB1_1: @newFuncRoot
+ mov r1, #13
+ tst r2, r1
+ bne LBB1_5 @bb4.exitStub
+LBB1_2: @newFuncRoot
+ ldr r1, LCPI1_0
+ tst r2, r1
+ bne LBB1_6 @bb9.exitStub
+LBB1_3: @newFuncRoot
+ mov r1, #1
+ lsl r1, r1, #8
+ tst r2, r1
+ bne LBB1_7 @bb.exitStub
+LBB1_4: @bb12.exitStub
+ mov r0, #0
+ bx lr
+LBB1_5: @bb4.exitStub
+ mov r0, #1
+ bx lr
+LBB1_6: @bb9.exitStub
+ mov r0, #2
+ bx lr
+LBB1_7: @bb.exitStub
+ mov r0, #3
+ bx lr
+LBB1_8:
+ .align 2
+LCPI1_0:
+ .long 642
+
+
gcc compiles to:
cmp r0, #9
.align 2
L11:
.long 642
+
+
+GCC is doing a couple of clever things here:
+ 1. It is predicating one of the returns. This isn't a clear win though: in
+ cases where that return isn't taken, it is replacing one condbranch with
+ two 'ne' predicated instructions.
+ 2. It is sinking the shift of "1 << i" into the tst, and using ands instead of
+ tst. This will probably require whole function isel.
+ 3. GCC emits:
+ tst r1, #256
+ we emit:
+ mov r1, #1
+ lsl r1, r1, #8
+ tst r2, r1
+
//===---------------------------------------------------------------------===//
(when hasFP is true or stack size is large) and restore R3 from that register
instead. This allows us to at least get rid of the save to r12 everytime it is
used.
+
+//===---------------------------------------------------------------------===//
+
+Poor codegen test/CodeGen/ARM/select.ll f7:
+
+ ldr r5, LCPI1_0
+LPC0:
+ add r5, pc
+ ldr r6, LCPI1_1
+ ldr r2, LCPI1_2
+ cpy r3, r6
+ cpy lr, pc
+ bx r5
+
+//===---------------------------------------------------------------------===//
+
+Make register allocator / spiller smarter so we can re-materialize "mov r, imm",
+etc. Almost all Thumb instructions clobber condition code.
+
+//===---------------------------------------------------------------------===//
+
+Add ldmia, stmia support.