final patch for very long conditional branches for mips16 constant islands.
authorReed Kotler <rkotler@mips.com>
Tue, 3 Dec 2013 23:42:51 +0000 (23:42 +0000)
committerReed Kotler <rkotler@mips.com>
Tue, 3 Dec 2013 23:42:51 +0000 (23:42 +0000)
this completes the basic port of ARM constant islands to Mips16.
More testing, code review, cleanup is in order but basically everything
seems to be working. A bug in gas is preventing some of the runtime
testing but I hope to resolve this soon.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196331 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsConstantIslandPass.cpp
test/CodeGen/Mips/lcb4a.ll [new file with mode: 0644]
test/CodeGen/Mips/lcb5.ll [new file with mode: 0644]

index e05fe0abac09e17457f25a643d1a496ae7774861..97ac501a72b64549f9ae0e0a59d3bb2e1ea63f8e 100644 (file)
@@ -712,41 +712,49 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
           isCond = false;
           break;
         case Mips::BeqzRxImm16:
+          UOpc=Mips::Bimm16;
           Bits = 8;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BeqzRxImmX16:
+          UOpc=Mips::Bimm16;
           Bits = 16;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BnezRxImm16:
+          UOpc=Mips::Bimm16;
           Bits = 8;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BnezRxImmX16:
+          UOpc=Mips::Bimm16;
           Bits = 16;
           Scale = 2;
           isCond = true;
           break;
         case Mips::Bteqz16:
+          UOpc=Mips::Bimm16;
           Bits = 8;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BteqzX16:
+          UOpc=Mips::Bimm16;
           Bits = 16;
           Scale = 2;
           isCond = true;
           break;
         case Mips::Btnez16:
+          UOpc=Mips::Bimm16;
           Bits = 8;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BtnezX16:
+          UOpc=Mips::Bimm16;
           Bits = 16;
           Scale = 2;
           isCond = true;
@@ -1617,7 +1625,7 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
   MachineBasicBlock *MBB = MI->getParent();
   MachineInstr *BMI = &MBB->back();
   bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);
-
+  unsigned OppositeBranchOpcode=TII->getOppositeBranchOpc(Opcode);
  
   ++NumCBrFixed;
   if (BMI != MI) {
@@ -1636,7 +1644,7 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
       if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
         DEBUG(dbgs() << "  Invert Bcc condition and swap its destination with "
                      << *BMI);
-        MI->setDesc(TII->get(TII->getOppositeBranchOpc(Opcode)));
+        MI->setDesc(TII->get(OppositeBranchOpcode));
         BMI->getOperand(BMITargetOperand).setMBB(DestBB);
         MI->getOperand(TargetOperand).setMBB(NewDest);
         return true;
@@ -1644,7 +1652,6 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
     }
   }
 
-  llvm_unreachable("unsupported range of unconditional branch");
 
   if (NeedSplit) {
     splitBlockBeforeInstr(MI);
@@ -1663,8 +1670,14 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
 
   // Insert a new conditional branch and a new unconditional branch.
   // Also update the ImmBranch as well as adding a new entry for the new branch.
-  BuildMI(MBB, DebugLoc(), TII->get(MI->getOpcode()))
-    .addMBB(NextBB);
+  if (MI->getNumExplicitOperands() == 2) {
+    BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))
+           .addReg(MI->getOperand(0).getReg())
+           .addMBB(NextBB);
+  }
+  else { BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))
+        .addMBB(NextBB);
+  }
   Br.MI = &MBB->back();
   BBInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
   BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);
