diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp | 213 | 
1 files changed, 25 insertions, 188 deletions
diff --git a/llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp b/llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp index a49f2538e1c..da057a65cad 100644 --- a/llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp +++ b/llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp @@ -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); +  //   %TrueValue = li 1 +  //   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);    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, PPCOpcode, 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 = li 1 -  //   b sinkMBB -  BB = copy1MBB; -  unsigned TrueValue = makeAnotherReg(I.getType()); -  BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1); -  BuildMI(BB, PPC::B, 1).addMBB(sinkMBB); -  // Update machine-CFG edges    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;  | 

