mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Back out branchless SetCC code. While it helped a lot in some cases, it
hurt a lot in others. Instead, improve branching version of SetCC and Select instructions. The old code will be in CVS should we ever need to dig it up again. llvm-svn: 15979
This commit is contained in:
parent
d73bd282d7
commit
e6aace2ecb
@ -1110,148 +1110,12 @@ void ISel::visitSetCondInst(SetCondInst &I) {
|
||||
if (canFoldSetCCIntoBranchOrSelect(&I))
|
||||
return;
|
||||
|
||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
||||
const Type *Ty = Op0->getType();
|
||||
unsigned Class = getClassB(Ty);
|
||||
unsigned Opcode = I.getOpcode();
|
||||
unsigned DestReg = getReg(I);
|
||||
|
||||
// If the comparison type is byte, short, or int, then we can emit a
|
||||
// branchless version of the SetCC that puts 0 (false) or 1 (true) in the
|
||||
// destination register.
|
||||
if (Class <= cInt) {
|
||||
++NumSetCC;
|
||||
MachineBasicBlock::iterator MI = BB->end();
|
||||
unsigned OpNum = getSetCCNumber(Opcode);
|
||||
unsigned Op0Reg = getReg(Op0, BB, MI);
|
||||
Op0Reg = ExtendOrClear(BB, MI, Op0Reg, Ty);
|
||||
|
||||
// comparisons against constant zero often have shorter sequences than the
|
||||
// general case, handled below.
|
||||
ConstantInt *CI = dyn_cast<ConstantInt>(Op1);
|
||||
if (CI && CI->getRawValue() == 0) {
|
||||
switch(OpNum) {
|
||||
case 0: { // eq0
|
||||
unsigned TempReg = makeAnotherReg(Type::IntTy);
|
||||
BuildMI(*BB, MI, PPC::CNTLZW, 1, TempReg).addReg(Op0Reg);
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(TempReg).addImm(5);
|
||||
break;
|
||||
}
|
||||
case 1: { // ne0
|
||||
unsigned TempReg = makeAnotherReg(Type::IntTy);
|
||||
BuildMI(*BB, MI, PPC::ADDIC, 2, TempReg).addReg(Op0Reg).addSImm(-1);
|
||||
BuildMI(*BB, MI, PPC::SUBFE, 2, DestReg).addReg(TempReg).addReg(Op0Reg);
|
||||
break;
|
||||
}
|
||||
case 2: { // lt0, always false if unsigned
|
||||
if (Ty->isSigned())
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Op0Reg).addImm(31);
|
||||
else
|
||||
BuildMI(*BB, MI, PPC::LI, 1, DestReg).addSImm(0);
|
||||
break;
|
||||
}
|
||||
case 3: { // ge0, always true if unsigned
|
||||
if (Ty->isSigned()) {
|
||||
unsigned TempReg = makeAnotherReg(Type::IntTy);
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, TempReg).addReg(Op0Reg).addImm(31);
|
||||
BuildMI(*BB, MI, PPC::XORI, 2, DestReg).addReg(TempReg).addImm(1);
|
||||
} else {
|
||||
BuildMI(*BB, MI, PPC::LI, 1, DestReg).addSImm(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: { // gt0, equivalent to ne0 if unsigned
|
||||
unsigned Temp1 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp2 = makeAnotherReg(Type::IntTy);
|
||||
if (Ty->isSigned()) {
|
||||
BuildMI(*BB, MI, PPC::NEG, 2, Temp1).addReg(Op0Reg);
|
||||
BuildMI(*BB, MI, PPC::ANDC, 2, Temp2).addReg(Temp1).addReg(Op0Reg);
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Temp2).addImm(31);
|
||||
} else {
|
||||
BuildMI(*BB, MI, PPC::ADDIC, 2, Temp1).addReg(Op0Reg).addSImm(-1);
|
||||
BuildMI(*BB, MI, PPC::SUBFE, 2, DestReg).addReg(Temp1).addReg(Op0Reg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5: { // le0, equivalent to eq0 if unsigned
|
||||
unsigned Temp1 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp2 = makeAnotherReg(Type::IntTy);
|
||||
if (Ty->isSigned()) {
|
||||
BuildMI(*BB, MI, PPC::NEG, 2, Temp1).addReg(Op0Reg);
|
||||
BuildMI(*BB, MI, PPC::ORC, 2, Temp2).addReg(Op0Reg).addReg(Temp1);
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Temp2).addImm(31);
|
||||
} else {
|
||||
BuildMI(*BB, MI, PPC::CNTLZW, 1, Temp1).addReg(Op0Reg);
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Temp1).addImm(5);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
return;
|
||||
}
|
||||
unsigned Op1Reg = getReg(Op1, BB, MI);
|
||||
switch(OpNum) {
|
||||
case 0: { // eq
|
||||
unsigned Temp1 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp2 = makeAnotherReg(Type::IntTy);
|
||||
BuildMI(*BB, MI, PPC::SUBF, 2, Temp1).addReg(Op0Reg).addReg(Op1Reg);
|
||||
BuildMI(*BB, MI, PPC::CNTLZW, 1, Temp2).addReg(Temp1);
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, DestReg).addReg(Temp2).addImm(5);
|
||||
break;
|
||||
}
|
||||
case 1: { // ne
|
||||
unsigned Temp1 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp2 = makeAnotherReg(Type::IntTy);
|
||||
BuildMI(*BB, MI, PPC::SUBF, 2, Temp1).addReg(Op0Reg).addReg(Op1Reg);
|
||||
BuildMI(*BB, MI, PPC::ADDIC, 2, Temp2).addReg(Temp1).addSImm(-1);
|
||||
BuildMI(*BB, MI, PPC::SUBFE, 2, DestReg).addReg(Temp2).addReg(Temp1);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 4: { // lt, gt
|
||||
unsigned Temp1 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp2 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp3 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp4 = makeAnotherReg(Type::IntTy);
|
||||
if (OpNum == 4) std::swap(Op0Reg, Op1Reg);
|
||||
if (Ty->isSigned()) {
|
||||
BuildMI(*BB, MI, PPC::SUBFC, 2, Temp1).addReg(Op1Reg).addReg(Op0Reg);
|
||||
BuildMI(*BB, MI, PPC::EQV, 2, Temp2).addReg(Op1Reg).addReg(Op0Reg);
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, Temp3).addReg(Temp2).addImm(31);
|
||||
BuildMI(*BB, MI, PPC::ADDZE, 1, Temp4).addReg(Temp3);
|
||||
BuildMI(*BB, MI, PPC::RLWINM, 4, DestReg).addReg(Temp4).addImm(0)
|
||||
.addImm(31).addImm(31);
|
||||
} else {
|
||||
BuildMI(*BB, MI, PPC::SUBFC, 2, Temp1).addReg(Op1Reg).addReg(Op0Reg);
|
||||
BuildMI(*BB, MI, PPC::SUBFE, 2, Temp2).addReg(Temp1).addReg(Temp1);
|
||||
BuildMI(*BB, MI, PPC::NEG, 2, DestReg).addReg(Temp2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
case 5: { // le, ge
|
||||
unsigned Temp1 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp2 = makeAnotherReg(Type::IntTy);
|
||||
unsigned Temp3 = makeAnotherReg(Type::IntTy);
|
||||
if (OpNum == 3) std::swap(Op0Reg, Op1Reg);
|
||||
if (Ty->isSigned()) {
|
||||
BuildMI(*BB, MI, PPC::SRWI, 2, Temp1).addReg(Op0Reg).addImm(31);
|
||||
BuildMI(*BB, MI, PPC::SRAWI, 2, Temp2).addReg(Op1Reg).addImm(31);
|
||||
BuildMI(*BB, MI, PPC::SUBFC, 2, Temp3).addReg(Op0Reg).addReg(Op1Reg);
|
||||
BuildMI(*BB, MI, PPC::ADDE, 2, DestReg).addReg(Temp2).addReg(Temp1);
|
||||
} else {
|
||||
BuildMI(*BB, MI, PPC::LI, 1, Temp2).addSImm(-1);
|
||||
BuildMI(*BB, MI, PPC::SUBFC, 2, Temp1).addReg(Op0Reg).addReg(Op1Reg);
|
||||
BuildMI(*BB, MI, PPC::SUBFZE, 1, DestReg).addReg(Temp2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
return;
|
||||
}
|
||||
EmitComparison(Opcode, Op0, Op1, BB, BB->end());
|
||||
|
||||
unsigned Opcode = I.getOpcode();
|
||||
unsigned PPCOpcode = getPPCOpcodeForSetCCNumber(Opcode);
|
||||
|
||||
// Create an iterator with which to insert the MBB for copying the false value
|
||||
// and the MBB to hold the PHI instruction for this SetCC.
|
||||
MachineBasicBlock *thisMBB = BB;
|
||||
const BasicBlock *LLVM_BB = BB->getBasicBlock();
|
||||
ilist<MachineBasicBlock>::iterator It = BB;
|
||||
@ -1260,32 +1124,18 @@ void ISel::visitSetCondInst(SetCondInst &I) {
|
||||
// thisMBB:
|
||||
// ...
|
||||
// cmpTY cr0, r1, r2
|
||||
// bCC copy1MBB
|
||||
// b copy0MBB
|
||||
|
||||
// FIXME: we wouldn't need copy0MBB (we could fold it into thisMBB)
|
||||
// if we could insert other, non-terminator instructions after the
|
||||
// bCC. But MBB->getFirstTerminator() can't understand this.
|
||||
MachineBasicBlock *copy1MBB = new MachineBasicBlock(LLVM_BB);
|
||||
F->getBasicBlockList().insert(It, copy1MBB);
|
||||
BuildMI(BB, PPCOpcode, 2).addReg(PPC::CR0).addMBB(copy1MBB);
|
||||
MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
|
||||
F->getBasicBlockList().insert(It, copy0MBB);
|
||||
BuildMI(BB, PPC::B, 1).addMBB(copy0MBB);
|
||||
MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
|
||||
F->getBasicBlockList().insert(It, sinkMBB);
|
||||
// Update machine-CFG edges
|
||||
BB->addSuccessor(copy1MBB);
|
||||
BB->addSuccessor(copy0MBB);
|
||||
|
||||
// copy1MBB:
|
||||
// %TrueValue = li 1
|
||||
// b sinkMBB
|
||||
BB = copy1MBB;
|
||||
// bCC sinkMBB
|
||||
EmitComparison(Opcode, I.getOperand(0), I.getOperand(1), BB, BB->end());
|
||||
unsigned TrueValue = makeAnotherReg(I.getType());
|
||||
BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1);
|
||||
BuildMI(BB, PPC::B, 1).addMBB(sinkMBB);
|
||||
MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
|
||||
MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
|
||||
BuildMI(BB, PPCOpcode, 2).addReg(PPC::CR0).addMBB(sinkMBB);
|
||||
F->getBasicBlockList().insert(It, copy0MBB);
|
||||
F->getBasicBlockList().insert(It, sinkMBB);
|
||||
// Update machine-CFG edges
|
||||
BB->addSuccessor(copy0MBB);
|
||||
BB->addSuccessor(sinkMBB);
|
||||
|
||||
// copy0MBB:
|
||||
@ -1298,11 +1148,11 @@ void ISel::visitSetCondInst(SetCondInst &I) {
|
||||
BB->addSuccessor(sinkMBB);
|
||||
|
||||
// sinkMBB:
|
||||
// %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, copy1MBB ]
|
||||
// %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
|
||||
// ...
|
||||
BB = sinkMBB;
|
||||
BuildMI(BB, PPC::PHI, 4, DestReg).addReg(FalseValue)
|
||||
.addMBB(copy0MBB).addReg(TrueValue).addMBB(copy1MBB);
|
||||
.addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
|
||||
}
|
||||
|
||||
void ISel::visitSelectInst(SelectInst &SI) {
|
||||
@ -1335,40 +1185,25 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
|
||||
BuildMI(*MBB, IP, PPC::CMPI, 2, PPC::CR0).addReg(CondReg).addSImm(0);
|
||||
Opcode = getPPCOpcodeForSetCCNumber(Instruction::SetNE);
|
||||
}
|
||||
|
||||
// thisMBB:
|
||||
// ...
|
||||
// cmpTY cr0, r1, r2
|
||||
// bCC copy1MBB
|
||||
// b copy0MBB
|
||||
unsigned TrueValue = getReg(TrueVal, BB, BB->end());
|
||||
|
||||
MachineBasicBlock *thisMBB = BB;
|
||||
const BasicBlock *LLVM_BB = BB->getBasicBlock();
|
||||
ilist<MachineBasicBlock>::iterator It = BB;
|
||||
++It;
|
||||
|
||||
// FIXME: we wouldn't need copy0MBB (we could fold it into thisMBB)
|
||||
// if we could insert other, non-terminator instructions after the
|
||||
// bCC. But MBB->getFirstTerminator() can't understand this.
|
||||
MachineBasicBlock *copy1MBB = new MachineBasicBlock(LLVM_BB);
|
||||
F->getBasicBlockList().insert(It, copy1MBB);
|
||||
BuildMI(BB, Opcode, 2).addReg(PPC::CR0).addMBB(copy1MBB);
|
||||
// thisMBB:
|
||||
// ...
|
||||
// cmpTY cr0, r1, r2
|
||||
// %TrueValue = ...
|
||||
// bCC sinkMBB
|
||||
MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
|
||||
F->getBasicBlockList().insert(It, copy0MBB);
|
||||
BuildMI(BB, PPC::B, 1).addMBB(copy0MBB);
|
||||
MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
|
||||
BuildMI(BB, Opcode, 2).addReg(PPC::CR0).addMBB(sinkMBB);
|
||||
F->getBasicBlockList().insert(It, copy0MBB);
|
||||
F->getBasicBlockList().insert(It, sinkMBB);
|
||||
// Update machine-CFG edges
|
||||
BB->addSuccessor(copy1MBB);
|
||||
BB->addSuccessor(copy0MBB);
|
||||
|
||||
// copy1MBB:
|
||||
// %TrueValue = ...
|
||||
// b sinkMBB
|
||||
BB = copy1MBB;
|
||||
unsigned TrueValue = getReg(TrueVal, BB, BB->begin());
|
||||
BuildMI(BB, PPC::B, 1).addMBB(sinkMBB);
|
||||
// Update machine-CFG edges
|
||||
BB->addSuccessor(sinkMBB);
|
||||
|
||||
// copy0MBB:
|
||||
@ -1380,12 +1215,14 @@ void ISel::emitSelectOperation(MachineBasicBlock *MBB,
|
||||
BB->addSuccessor(sinkMBB);
|
||||
|
||||
// sinkMBB:
|
||||
// %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, copy1MBB ]
|
||||
// %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
|
||||
// ...
|
||||
BB = sinkMBB;
|
||||
BuildMI(BB, PPC::PHI, 4, DestReg).addReg(FalseValue)
|
||||
.addMBB(copy0MBB).addReg(TrueValue).addMBB(copy1MBB);
|
||||
.addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
|
||||
|
||||
// For a register pair representing a long value, define the second reg
|
||||
// FIXME: Can this really be correct for selecting longs?
|
||||
if (getClassB(TrueVal->getType()) == cLong)
|
||||
BuildMI(BB, PPC::LI, 1, DestReg+1).addImm(0);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user