Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.276 -> 1.277 X86ISelLowering.h updated: 1.75 -> 1.76 X86InstrInfo.cpp updated: 1.63 -> 1.64 X86InstrInfo.h updated: 1.56 -> 1.57 --- Log message: Implement branch analysis/xform hooks required by the branch folding pass. --- Diffs of the changes: (+229 -87) X86ISelLowering.cpp | 107 ++++++++++++++---------------------- X86ISelLowering.h | 22 ------- X86InstrInfo.cpp | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++ X86InstrInfo.h | 36 ++++++++++++ 4 files changed, 229 insertions(+), 87 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.276 llvm/lib/Target/X86/X86ISelLowering.cpp:1.277 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.276 Mon Oct 16 01:36:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Oct 20 12:42:20 2006 @@ -2317,30 +2317,6 @@ return std::make_pair(Result, Chain); } -/// getCondBrOpcodeForX86CC - Returns the X86 conditional branch opcode -/// which corresponds to the condition code. -static unsigned getCondBrOpcodeForX86CC(unsigned X86CC) { - switch (X86CC) { - default: assert(0 && "Unknown X86 conditional code!"); - case X86ISD::COND_A: return X86::JA; - case X86ISD::COND_AE: return X86::JAE; - case X86ISD::COND_B: return X86::JB; - case X86ISD::COND_BE: return X86::JBE; - case X86ISD::COND_E: return X86::JE; - case X86ISD::COND_G: return X86::JG; - case X86ISD::COND_GE: return X86::JGE; - case X86ISD::COND_L: return X86::JL; - case X86ISD::COND_LE: return X86::JLE; - case X86ISD::COND_NE: return X86::JNE; - case X86ISD::COND_NO: return X86::JNO; - case X86ISD::COND_NP: return X86::JNP; - case X86ISD::COND_NS: return X86::JNS; - case X86ISD::COND_O: return X86::JO; - case X86ISD::COND_P: return X86::JP; - case X86ISD::COND_S: return X86::JS; - } -} - /// translateX86CC - do a one to one translation of a ISD::CondCode to the X86 /// specific condition code. It returns a false if it cannot do a direct /// translation. X86CC is the translated CondCode. LHS/RHS are modified as @@ -2348,33 +2324,33 @@ static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP, unsigned &X86CC, SDOperand &LHS, SDOperand &RHS, SelectionDAG &DAG) { - X86CC = X86ISD::COND_INVALID; + X86CC = X86::COND_INVALID; if (!isFP) { if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { if (SetCCOpcode == ISD::SETGT && RHSC->isAllOnesValue()) { // X > -1 -> X == 0, jump !sign. RHS = DAG.getConstant(0, RHS.getValueType()); - X86CC = X86ISD::COND_NS; + X86CC = X86::COND_NS; return true; } else if (SetCCOpcode == ISD::SETLT && RHSC->isNullValue()) { // X < 0 -> X == 0, jump on sign. - X86CC = X86ISD::COND_S; + X86CC = X86::COND_S; return true; } } switch (SetCCOpcode) { default: break; - case ISD::SETEQ: X86CC = X86ISD::COND_E; break; - case ISD::SETGT: X86CC = X86ISD::COND_G; break; - case ISD::SETGE: X86CC = X86ISD::COND_GE; break; - case ISD::SETLT: X86CC = X86ISD::COND_L; break; - case ISD::SETLE: X86CC = X86ISD::COND_LE; break; - case ISD::SETNE: X86CC = X86ISD::COND_NE; break; - case ISD::SETULT: X86CC = X86ISD::COND_B; break; - case ISD::SETUGT: X86CC = X86ISD::COND_A; break; - case ISD::SETULE: X86CC = X86ISD::COND_BE; break; - case ISD::SETUGE: X86CC = X86ISD::COND_AE; break; + case ISD::SETEQ: X86CC = X86::COND_E; break; + case ISD::SETGT: X86CC = X86::COND_G; break; + case ISD::SETGE: X86CC = X86::COND_GE; break; + case ISD::SETLT: X86CC = X86::COND_L; break; + case ISD::SETLE: X86CC = X86::COND_LE; break; + case ISD::SETNE: X86CC = X86::COND_NE; break; + case ISD::SETULT: X86CC = X86::COND_B; break; + case ISD::SETUGT: X86CC = X86::COND_A; break; + case ISD::SETULE: X86CC = X86::COND_BE; break; + case ISD::SETUGE: X86CC = X86::COND_AE; break; } } else { // On a floating point condition, the flags are set as follows: @@ -2387,29 +2363,29 @@ switch (SetCCOpcode) { default: break; case ISD::SETUEQ: - case ISD::SETEQ: X86CC = X86ISD::COND_E; break; + case ISD::SETEQ: X86CC = X86::COND_E; break; case ISD::SETOLT: Flip = true; // Fallthrough case ISD::SETOGT: - case ISD::SETGT: X86CC = X86ISD::COND_A; break; + case ISD::SETGT: X86CC = X86::COND_A; break; case ISD::SETOLE: Flip = true; // Fallthrough case ISD::SETOGE: - case ISD::SETGE: X86CC = X86ISD::COND_AE; break; + case ISD::SETGE: X86CC = X86::COND_AE; break; case ISD::SETUGT: Flip = true; // Fallthrough case ISD::SETULT: - case ISD::SETLT: X86CC = X86ISD::COND_B; break; + case ISD::SETLT: X86CC = X86::COND_B; break; case ISD::SETUGE: Flip = true; // Fallthrough case ISD::SETULE: - case ISD::SETLE: X86CC = X86ISD::COND_BE; break; + case ISD::SETLE: X86CC = X86::COND_BE; break; case ISD::SETONE: - case ISD::SETNE: X86CC = X86ISD::COND_NE; break; - case ISD::SETUO: X86CC = X86ISD::COND_P; break; - case ISD::SETO: X86CC = X86ISD::COND_NP; break; + case ISD::SETNE: X86CC = X86::COND_NE; break; + case ISD::SETUO: X86CC = X86::COND_P; break; + case ISD::SETO: X86CC = X86::COND_NP; break; } if (Flip) std::swap(LHS, RHS); } - return X86CC != X86ISD::COND_INVALID; + return X86CC != X86::COND_INVALID; } /// hasFPCMov - is there a floating point cmov for the specific X86 condition @@ -2419,14 +2395,14 @@ switch (X86CC) { default: return false; - case X86ISD::COND_B: - case X86ISD::COND_BE: - case X86ISD::COND_E: - case X86ISD::COND_P: - case X86ISD::COND_A: - case X86ISD::COND_AE: - case X86ISD::COND_NE: - case X86ISD::COND_NP: + case X86::COND_B: + case X86::COND_BE: + case X86::COND_E: + case X86::COND_P: + case X86::COND_A: + case X86::COND_AE: + case X86::COND_NE: + case X86::COND_NP: return true; } } @@ -3928,7 +3904,7 @@ SDOperand InFlag = DAG.getNode(X86ISD::CMP, VTs, 2, COps, 3).getValue(1); SDOperand Hi, Lo; - SDOperand CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8); + SDOperand CC = DAG.getConstant(X86::COND_NE, MVT::i8); VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag); SmallVector<SDOperand, 4> Ops; @@ -4148,17 +4124,17 @@ switch (SetCCOpcode) { default: assert(false && "Illegal floating point SetCC!"); case ISD::SETOEQ: { // !PF & ZF - SDOperand Ops1[] = { DAG.getConstant(X86ISD::COND_NP, MVT::i8), Cond }; + SDOperand Ops1[] = { DAG.getConstant(X86::COND_NP, MVT::i8), Cond }; SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops1, 2); - SDOperand Ops2[] = { DAG.getConstant(X86ISD::COND_E, MVT::i8), + SDOperand Ops2[] = { DAG.getConstant(X86::COND_E, MVT::i8), Tmp1.getValue(1) }; SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops2, 2); return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2); } case ISD::SETUNE: { // PF | !ZF - SDOperand Ops1[] = { DAG.getConstant(X86ISD::COND_P, MVT::i8), Cond }; + SDOperand Ops1[] = { DAG.getConstant(X86::COND_P, MVT::i8), Cond }; SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops1, 2); - SDOperand Ops2[] = { DAG.getConstant(X86ISD::COND_NE, MVT::i8), + SDOperand Ops2[] = { DAG.getConstant(X86::COND_NE, MVT::i8), Tmp1.getValue(1) }; SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, VTs2, 2, Ops2, 2); return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2); @@ -4199,7 +4175,7 @@ } if (addTest) { - CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8); + CC = DAG.getConstant(X86::COND_NE, MVT::i8); SDOperand Ops[] = { Chain, Cond, DAG.getConstant(0, MVT::i8) }; Cond = DAG.getNode(X86ISD::CMP, VTs, 2, Ops, 3); } @@ -4245,7 +4221,7 @@ } if (addTest) { - CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8); + CC = DAG.getConstant(X86::COND_NE, MVT::i8); SDOperand Ops[] = { Chain, Cond, DAG.getConstant(0, MVT::i8) }; Cond = DAG.getNode(X86ISD::CMP, VTs, 2, Ops, 3); } @@ -5069,7 +5045,8 @@ MachineBasicBlock *thisMBB = BB; MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); - unsigned Opc = getCondBrOpcodeForX86CC(MI->getOperand(3).getImmedValue()); + unsigned Opc = + X86::GetCondBranchFromCond((X86::CondCode)MI->getOperand(3).getImm()); BuildMI(BB, Opc, 1).addMBB(sinkMBB); MachineFunction *F = BB->getParent(); F->getBasicBlockList().insert(It, copy0MBB); @@ -5149,15 +5126,15 @@ } Op = MI->getOperand(1); if (Op.isImmediate()) - AM.Scale = Op.getImmedValue(); + AM.Scale = Op.getImm(); Op = MI->getOperand(2); if (Op.isImmediate()) - AM.IndexReg = Op.getImmedValue(); + AM.IndexReg = Op.getImm(); Op = MI->getOperand(3); if (Op.isGlobalAddress()) { AM.GV = Op.getGlobal(); } else { - AM.Disp = Op.getImmedValue(); + AM.Disp = Op.getImm(); } addFullAddress(BuildMI(BB, Opc, 5), AM).addReg(MI->getOperand(4).getReg()); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.75 llvm/lib/Target/X86/X86ISelLowering.h:1.76 --- llvm/lib/Target/X86/X86ISelLowering.h:1.75 Wed Oct 18 13:26:48 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Oct 20 12:42:20 2006 @@ -162,28 +162,6 @@ /// corresponds to X86::PINSRW. PINSRW }; - - // X86 specific condition code. These correspond to X86_*_COND in - // X86InstrInfo.td. They must be kept in synch. - enum CondCode { - COND_A = 0, - COND_AE = 1, - COND_B = 2, - COND_BE = 3, - COND_E = 4, - COND_G = 5, - COND_GE = 6, - COND_L = 7, - COND_LE = 8, - COND_NE = 9, - COND_NO = 10, - COND_NP = 11, - COND_NS = 12, - COND_O = 13, - COND_P = 14, - COND_S = 15, - COND_INVALID - }; } /// Define some predicates that are used for node matching. Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.63 llvm/lib/Target/X86/X86InstrInfo.cpp:1.64 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.63 Tue Oct 17 17:41:45 2006 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Fri Oct 20 12:42:20 2006 @@ -246,6 +246,157 @@ } } +static X86::CondCode GetCondFromBranchOpc(unsigned BrOpc) { + switch (BrOpc) { + default: return X86::COND_INVALID; + case X86::JE: return X86::COND_E; + case X86::JNE: return X86::COND_NE; + case X86::JL: return X86::COND_L; + case X86::JLE: return X86::COND_LE; + case X86::JG: return X86::COND_G; + case X86::JGE: return X86::COND_GE; + case X86::JB: return X86::COND_B; + case X86::JBE: return X86::COND_BE; + case X86::JA: return X86::COND_A; + case X86::JAE: return X86::COND_AE; + case X86::JS: return X86::COND_S; + case X86::JNS: return X86::COND_NS; + case X86::JP: return X86::COND_P; + case X86::JNP: return X86::COND_NP; + case X86::JO: return X86::COND_O; + case X86::JNO: return X86::COND_NO; + } +} + +unsigned X86::GetCondBranchFromCond(X86::CondCode CC) { + switch (CC) { + default: assert(0 && "Illegal condition code!"); + case X86::COND_E: return X86::JE; + case X86::COND_NE: return X86::JNE; + case X86::COND_L: return X86::JL; + case X86::COND_LE: return X86::JLE; + case X86::COND_G: return X86::JG; + case X86::COND_GE: return X86::JGE; + case X86::COND_B: return X86::JB; + case X86::COND_BE: return X86::JBE; + case X86::COND_A: return X86::JA; + case X86::COND_AE: return X86::JAE; + case X86::COND_S: return X86::JS; + case X86::COND_NS: return X86::JNS; + case X86::COND_P: return X86::JP; + case X86::COND_NP: return X86::JNP; + case X86::COND_O: return X86::JO; + case X86::COND_NO: return X86::JNO; + } +} + +bool X86InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, + MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + std::vector<MachineOperand> &Cond) const { + // TODO: If FP_REG_KILL is around, ignore it. + + // If the block has no terminators, it just falls into the block after it. + MachineBasicBlock::iterator I = MBB.end(); + if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode())) + return false; + + // Get the last instruction in the block. + MachineInstr *LastInst = I; + + // If there is only one terminator instruction, process it. + if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode())) { + if (!isBranch(LastInst->getOpcode())) + return true; + + // If the block ends with a branch there are 3 possibilities: + // it's an unconditional, conditional, or indirect branch. + + if (LastInst->getOpcode() == X86::JMP) { + TBB = LastInst->getOperand(0).getMachineBasicBlock(); + return false; + } + X86::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode()); + if (BranchCode == X86::COND_INVALID) + return true; // Can't handle indirect branch. + + // Otherwise, block ends with fall-through condbranch. + TBB = LastInst->getOperand(0).getMachineBasicBlock(); + Cond.push_back(MachineOperand::CreateImm(BranchCode)); + return false; + } + + // Get the instruction before it if it's a terminator. + MachineInstr *SecondLastInst = I; + + // If there are three terminators, we don't know what sort of block this is. + if (SecondLastInst && I != MBB.begin() && + isTerminatorInstr((--I)->getOpcode())) + return true; + + // If the block ends with X86::JMP and a COND_BRANCH, handle it. + X86::CondCode BranchCode = GetCondFromBranchOpc(SecondLastInst->getOpcode()); + if (BranchCode != X86::COND_INVALID && LastInst->getOpcode() == X86::JMP) { + TBB = SecondLastInst->getOperand(0).getMachineBasicBlock(); + Cond.push_back(MachineOperand::CreateImm(BranchCode)); + FBB = LastInst->getOperand(0).getMachineBasicBlock(); + return false; + } + + // Otherwise, can't handle this. + return true; +} + +void X86InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { + MachineBasicBlock::iterator I = MBB.end(); + if (I == MBB.begin()) return; + --I; + if (I->getOpcode() != X86::JMP && + GetCondFromBranchOpc(I->getOpcode()) == X86::COND_INVALID) + return; + + // Remove the branch. + I->eraseFromParent(); + + I = MBB.end(); + + if (I == MBB.begin()) return; + --I; + if (GetCondFromBranchOpc(I->getOpcode()) == X86::COND_INVALID) + return; + + // Remove the branch. + I->eraseFromParent(); +} + +void X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + const std::vector<MachineOperand> &Cond) const { + // Shouldn't be a fall through. + assert(TBB && "InsertBranch must not be told to insert a fallthrough"); + + // Unconditional branch? + if (FBB == 0) { + BuildMI(&MBB, X86::JMP, 1).addMBB(TBB); + return; + } + + assert(Cond.size() == 2 && "PPC branch conditions have two components!"); + + // Conditional branch. + unsigned Opc = GetCondBranchFromCond((X86::CondCode)Cond[0].getImm()); + BuildMI(&MBB, Opc, 1).addMBB(TBB); + + if (FBB) // Two-way branch. + BuildMI(&MBB, X86::JMP, 1).addMBB(FBB); +} + +bool X86InstrInfo:: +ReverseBranchCondition(std::vector<MachineOperand> &Cond) const { + // TODO: IMPLEMENT. + return true; +} + const TargetRegisterClass *X86InstrInfo::getPointerRegClass() const { const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>(); if (Subtarget->is64Bit()) Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.56 llvm/lib/Target/X86/X86InstrInfo.h:1.57 --- llvm/lib/Target/X86/X86InstrInfo.h:1.56 Tue Oct 17 17:41:45 2006 +++ llvm/lib/Target/X86/X86InstrInfo.h Fri Oct 20 12:42:20 2006 @@ -21,6 +21,33 @@ class X86RegisterInfo; class X86TargetMachine; +namespace X86 { + // X86 specific condition code. These correspond to X86_*_COND in + // X86InstrInfo.td. They must be kept in synch. + enum CondCode { + COND_A = 0, + COND_AE = 1, + COND_B = 2, + COND_BE = 3, + COND_E = 4, + COND_G = 5, + COND_GE = 6, + COND_L = 7, + COND_LE = 8, + COND_NE = 9, + COND_NO = 10, + COND_NP = 11, + COND_NS = 12, + COND_O = 13, + COND_P = 14, + COND_S = 15, + COND_INVALID + }; + + // Turn condition code into conditional branch opcode. + unsigned GetCondBranchFromCond(CondCode CC); +} + /// X86II - This namespace holds all of the target specific flags that /// instruction info tracks. /// @@ -227,6 +254,15 @@ /// virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + // Branch analysis. + virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + std::vector<MachineOperand> &Cond) const; + virtual void RemoveBranch(MachineBasicBlock &MBB) const; + virtual void InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + const std::vector<MachineOperand> &Cond) const; + virtual bool ReverseBranchCondition(std::vector<MachineOperand> &Cond) const; const TargetRegisterClass *getPointerRegClass() const; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits