[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