[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.cpp X86InstrInfo.h
Chris Lattner
sabre at nondot.org
Fri Oct 20 10:42:35 PDT 2006
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;
More information about the llvm-commits
mailing list