[llvm-commits] [llvm] r74549 - in /llvm/trunk: lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMConstantIslandPass.cpp lib/Target/ARM/ARMInstrInfo.cpp lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/Thumb2/thumb2-jumptbl.ll
David Goodwin
david_goodwin at apple.com
Tue Jun 30 12:50:31 PDT 2009
Author: david_goodwin
Date: Tue Jun 30 14:50:22 2009
New Revision: 74549
URL: http://llvm.org/viewvc/llvm-project?rev=74549&view=rev
Log:
Improve Thumb-2 jump table support.
Added:
llvm/trunk/test/CodeGen/Thumb2/thumb2-jumptbl.ll
Modified:
llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=74549&r1=74548&r2=74549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue Jun 30 14:50:22 2009
@@ -1155,16 +1155,17 @@
const TargetInstrDesc &TID = MI.getDesc();
// Handle jump tables.
- if (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::BR_JTadd) {
+ if (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::BR_JTadd ||
+ TID.Opcode == ARM::t2BR_JTr || TID.Opcode == ARM::t2BR_JTadd) {
// First emit a ldr pc, [] instruction.
emitDataProcessingInstruction(MI, ARM::PC);
// Then emit the inline jump table.
- unsigned JTIndex = (TID.Opcode == ARM::BR_JTr)
+ unsigned JTIndex = (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::t2BR_JTr)
? MI.getOperand(1).getIndex() : MI.getOperand(2).getIndex();
emitInlineJumpTable(JTIndex);
return;
- } else if (TID.Opcode == ARM::BR_JTm) {
+ } else if (TID.Opcode == ARM::BR_JTm || TID.Opcode == ARM::t2BR_JTm) {
// First emit a ldr pc, [] instruction.
emitLoadStoreInstruction(MI, ARM::PC);
Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=74549&r1=74548&r2=74549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Tue Jun 30 14:50:22 2009
@@ -379,6 +379,8 @@
switch (Opc) {
case ARM::tBR_JTr:
case ARM::t2BR_JTr:
+ case ARM::t2BR_JTm:
+ case ARM::t2BR_JTadd:
// A Thumb table jump may involve padding; for the offsets to
// be right, functions containing these must be 4-byte aligned.
AFI->setAlign(2U);
@@ -766,7 +768,9 @@
// following unconditional branches are removed by AnalyzeBranch.
MachineInstr *ThumbJTMI = NULL;
if ((prior(MBB->end())->getOpcode() == ARM::tBR_JTr)
- || (prior(MBB->end())->getOpcode() == ARM::t2BR_JTr))
+ || (prior(MBB->end())->getOpcode() == ARM::t2BR_JTr)
+ || (prior(MBB->end())->getOpcode() == ARM::t2BR_JTm)
+ || (prior(MBB->end())->getOpcode() == ARM::t2BR_JTadd))
ThumbJTMI = prior(MBB->end());
if (ThumbJTMI) {
unsigned newMIOffset = GetOffsetOf(ThumbJTMI);
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=74549&r1=74548&r2=74549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Tue Jun 30 14:50:22 2009
@@ -401,7 +401,8 @@
// correctness of Thumb constant islands.
if ((SecondLastOpc == ARM::BR_JTr || SecondLastOpc==ARM::BR_JTm ||
SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr ||
- SecondLastOpc==ARM::t2BR_JTr) &&
+ SecondLastOpc == ARM::t2BR_JTr || SecondLastOpc==ARM::t2BR_JTm ||
+ SecondLastOpc == ARM::t2BR_JTadd) &&
(LastOpc == ARM::B || LastOpc == ARM::tB || LastOpc == ARM::t2B)) {
I = LastInst;
if (AllowModify)
@@ -708,7 +709,9 @@
case ARM::tBR_JTr:
case ARM::t2BR_JTr:
case ARM::BR_JTr: // Jumptable branch.
+ case ARM::t2BR_JTm:
case ARM::BR_JTm: // Jumptable branch through mem.
+ case ARM::t2BR_JTadd:
case ARM::BR_JTadd: // Jumptable branch add to pc.
return true;
default: return false;
@@ -846,8 +849,10 @@
case ARM::BR_JTr:
case ARM::BR_JTm:
case ARM::BR_JTadd:
- case ARM::tBR_JTr:
- case ARM::t2BR_JTr: {
+ case ARM::t2BR_JTr:
+ case ARM::t2BR_JTm:
+ case ARM::t2BR_JTadd:
+ case ARM::tBR_JTr: {
// These are jumptable branches, i.e. a branch followed by an inlined
// jumptable. The size is 4 + 4 * number of entries.
unsigned NumOps = TID.getNumOperands();
@@ -865,8 +870,7 @@
// bytes, we can use 16-bit entries instead. Then there won't be an
// alignment issue.
return getNumJTEntries(JT, JTI) * 4 +
- ((MI->getOpcode()==ARM::tBR_JTr ||
- MI->getOpcode()==ARM::t2BR_JTr) ? 2 : 4);
+ ((MI->getOpcode()==ARM::tBR_JTr) ? 2 : 4);
}
default:
// Otherwise, pseudo-instruction sizes are zero.
Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=74549&r1=74548&r2=74549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Tue Jun 30 14:50:22 2009
@@ -698,11 +698,25 @@
"b $target",
[(br bb:$target)]>;
-def t2BR_JTr : T2JTI<(outs),
- (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
- "cpy pc, $target \n\t.align\t2\n$jt",
- [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
-}
+let isNotDuplicable = 1, isIndirectBranch = 1 in {
+def t2BR_JTr : T2JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
+ "mov pc, $target \n$jt",
+ [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
+
+def t2BR_JTm :
+ T2JTI<(outs),
+ (ins t2addrmode_so_reg:$target, jtblock_operand:$jt, i32imm:$id),
+ "ldr pc, $target \n$jt",
+ [(ARMbrjt (i32 (load t2addrmode_so_reg:$target)), tjumptable:$jt,
+ imm:$id)]>;
+
+def t2BR_JTadd :
+ T2JTI<(outs),
+ (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
+ "add pc, $target, $idx \n$jt",
+ [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, imm:$id)]>;
+} // isNotDuplicate, isIndirectBranch
+} // isBranch, isTerminator, isBarrier
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
// a two-value operand where a dag node expects two operands. :(
Added: llvm/trunk/test/CodeGen/Thumb2/thumb2-jumptbl.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-jumptbl.ll?rev=74549&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-jumptbl.ll (added)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-jumptbl.ll Tue Jun 30 14:50:22 2009
@@ -0,0 +1,26 @@
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep {ldr\\W*pc,} | count 1
+
+define i32 @foo(i32 %a) nounwind {
+entry:
+ switch i32 %a, label %bb4 [
+ i32 1, label %bb5
+ i32 2, label %bb1
+ i32 3, label %bb2
+ i32 5, label %bb3
+ ]
+
+bb1: ; preds = %entry
+ ret i32 1
+
+bb2: ; preds = %entry
+ ret i32 1234
+
+bb3: ; preds = %entry
+ ret i32 3456
+
+bb4: ; preds = %entry
+ ret i32 0
+
+bb5: ; preds = %entry
+ ret i32 12
+}
More information about the llvm-commits
mailing list