mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-08 18:30:04 +00:00
[mips] Optimize long branch for MIPS64 by removing %higher and %highest.
%higher and %highest can have non-zero values only for offsets greater than 2GB, which is highly unlikely, if not impossible when compiling a single function. This makes long branch for MIPS64 3 instructions smaller. Differential Revision: http://llvm-reviews.chandlerc.com/D3281.diff git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209678 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
41087d99df
commit
95ce098219
@ -245,16 +245,12 @@ let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
|
|||||||
"sll\t$rd, $rt, 0", [], II_SLL>;
|
"sll\t$rd, $rt, 0", [], II_SLL>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need the following two pseudo instructions to avoid offset calculation for
|
// We need the following pseudo instruction to avoid offset calculation for
|
||||||
// long branches. See the comment in file MipsLongBranch.cpp for detailed
|
// long branches. See the comment in file MipsLongBranch.cpp for detailed
|
||||||
// explanation.
|
// explanation.
|
||||||
|
|
||||||
// Expands to: lui $dst, %highest($tgt - $baltgt)
|
|
||||||
def LONG_BRANCH_LUi64 : PseudoSE<(outs GPR64Opnd:$dst),
|
|
||||||
(ins brtarget:$tgt, brtarget:$baltgt), []>;
|
|
||||||
|
|
||||||
// Expands to: daddiu $dst, $src, %PART($tgt - $baltgt)
|
// Expands to: daddiu $dst, $src, %PART($tgt - $baltgt)
|
||||||
// where %PART may be %higher, %hi or %lo, depending on the relocation kind
|
// where %PART may be %hi or %lo, depending on the relocation kind
|
||||||
// that $tgt is annotated with.
|
// that $tgt is annotated with.
|
||||||
def LONG_BRANCH_DADDiu : PseudoSE<(outs GPR64Opnd:$dst),
|
def LONG_BRANCH_DADDiu : PseudoSE<(outs GPR64Opnd:$dst),
|
||||||
(ins GPR64Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
|
(ins GPR64Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
|
||||||
|
@ -958,7 +958,6 @@ void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) {
|
|||||||
bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
|
bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
|
||||||
return (Opcode == Mips::LONG_BRANCH_LUi
|
return (Opcode == Mips::LONG_BRANCH_LUi
|
||||||
|| Opcode == Mips::LONG_BRANCH_ADDiu
|
|| Opcode == Mips::LONG_BRANCH_ADDiu
|
||||||
|| Opcode == Mips::LONG_BRANCH_LUi64
|
|
||||||
|| Opcode == Mips::LONG_BRANCH_DADDiu);
|
|| Opcode == Mips::LONG_BRANCH_DADDiu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ namespace {
|
|||||||
: MachineFunctionPass(ID), TM(tm),
|
: MachineFunctionPass(ID), TM(tm),
|
||||||
IsPIC(TM.getRelocationModel() == Reloc::PIC_),
|
IsPIC(TM.getRelocationModel() == Reloc::PIC_),
|
||||||
ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),
|
ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),
|
||||||
LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {}
|
LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 : 9)) {}
|
||||||
|
|
||||||
const char *getPassName() const override {
|
const char *getPassName() const override {
|
||||||
return "Mips Long Branch";
|
return "Mips Long Branch";
|
||||||
@ -324,10 +324,7 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
|
|||||||
// $longbr:
|
// $longbr:
|
||||||
// daddiu $sp, $sp, -16
|
// daddiu $sp, $sp, -16
|
||||||
// sd $ra, 0($sp)
|
// sd $ra, 0($sp)
|
||||||
// lui64 $at, %highest($tgt - $baltgt)
|
// daddiu $at, $zero, %hi($tgt - $baltgt)
|
||||||
// daddiu $at, $at, %higher($tgt - $baltgt)
|
|
||||||
// dsll $at, $at, 16
|
|
||||||
// daddiu $at, $at, %hi($tgt - $baltgt)
|
|
||||||
// dsll $at, $at, 16
|
// dsll $at, $at, 16
|
||||||
// bal $baltgt
|
// bal $baltgt
|
||||||
// daddiu $at, $at, %lo($tgt - $baltgt)
|
// daddiu $at, $at, %lo($tgt - $baltgt)
|
||||||
@ -339,10 +336,20 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
|
|||||||
// $fallthrough:
|
// $fallthrough:
|
||||||
//
|
//
|
||||||
|
|
||||||
// TODO: %highest and %higher can have non-zero values only when the
|
// We assume the branch is within-function, and that offset is within
|
||||||
// offset is greater than 4GB, which is highly unlikely. Replace
|
// +/- 2GB. High 32 bits will therefore always be zero.
|
||||||
// them (and the following instructon that shifts $at by 16) with the
|
|
||||||
// instruction that sets $at to zero.
|
// Note that this will work even if the offset is negative, because
|
||||||
|
// of the +1 modification that's added in that case. For example, if the
|
||||||
|
// offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is
|
||||||
|
//
|
||||||
|
// 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000
|
||||||
|
//
|
||||||
|
// and the bits [47:32] are zero. For %highest
|
||||||
|
//
|
||||||
|
// 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000
|
||||||
|
//
|
||||||
|
// and the bits [63:48] are zero.
|
||||||
|
|
||||||
Pos = LongBrMBB->begin();
|
Pos = LongBrMBB->begin();
|
||||||
|
|
||||||
@ -350,16 +357,9 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
|
|||||||
.addReg(Mips::SP_64).addImm(-16);
|
.addReg(Mips::SP_64).addImm(-16);
|
||||||
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
|
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
|
||||||
.addReg(Mips::SP_64).addImm(0);
|
.addReg(Mips::SP_64).addImm(0);
|
||||||
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi64),
|
|
||||||
Mips::AT_64).addMBB(TgtMBB).addMBB(BalTgtMBB);
|
|
||||||
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
|
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
|
||||||
Mips::AT_64).addReg(Mips::AT_64).addMBB(TgtMBB, MipsII::MO_HIGHER)
|
Mips::AT_64).addReg(Mips::ZERO_64)
|
||||||
.addMBB(BalTgtMBB);
|
.addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB);
|
||||||
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
|
|
||||||
.addReg(Mips::AT_64).addImm(16);
|
|
||||||
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
|
|
||||||
Mips::AT_64).addReg(Mips::AT_64).addMBB(TgtMBB, MipsII::MO_ABS_HI)
|
|
||||||
.addMBB(BalTgtMBB);
|
|
||||||
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
|
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
|
||||||
.addReg(Mips::AT_64).addImm(16);
|
.addReg(Mips::AT_64).addImm(16);
|
||||||
|
|
||||||
|
@ -162,16 +162,16 @@ MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MipsMCInstLower::
|
void MipsMCInstLower::
|
||||||
lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI, int Opcode,
|
lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
|
||||||
MCSymbolRefExpr::VariantKind Kind) const {
|
OutMI.setOpcode(Mips::LUi);
|
||||||
OutMI.setOpcode(Opcode);
|
|
||||||
|
|
||||||
// Lower register operand.
|
// Lower register operand.
|
||||||
OutMI.addOperand(LowerOperand(MI->getOperand(0)));
|
OutMI.addOperand(LowerOperand(MI->getOperand(0)));
|
||||||
|
|
||||||
// Create %hi($tgt-$baltgt) or %highest($tgt-$baltgt).
|
// Create %hi($tgt-$baltgt).
|
||||||
OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
|
OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
|
||||||
MI->getOperand(2).getMBB(), Kind));
|
MI->getOperand(2).getMBB(),
|
||||||
|
MCSymbolRefExpr::VK_Mips_ABS_HI));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MipsMCInstLower::
|
void MipsMCInstLower::
|
||||||
@ -185,7 +185,7 @@ lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI, int Opcode,
|
|||||||
OutMI.addOperand(LowerOperand(MO));
|
OutMI.addOperand(LowerOperand(MO));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create %lo($tgt-$baltgt), %hi($tgt-$baltgt) or %higher($tgt-$baltgt).
|
// Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
|
||||||
OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
|
OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
|
||||||
MI->getOperand(3).getMBB(), Kind));
|
MI->getOperand(3).getMBB(), Kind));
|
||||||
}
|
}
|
||||||
@ -196,11 +196,7 @@ bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
case Mips::LONG_BRANCH_LUi:
|
case Mips::LONG_BRANCH_LUi:
|
||||||
lowerLongBranchLUi(MI, OutMI, Mips::LUi, MCSymbolRefExpr::VK_Mips_ABS_HI);
|
lowerLongBranchLUi(MI, OutMI);
|
||||||
return true;
|
|
||||||
case Mips::LONG_BRANCH_LUi64:
|
|
||||||
lowerLongBranchLUi(MI, OutMI, Mips::LUi64,
|
|
||||||
MCSymbolRefExpr::VK_Mips_HIGHEST);
|
|
||||||
return true;
|
return true;
|
||||||
case Mips::LONG_BRANCH_ADDiu:
|
case Mips::LONG_BRANCH_ADDiu:
|
||||||
lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu,
|
lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu,
|
||||||
@ -208,10 +204,7 @@ bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
|
|||||||
return true;
|
return true;
|
||||||
case Mips::LONG_BRANCH_DADDiu:
|
case Mips::LONG_BRANCH_DADDiu:
|
||||||
unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
|
unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
|
||||||
if (TargetFlags == MipsII::MO_HIGHER)
|
if (TargetFlags == MipsII::MO_ABS_HI)
|
||||||
lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu,
|
|
||||||
MCSymbolRefExpr::VK_Mips_HIGHER);
|
|
||||||
else if (TargetFlags == MipsII::MO_ABS_HI)
|
|
||||||
lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu,
|
lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu,
|
||||||
MCSymbolRefExpr::VK_Mips_ABS_HI);
|
MCSymbolRefExpr::VK_Mips_ABS_HI);
|
||||||
else if (TargetFlags == MipsII::MO_ABS_LO)
|
else if (TargetFlags == MipsII::MO_ABS_LO)
|
||||||
|
@ -39,8 +39,7 @@ private:
|
|||||||
MachineOperandType MOTy, unsigned Offset) const;
|
MachineOperandType MOTy, unsigned Offset) const;
|
||||||
MCOperand createSub(MachineBasicBlock *BB1, MachineBasicBlock *BB2,
|
MCOperand createSub(MachineBasicBlock *BB1, MachineBasicBlock *BB2,
|
||||||
MCSymbolRefExpr::VariantKind Kind) const;
|
MCSymbolRefExpr::VariantKind Kind) const;
|
||||||
void lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI,
|
void lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const;
|
||||||
int Opcode, MCSymbolRefExpr::VariantKind Kind) const;
|
|
||||||
void lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI,
|
void lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI,
|
||||||
int Opcode,
|
int Opcode,
|
||||||
MCSymbolRefExpr::VariantKind Kind) const;
|
MCSymbolRefExpr::VariantKind Kind) const;
|
||||||
|
@ -80,10 +80,7 @@ end:
|
|||||||
; Check for long branch expansion:
|
; Check for long branch expansion:
|
||||||
; N64: daddiu $sp, $sp, -16
|
; N64: daddiu $sp, $sp, -16
|
||||||
; N64-NEXT: sd $ra, 0($sp)
|
; N64-NEXT: sd $ra, 0($sp)
|
||||||
; N64-NEXT: lui $1, %highest(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
|
; N64-NEXT: daddiu $1, $zero, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
|
||||||
; N64-NEXT: daddiu $1, $1, %higher(($[[BB2]])-($[[BB1]]))
|
|
||||||
; N64-NEXT: dsll $1, $1, 16
|
|
||||||
; N64-NEXT: daddiu $1, $1, %hi(($[[BB2]])-($[[BB1]]))
|
|
||||||
; N64-NEXT: dsll $1, $1, 16
|
; N64-NEXT: dsll $1, $1, 16
|
||||||
; N64-NEXT: bal $[[BB1]]
|
; N64-NEXT: bal $[[BB1]]
|
||||||
; N64-NEXT: daddiu $1, $1, %lo(($[[BB2]])-($[[BB1]]))
|
; N64-NEXT: daddiu $1, $1, %lo(($[[BB2]])-($[[BB1]]))
|
||||||
|
Loading…
Reference in New Issue
Block a user