Hooks for predication support.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37093 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp
index 3f501a6..de9ea48 100644
--- a/lib/Target/ARM/ARMInstrInfo.cpp
+++ b/lib/Target/ARM/ARMInstrInfo.cpp
@@ -423,6 +423,28 @@
   return false;
 }
 
+bool ARMInstrInfo::isPredicatable(MachineInstr *MI) const {
+  const TargetInstrDescriptor *TID = MI->getInstrDescriptor();
+  if (TID->Flags & M_PREDICATED)
+    return true;
+
+  unsigned Opc = MI->getOpcode();
+  return Opc == ARM::B || Opc == ARM::tB;
+}
+
+void ARMInstrInfo::PredicateInstruction(MachineInstr *MI,
+                                      std::vector<MachineOperand> &Cond) const {
+  unsigned Opc = MI->getOpcode();
+  if (Opc == ARM::B || Opc == ARM::tB) {
+    MI->setInstrDescriptor(get(Opc == ARM::B ? ARM::Bcc : ARM::tBcc));
+    MI->addImmOperand(Cond[0].getImmedValue());
+    return;
+  }
+
+  MachineOperand *PMO = MI->findFirstPredOperand();
+  PMO->setImm(Cond[0].getImmedValue());
+}
+
 
 /// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
 static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h
index ebec9e5..d51b9bd 100644
--- a/lib/Target/ARM/ARMInstrInfo.h
+++ b/lib/Target/ARM/ARMInstrInfo.h
@@ -102,6 +102,11 @@
                             const std::vector<MachineOperand> &Cond) const;
   virtual bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const;
   virtual bool ReverseBranchCondition(std::vector<MachineOperand> &Cond) const;
+
+  // Predication support.
+  virtual bool isPredicatable(MachineInstr *MI) const;
+  virtual void PredicateInstruction(MachineInstr *MI,
+                                    std::vector<MachineOperand> &Cond) const;
 };
 
   // Utility routines
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index 3815875..57b6440 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -17,6 +17,7 @@
 #include "ARM.h"
 #include "llvm/Module.h"
 #include "llvm/PassManager.h"
+#include "llvm/CodeGen/Passes.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Target/TargetMachineRegistry.h"
 #include "llvm/Target/TargetOptions.h"
@@ -24,6 +25,8 @@
 
 static cl::opt<bool> DisableLdStOpti("disable-arm-loadstore-opti", cl::Hidden,
                               cl::desc("Disable load store optimization pass"));
+static cl::opt<bool> EnableIfConversion("enable-arm-if-conversion", cl::Hidden,
+                              cl::desc("Enable if-conversion pass"));
 
 namespace {
   // Register the target.
@@ -85,6 +88,14 @@
   return false;
 }
 
+bool ARMTargetMachine::addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
+  if (Fast || !EnableIfConversion || Subtarget.isThumb())
+    return false;
+
+  PM.add(createIfConverterPass());
+  return true;
+}
+
 bool ARMTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
   // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
   if (!Fast && !DisableLdStOpti && !Subtarget.isThumb())
diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h
index a50275c..dcdd128 100644
--- a/lib/Target/ARM/ARMTargetMachine.h
+++ b/lib/Target/ARM/ARMTargetMachine.h
@@ -53,6 +53,7 @@
   
   // Pass Pipeline Configuration
   virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+  virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast);
   virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
   virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast, 
                                   std::ostream &Out);