implement branch inspection/modification methods.
authorChris Lattner <sabre@nondot.org>
Fri, 13 Oct 2006 21:21:17 +0000 (21:21 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 13 Oct 2006 21:21:17 +0000 (21:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30946 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCInstrInfo.cpp
lib/Target/PowerPC/PPCInstrInfo.h

index 83a0aaadb8fccc7bbb991f91e3da6994532154e9..ddb9dbf3162765fdd38e4b57c61cd096b7f4df91 100644 (file)
@@ -162,3 +162,96 @@ void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator MI) const {
   BuildMI(MBB, MI, PPC::NOP, 0);
 }
+
+
+// Branch analysis.
+bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
+                                 MachineBasicBlock *&FBB,
+                                 std::vector<MachineOperand> &Cond) const {
+  // 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 (LastInst->getOpcode() == PPC::B) {
+      TBB = LastInst->getOperand(0).getMachineBasicBlock();
+      return false;
+    } else if (LastInst->getOpcode() == PPC::COND_BRANCH) {
+      // Block ends with fall-through condbranch.
+      TBB = LastInst->getOperand(2).getMachineBasicBlock();
+      Cond.push_back(LastInst->getOperand(0));
+      Cond.push_back(LastInst->getOperand(1));
+      return true;
+    }
+    // Otherwise, don't know what this is.
+    return true;
+  }
+  
+  // 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 PPC::B and PPC:COND_BRANCH, handle it.
+  if (SecondLastInst->getOpcode() == PPC::COND_BRANCH && 
+      LastInst->getOpcode() == PPC::B) {
+    TBB =  SecondLastInst->getOperand(2).getMachineBasicBlock();
+    Cond.push_back(SecondLastInst->getOperand(0));
+    Cond.push_back(SecondLastInst->getOperand(1));
+    FBB = LastInst->getOperand(0).getMachineBasicBlock();
+    return false;
+  }
+  
+  // Otherwise, can't handle this.
+  return true;
+}
+
+void PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
+  MachineBasicBlock::iterator I = MBB.end();
+  if (I == MBB.begin()) return;
+  --I;
+  if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::COND_BRANCH)
+    return;
+  
+  // Remove the branch.
+  I->eraseFromParent();
+  
+  I = MBB.end();
+
+  if (I == MBB.begin()) return;
+  --I;
+  if (I->getOpcode() != PPC::COND_BRANCH)
+    return;
+  
+  // Remove the branch.
+  I->eraseFromParent();
+}
+
+void PPCInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+                                MachineBasicBlock *FBB,
+                                const std::vector<MachineOperand> &Cond) const {
+  // Fall through?
+  if (TBB == 0 && FBB == 0) return;
+  
+  assert(Cond.size() == 2 && "PPC branch conditions have two components!");
+  
+  // Conditional branch
+  BuildMI(&MBB, PPC::COND_BRANCH, 3)
+    .addReg(Cond[0].getReg()).addImm(Cond[1].getImm()).addMBB(TBB);
+  
+  if (FBB)  // Two-way branch.
+    BuildMI(&MBB, PPC::B, 1).addMBB(FBB);
+}
+
+bool PPCInstrInfo::
+ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
+  return true;
+}
index eecc1bc8be6bfe9e68d59b0359d00e0c63bdb651..265e1e76c2f3a36caf4b2596a7613e36d057e3b9 100644 (file)
@@ -94,6 +94,19 @@ public:
   virtual void insertNoop(MachineBasicBlock &MBB, 
                           MachineBasicBlock::iterator 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;
+  
+  
+  
   static unsigned invertPPCBranchOpcode(unsigned Opcode) {
     switch (Opcode) {
     default: assert(0 && "Unknown PPC branch opcode!");