diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/Mips/MipsConstantIslandPass.cpp | 156 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsSubtarget.cpp | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/Mips/i32k.ll | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/Mips/largefr1.ll | 4 | ||||
-rw-r--r-- | llvm/test/CodeGen/Mips/lcb2.ll | 133 |
5 files changed, 293 insertions, 8 deletions
diff --git a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp index 7ab601c1a1a..3c62baeec15 100644 --- a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp +++ b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp @@ -77,6 +77,103 @@ static cl::opt<bool> NoLoadRelaxation( cl::desc("Don't relax loads to long loads - for testing purposes"), cl::Hidden); +static unsigned int branchTargetOperand(MachineInstr *MI) { + switch (MI->getOpcode()) { + case Mips::Bimm16: + case Mips::BimmX16: + case Mips::Bteqz16: + case Mips::BteqzX16: + case Mips::Btnez16: + case Mips::BtnezX16: + case Mips::Jal16: + return 0; + case Mips::BeqzRxImm16: + case Mips::BeqzRxImmX16: + case Mips::BnezRxImm16: + case Mips::BnezRxImmX16: + return 1; + } + llvm_unreachable("Unknown branch type"); +} + +static unsigned int longformBranchOpcode(unsigned int Opcode) { + switch (Opcode) { + case Mips::Bimm16: + case Mips::BimmX16: + return Mips::BimmX16; + case Mips::Bteqz16: + case Mips::BteqzX16: + return Mips::BteqzX16; + case Mips::Btnez16: + case Mips::BtnezX16: + return Mips::BtnezX16; + case Mips::Jal16: + return Mips::Jal16; + case Mips::BeqzRxImm16: + case Mips::BeqzRxImmX16: + return Mips::BeqzRxImmX16; + case Mips::BnezRxImm16: + case Mips::BnezRxImmX16: + return Mips::BnezRxImmX16; + } + llvm_unreachable("Unknown branch type"); +} + +// +// FIXME: need to go through this whole constant islands port and check the math +// for branch ranges and clean this up and make some functions to calculate things +// that are done many times identically. +// Need to refactor some of the code to call this routine. +// +static unsigned int branchMaxOffsets(unsigned int Opcode) { + unsigned Bits, Scale; + switch (Opcode) { + case Mips::Bimm16: + Bits = 11; + Scale = 2; + break; + case Mips::BimmX16: + Bits = 16; + Scale = 2; + break; + case Mips::BeqzRxImm16: + Bits = 8; + Scale = 2; + break; + case Mips::BeqzRxImmX16: + Bits = 16; + Scale = 2; + break; + case Mips::BnezRxImm16: + Bits = 8; + Scale = 2; + break; + case Mips::BnezRxImmX16: + Bits = 16; + Scale = 2; + break; + case Mips::Bteqz16: + Bits = 8; + Scale = 2; + break; + case Mips::BteqzX16: + Bits = 16; + Scale = 2; + break; + case Mips::Btnez16: + Bits = 8; + Scale = 2; + break; + case Mips::BtnezX16: + Bits = 16; + Scale = 2; + break; + default: + llvm_unreachable("Unknown branch type"); + } + unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale; + return MaxOffs; +} namespace { @@ -603,6 +700,47 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) { Bits = 16; Scale = 2; isCond = false; + break; + case Mips::BeqzRxImm16: + Bits = 8; + Scale = 2; + isCond = true; + break; + case Mips::BeqzRxImmX16: + Bits = 16; + Scale = 2; + isCond = true; + break; + case Mips::BnezRxImm16: + Bits = 8; + Scale = 2; + isCond = true; + break; + case Mips::BnezRxImmX16: + Bits = 16; + Scale = 2; + isCond = true; + break; + case Mips::Bteqz16: + Bits = 8; + Scale = 2; + isCond = true; + break; + case Mips::BteqzX16: + Bits = 16; + Scale = 2; + isCond = true; + break; + case Mips::Btnez16: + Bits = 8; + Scale = 2; + isCond = true; + break; + case Mips::BtnezX16: + Bits = 16; + Scale = 2; + isCond = true; + break; } // Record this immediate branch. unsigned MaxOffs = ((1 << (Bits-1))-1) * Scale; @@ -1382,7 +1520,8 @@ unsigned PCAdj = 4; /// away to fit in its displacement field. bool MipsConstantIslands::fixupImmediateBr(ImmBranch &Br) { MachineInstr *MI = Br.MI; - MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); + unsigned TargetOperand = branchTargetOperand(MI); + MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB(); // Check to see if the DestBB is already in-range. if (isBBInRange(MI, DestBB, Br.MaxDisp)) @@ -1434,13 +1573,26 @@ MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) { return true; } + /// fixupConditionalBr - Fix up a conditional branch whose destination is too /// far away to fit in its displacement field. It is converted to an inverse /// conditional branch + an unconditional branch to the destination. bool MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) { MachineInstr *MI = Br.MI; - MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); + unsigned TargetOperand = branchTargetOperand(MI); + MachineBasicBlock *DestBB = MI->getOperand(TargetOperand).getMBB(); + unsigned Opcode = MI->getOpcode(); + unsigned LongFormOpcode = longformBranchOpcode(Opcode); + unsigned LongFormMaxOff = branchMaxOffsets(LongFormOpcode); + + // Check to see if the DestBB is already in-range. + if (isBBInRange(MI, DestBB, LongFormMaxOff)) { + Br.MaxDisp = LongFormMaxOff; + MI->setDesc(TII->get(LongFormOpcode)); + return true; + } + llvm_unreachable("Fixup of very long conditional branch not working yet."); // Add an unconditional branch to the destination and invert the branch // condition to jump over it: diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp index 9688f0e264b..5103084db5b 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.cpp +++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp @@ -55,9 +55,9 @@ Mips16HardFloat("mips16-hard-float", cl::NotHidden, static cl::opt<bool> Mips16ConstantIslands( - "mips16-constant-islands", cl::Hidden, - cl::desc("MIPS: mips16 constant islands enable. experimental feature"), - cl::init(false)); + "mips16-constant-islands", cl::NotHidden, + cl::desc("MIPS: mips16 constant islands enable."), + cl::init(true)); void MipsSubtarget::anchor() { } diff --git a/llvm/test/CodeGen/Mips/i32k.ll b/llvm/test/CodeGen/Mips/i32k.ll index f4dd1eb78a1..73f1302beec 100644 --- a/llvm/test/CodeGen/Mips/i32k.ll +++ b/llvm/test/CodeGen/Mips/i32k.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 +; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -relocation-model=pic -mips16-constant-islands=false -O3 < %s | FileCheck %s -check-prefix=16 @.str = private unnamed_addr constant [4 x i8] c"%i\0A\00", align 1 diff --git a/llvm/test/CodeGen/Mips/largefr1.ll b/llvm/test/CodeGen/Mips/largefr1.ll index 7594e22d0f4..4fb62861b12 100644 --- a/llvm/test/CodeGen/Mips/largefr1.ll +++ b/llvm/test/CodeGen/Mips/largefr1.ll @@ -1,6 +1,6 @@ -; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -relocation-model=static < %s | FileCheck %s -check-prefix=1 +; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -relocation-model=static -mips16-constant-islands=false < %s | FileCheck %s -check-prefix=1 -; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=pic -mips16-constant-islands < %s | FileCheck %s -check-prefix=ci +; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=pic < %s | FileCheck %s -check-prefix=ci @i = common global i32 0, align 4 @j = common global i32 0, align 4 diff --git a/llvm/test/CodeGen/Mips/lcb2.ll b/llvm/test/CodeGen/Mips/lcb2.ll new file mode 100644 index 00000000000..715584b6797 --- /dev/null +++ b/llvm/test/CodeGen/Mips/lcb2.ll @@ -0,0 +1,133 @@ +; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static -mips16-constant-islands=true < %s | FileCheck %s -check-prefix=lcb + +; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static -mips16-constant-islands=true < %s | FileCheck %s -check-prefix=lcbn + +@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 @bnez() #0 { +entry: + %0 = load i32* @i, align 4, !tbaa !1 + %cmp = icmp eq i32 %0, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + tail call void asm sideeffect ".space 10000", ""() #1, !srcloc !5 + store i32 0, i32* @i, align 4, !tbaa !1 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret i32 0 +} +; lcb: .ent bnez +; lcbn: .ent bnez +; lcb: bnez ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]+}} +; lcbn-NOT: bnez ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]+}} # 16 bit inst +; lcb: .end bnez +; lcbn: .end bnez + +; Function Attrs: nounwind optsize +define i32 @beqz() #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 10000", ""() #1, !srcloc !6 + br label %if.end + +if.else: ; preds = %entry + store i32 55, i32* @j, align 4, !tbaa !1 + tail call void asm sideeffect ".space 10000", ""() #1, !srcloc !7 + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret i32 0 +} + +; lcb: .ent beqz +; lcbn: .ent beqz +; lcb: beqz ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]+}} +; lcbn-NOT: beqz ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]+}} # 16 bit inst +; lcb: .end beqz +; lcbn: .end beqz + + +; Function Attrs: nounwind optsize +define void @bteqz() #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 1000", ""() #1, !srcloc !8 + br label %if.end + +if.else: ; preds = %entry + tail call void asm sideeffect ".space 1000", ""() #1, !srcloc !9 + store i32 2, i32* @k, align 4, !tbaa !1 + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +; lcb: .ent bteqz +; lcbn: .ent bteqz +; lcb: btnez $BB{{[0-9]+}}_{{[0-9]+}} +; lcbn-NOT: btnez $BB{{[0-9]+}}_{{[0-9]+}} # 16 bit inst +; lcb: .end bteqz +; lcbn: .end bteqz + + +; Function Attrs: nounwind optsize +define void @btz() #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 60000", ""() #1, !srcloc !10 + %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 +} + +; lcb: .ent btz +; lcbn: .ent btz +; lcb: bteqz $BB{{[0-9]+}}_{{[0-9]+}} +; lcbn-NOT: bteqz $BB{{[0-9]+}}_{{[0-9]+}} # 16 bit inst +; lcb: btnez $BB{{[0-9]+}}_{{[0-9]+}} +; lcbn-NOT: btnez $BB{{[0-9]+}}_{{[0-9]+}} # 16 bit inst +; lcb: .end btz +; lcbn: .end btz + +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 } + +!llvm.ident = !{!0} + +!0 = metadata !{metadata !"clang version 3.5 (gitosis@dmz-portal.mips.com:clang.git ed197d08c90d82e1119774e10920e6f7a841c8ec) (gitosis@dmz-portal.mips.com:llvm.git b9235a363fa2dddb26ac01cbaed58efbc9eff392)"} +!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 59} +!6 = metadata !{i32 156} +!7 = metadata !{i32 210} +!8 = metadata !{i32 299} +!9 = metadata !{i32 340} +!10 = metadata !{i32 412} |