diff --git a/test/CodeGen/Mips/lcb4a.ll b/test/CodeGen/Mips/lcb4a.ll
new file mode 100644 (file)
index 0000000..e37feca
--- /dev/null
@@ -0,0 +1,69 @@
+; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static     < %s | FileCheck %s -check-prefix=ci
+
+@i = global i32 0, align 4
+@j = common global i32 0, align 4
+@k = common global i32 0, align 4
+
+; Function Attrs: nounwind optsize
+define i32 @foo() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %cmp = icmp eq i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 1000", ""() #1, !srcloc !5
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 1004", ""() #1, !srcloc !6
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  %storemerge = phi i32 [ 1, %if.else ], [ 0, %if.then ]
+  store i32 %storemerge, i32* @i, align 4, !tbaa !1
+  ret i32 0
+}
+
+; ci:  beqz    $3, $BB0_2
+; ci: # BB#1:                                 # %if.else
+
+
+; Function Attrs: nounwind optsize
+define i32 @goo() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %cmp = icmp eq i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 1000000", ""() #1, !srcloc !7
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 1000004", ""() #1, !srcloc !8
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  %storemerge = phi i32 [ 1, %if.else ], [ 0, %if.then ]
+  store i32 %storemerge, i32* @i, align 4, !tbaa !1
+  ret i32 0
+}
+
+; ci:  bnez    $3, $BB1_1  # 16 bit inst
+; ci:  jal     $BB1_2  # branch
+; ci:  nop
+; ci: $BB1_1:                                 # %if.else
+
+attributes #0 = { nounwind optsize "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind }
+
+
+!1 = metadata !{metadata !2, metadata !2, i64 0}
+!2 = metadata !{metadata !"int", metadata !3, i64 0}
+!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
+!4 = metadata !{metadata !"Simple C/C++ TBAA"}
+!5 = metadata !{i32 58}
+!6 = metadata !{i32 108}
+!7 = metadata !{i32 190}
+!8 = metadata !{i32 243}
diff --git a/test/CodeGen/Mips/lcb5.ll b/test/CodeGen/Mips/lcb5.ll
new file mode 100644 (file)
index 0000000..0a89c80
--- /dev/null
@@ -0,0 +1,240 @@
+; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static     < %s | FileCheck %s -check-prefix=ci
+
+@i = global i32 0, align 4
+@j = common global i32 0, align 4
+@k = common global i32 0, align 4
+
+; Function Attrs: nounwind optsize
+define i32 @x0() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %cmp = icmp eq i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 1000", ""() #1, !srcloc !5
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 1004", ""() #1, !srcloc !6
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  %storemerge = phi i32 [ 1, %if.else ], [ 0, %if.then ]
+  store i32 %storemerge, i32* @i, align 4, !tbaa !1
+  ret i32 0
+}
+
+; ci:  .ent    x0
+; ci:  beqz    $3, $BB0_2
+; ci: $BB0_2:
+; ci:  .end    x0
+
+; Function Attrs: nounwind optsize
+define i32 @x1() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %cmp = icmp eq i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 1000000", ""() #1, !srcloc !7
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 1000004", ""() #1, !srcloc !8
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  %storemerge = phi i32 [ 1, %if.else ], [ 0, %if.then ]
+  store i32 %storemerge, i32* @i, align 4, !tbaa !1
+  ret i32 0
+}
+
+; ci:  .ent    x1
+; ci:  bnez    $3, $BB1_1  # 16 bit inst
+; ci:  jal     $BB1_2  # branch
+; ci:  nop
+; ci: $BB1_1:
+; ci:  .end    x1
+
+; Function Attrs: nounwind optsize
+define i32 @y0() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %cmp = icmp eq i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  store i32 10, i32* @j, align 4, !tbaa !1
+  tail call void asm sideeffect ".space 1000", ""() #1, !srcloc !9
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  store i32 55, i32* @j, align 4, !tbaa !1
+  tail call void asm sideeffect ".space 1004", ""() #1, !srcloc !10
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret i32 0
+}
+
+; ci:  .ent    y0
+; ci:  beqz    $2, $BB2_2
+; ci:  .end    y0
+
+; Function Attrs: nounwind optsize
+define i32 @y1() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %cmp = icmp eq i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  store i32 10, i32* @j, align 4, !tbaa !1
+  tail call void asm sideeffect ".space 1000000", ""() #1, !srcloc !11
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  store i32 55, i32* @j, align 4, !tbaa !1
+  tail call void asm sideeffect ".space 1000004", ""() #1, !srcloc !12
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret i32 0
+}
+
+; ci:  .ent    y1
+; ci:  bnez    $2, $BB3_1  # 16 bit inst
+; ci:  jal     $BB3_2  # branch
+; ci:  nop
+; ci: $BB3_1:
+; ci:  .end    y1
+
+; Function Attrs: nounwind optsize
+define void @z0() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %1 = load i32* @j, align 4, !tbaa !1
+  %cmp = icmp eq i32 %0, %1
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  store i32 1, i32* @k, align 4, !tbaa !1
+  tail call void asm sideeffect ".space 10000", ""() #1, !srcloc !13
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 10004", ""() #1, !srcloc !14
+  store i32 2, i32* @k, align 4, !tbaa !1
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+
+; ci:  .ent    z0
+; ci:  btnez   $BB4_2
+; ci:  .end    z0
+
+; Function Attrs: nounwind optsize
+define void @z1() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %1 = load i32* @j, align 4, !tbaa !1
+  %cmp = icmp eq i32 %0, %1
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  store i32 1, i32* @k, align 4, !tbaa !1
+  tail call void asm sideeffect ".space 10000000", ""() #1, !srcloc !15
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void asm sideeffect ".space 10000004", ""() #1, !srcloc !16
+  store i32 2, i32* @k, align 4, !tbaa !1
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+
+; ci:  .ent    z1
+; ci:  bteqz   $BB5_1  # 16 bit inst
+; ci:  jal     $BB5_2  # branch
+; ci:  nop
+; ci: $BB5_1:
+; ci:  .end    z1
+
+; Function Attrs: nounwind optsize
+define void @z3() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %1 = load i32* @j, align 4, !tbaa !1
+  %cmp1 = icmp sgt i32 %0, %1
+  br i1 %cmp1, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry, %if.then
+  tail call void asm sideeffect ".space 10000", ""() #1, !srcloc !17
+  %2 = load i32* @i, align 4, !tbaa !1
+  %3 = load i32* @j, align 4, !tbaa !1
+  %cmp = icmp sgt i32 %2, %3
+  br i1 %cmp, label %if.then, label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
+; ci:  .ent    z3
+; ci:  bteqz   $BB6_2
+; ci:  .end    z3
+
+; Function Attrs: nounwind optsize
+define void @z4() #0 {
+entry:
+  %0 = load i32* @i, align 4, !tbaa !1
+  %1 = load i32* @j, align 4, !tbaa !1
+  %cmp1 = icmp sgt i32 %0, %1
+  br i1 %cmp1, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry, %if.then
+  tail call void asm sideeffect ".space 10000000", ""() #1, !srcloc !18
+  %2 = load i32* @i, align 4, !tbaa !1
+  %3 = load i32* @j, align 4, !tbaa !1
+  %cmp = icmp sgt i32 %2, %3
+  br i1 %cmp, label %if.then, label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  ret void
+}
+
+; ci:  .ent    z4
+; ci:  btnez   $BB7_1  # 16 bit inst
+; ci:  jal     $BB7_2  # branch
+; ci:  nop
+; ci:  .align  2
+; ci: $BB7_1:
+; ci:  .end    z4
+
+attributes #0 = { nounwind optsize "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind }
+
+
+!1 = metadata !{metadata !2, metadata !2, i64 0}
+!2 = metadata !{metadata !"int", metadata !3, i64 0}
+!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
+!4 = metadata !{metadata !"Simple C/C++ TBAA"}
+!5 = metadata !{i32 57}
+!6 = metadata !{i32 107}
+!7 = metadata !{i32 188}
+!8 = metadata !{i32 241}
+!9 = metadata !{i32 338}
+!10 = metadata !{i32 391}
+!11 = metadata !{i32 477}
+!12 = metadata !{i32 533}
+!13 = metadata !{i32 621}
+!14 = metadata !{i32 663}
+!15 = metadata !{i32 747}
+!16 = metadata !{i32 792}
+!17 = metadata !{i32 867}
+!18 = metadata !{i32 953}