[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