Fixed logic error. Should check Builder for validity before calling SetSession
[oota-llvm.git] / lib / Target / ARM / Thumb2ITBlockPass.cpp
index da7228b3457f8d247b548d0d3e3b37f4a3a0725a..f36d4ef7567ee650fe9b0f115d55ac6054e73221 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Thumb2ITBlockPass.cpp - Insert Thumb IT blocks -----------*- C++ -*-===//
+//===-- Thumb2ITBlockPass.cpp - Insert Thumb IT blocks ----------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Support/Compiler.h"
 #include "llvm/ADT/Statistic.h"
 using namespace llvm;
 
 STATISTIC(NumITs,     "Number of IT blocks inserted");
 
 namespace {
-  struct VISIBILITY_HIDDEN Thumb2ITBlockPass : public MachineFunctionPass {
+  struct Thumb2ITBlockPass : public MachineFunctionPass {
     static char ID;
     Thumb2ITBlockPass() : MachineFunctionPass(&ID) {}
 
@@ -40,12 +39,11 @@ namespace {
   char Thumb2ITBlockPass::ID = 0;
 }
 
-static ARMCC::CondCodes getPredicate(const MachineInstr *MI,
-                                     const Thumb2InstrInfo *TII) {
+static ARMCC::CondCodes getPredicate(const MachineInstr *MI, unsigned &PredReg){
   unsigned Opc = MI->getOpcode();
   if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
     return ARMCC::AL;
-  return TII->getPredicate(MI);
+  return llvm::getInstrPredicate(MI, PredReg);
 }
 
 bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) {
@@ -54,35 +52,42 @@ bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) {
   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
   while (MBBI != E) {
     MachineInstr *MI = &*MBBI;
-    ARMCC::CondCodes CC = getPredicate(MI, TII);
+    DebugLoc dl = MI->getDebugLoc();
+    unsigned PredReg = 0;
+    ARMCC::CondCodes CC = getPredicate(MI, PredReg);
+
     if (CC == ARMCC::AL) {
       ++MBBI;
       continue;
     }
 
     // Insert an IT instruction.
-    DebugLoc dl = MI->getDebugLoc();
     MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
       .addImm(CC);
     ++MBBI;
 
-    // Finalize IT mask. If the following instruction is not predicated or it's
-    // predicated on a condition that's not the same or the opposite of CC, then
-    // the mask is 0x8.
+    // Finalize IT mask.
     ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
-    unsigned Mask = 0x8;
-    while (MBBI != E || (Mask & 1)) {
-      ARMCC::CondCodes NCC = getPredicate(&*MBBI, TII);
-      if (NCC == CC) {
-        Mask >>= 1;
-        Mask |= 0x8;
-      } else if (NCC == OCC) {
-        Mask >>= 1;
-      } else {
+    unsigned Mask = 0, Pos = 3;
+    // Branches, including tricky ones like LDM_RET, need to end an IT
+    // block so check the instruction we just put in the block.
+    while (MBBI != E && Pos &&
+           (!MI->getDesc().isBranch() && !MI->getDesc().isReturn())) {
+      MachineInstr *NMI = &*MBBI;
+      MI = NMI;
+      DebugLoc ndl = NMI->getDebugLoc();
+      unsigned NPredReg = 0;
+      ARMCC::CondCodes NCC = getPredicate(NMI, NPredReg);
+      if (NCC == CC || NCC == OCC)
+        Mask |= (NCC & 1) << Pos;
+      else
         break;
-      }
+      --Pos;
       ++MBBI;
     }
+    Mask |= (1 << Pos);
+    // Tag along (firstcond[0] << 4) with the mask.
+    Mask |= (CC & 1) << 4;
     MIB.addImm(Mask);
     Modified = true;
     ++NumITs;