Be nice to CellSPU: for this target getSetCCResultType
[oota-llvm.git] / lib / CodeGen / LiveIntervalAnalysis.cpp
index bc66321b4af3d941d058fc894591651636e7bdb4..d6c8a6561e4f85c680c201bca826a46e817b8fee 100644 (file)
@@ -30,6 +30,7 @@
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/ADT/Statistic.h"
@@ -67,8 +68,12 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<LiveVariables>();
   AU.addPreservedID(MachineLoopInfoID);
   AU.addPreservedID(MachineDominatorsID);
-  AU.addPreservedID(PHIEliminationID);
-  AU.addRequiredID(PHIEliminationID);
+  
+  if (!StrongPHIElim) {
+    AU.addPreservedID(PHIEliminationID);
+    AU.addRequiredID(PHIEliminationID);
+  }
+  
   AU.addRequiredID(TwoAddressInstructionPassID);
   MachineFunctionPass::getAnalysisUsage(AU);
 }
@@ -125,9 +130,13 @@ void LiveIntervals::computeNumbering() {
       MIIndex += InstrSlots::NUM;
       FunctionSize++;
       
-      // Insert an empty slot after every instruction.
-      MIIndex += InstrSlots::NUM;
-      i2miMap_.push_back(0);
+      // Insert max(1, numdefs) empty slots after every instruction.
+      unsigned Slots = I->getDesc().getNumDefs();
+      if (Slots == 0)
+        Slots = 1;
+      MIIndex += InstrSlots::NUM * Slots;
+      while (Slots--)
+        i2miMap_.push_back(0);
     }
     
     // Set the MBB2IdxMap entry for this MBB.
@@ -213,7 +222,7 @@ void LiveIntervals::computeNumbering() {
           
           unsigned index = (vni->kills[i]-1) / InstrSlots::NUM;
           unsigned offset = vni->kills[i] % InstrSlots::NUM;
-          if (offset == InstrSlots::STORE) {
+          if (offset == InstrSlots::LOAD) {
             std::vector<IdxMBBPair>::const_iterator I =
              std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->kills[i]);
             --I;
@@ -302,7 +311,7 @@ bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
           continue;
       for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
         MachineOperand& mop = MI->getOperand(i);
-        if (!mop.isRegister())
+        if (!mop.isReg())
           continue;
         unsigned PhysReg = mop.getReg();
         if (PhysReg == 0 || PhysReg == li.reg)
@@ -723,12 +732,16 @@ void LiveIntervals::computeIntervals() {
       for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
         MachineOperand &MO = MI->getOperand(i);
         // handle register defs - build intervals
-        if (MO.isRegister() && MO.getReg() && MO.isDef()) {
+        if (MO.isReg() && MO.getReg() && MO.isDef()) {
           handleRegisterDef(MBB, MI, MIIndex, MO, i);
         }
       }
-      
-      MIIndex += InstrSlots::NUM;
+
+      // Skip over the empty slots after each instruction.
+      unsigned Slots = MI->getDesc().getNumDefs();
+      if (Slots == 0)
+        Slots = 1;
+      MIIndex += InstrSlots::NUM * Slots;
       
       // Skip over empty indices.
       while (MIIndex / InstrSlots::NUM < i2miMap_.size() &&
@@ -789,7 +802,7 @@ unsigned LiveIntervals::getReMatImplicitUse(const LiveInterval &li,
   unsigned RegOp = 0;
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
     MachineOperand &MO = MI->getOperand(i);
-    if (!MO.isRegister() || !MO.isUse())
+    if (!MO.isReg() || !MO.isUse())
       continue;
     unsigned Reg = MO.getReg();
     if (Reg == 0 || Reg == li.reg)
@@ -819,6 +832,7 @@ bool LiveIntervals::isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI,
 /// val# of the specified interval is re-materializable.
 bool LiveIntervals::isReMaterializable(const LiveInterval &li,
                                        const VNInfo *ValNo, MachineInstr *MI,
+                                       SmallVectorImpl<LiveInterval*> &SpillIs,
                                        bool &isLoad) {
   if (DisableReMat)
     return false;
@@ -855,8 +869,8 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
 
     // If the instruction accesses memory and the memory could be non-constant,
     // assume the instruction is not rematerializable.
-    for (std::list<MachineMemOperand>::const_iterator I = MI->memoperands_begin(),
-         E = MI->memoperands_end(); I != E; ++I) {
+    for (std::list<MachineMemOperand>::const_iterator
+           I = MI->memoperands_begin(), E = MI->memoperands_end(); I != E; ++I){
       const MachineMemOperand &MMO = *I;
       if (MMO.isVolatile() || MMO.isStore())
         return false;
@@ -875,7 +889,7 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
     unsigned ImpUse = 0;
     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
       const MachineOperand &MO = MI->getOperand(i);
-      if (MO.isRegister()) {
+      if (MO.isReg()) {
         unsigned Reg = MO.getReg();
         if (Reg == 0)
           continue;
@@ -924,13 +938,21 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
       if (!isValNoAvailableAt(ImpLi, MI, UseIdx))
         return false;
     }
+
+    // If a register operand of the re-materialized instruction is going to
+    // be spilled next, then it's not legal to re-materialize this instruction.
+    for (unsigned i = 0, e = SpillIs.size(); i != e; ++i)
+      if (ImpUse == SpillIs[i]->reg)
+        return false;
   }
   return true;
 }
 
 /// isReMaterializable - Returns true if every definition of MI of every
 /// val# of the specified interval is re-materializable.
-bool LiveIntervals::isReMaterializable(const LiveInterval &li, bool &isLoad) {
+bool LiveIntervals::isReMaterializable(const LiveInterval &li,
+                                       SmallVectorImpl<LiveInterval*> &SpillIs,
+                                       bool &isLoad) {
   isLoad = false;
   for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end();
        i != e; ++i) {
@@ -944,7 +966,7 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li, bool &isLoad) {
     MachineInstr *ReMatDefMI = getInstructionFromIndex(DefIdx);
     bool DefIsLoad = false;
     if (!ReMatDefMI ||
-        !isReMaterializable(li, VNI, ReMatDefMI, DefIsLoad))
+        !isReMaterializable(li, VNI, ReMatDefMI, SpillIs, DefIsLoad))
       return false;
     isLoad |= DefIsLoad;
   }
@@ -1084,7 +1106,7 @@ void LiveIntervals::rewriteImplicitOps(const LiveInterval &li,
   // use operand. Make sure we rewrite that as well.
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
     MachineOperand &MO = MI->getOperand(i);
-    if (!MO.isRegister())
+    if (!MO.isReg())
       continue;
     unsigned Reg = MO.getReg();
     if (Reg == 0 || TargetRegisterInfo::isPhysicalRegister(Reg))
@@ -1119,7 +1141,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
  RestartInstruction:
   for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
     MachineOperand& mop = MI->getOperand(i);
-    if (!mop.isRegister())
+    if (!mop.isReg())
       continue;
     unsigned Reg = mop.getReg();
     unsigned RegI = Reg;
@@ -1171,7 +1193,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
     Ops.push_back(i);
     for (unsigned j = i+1, e = MI->getNumOperands(); j != e; ++j) {
       const MachineOperand &MOj = MI->getOperand(j);
-      if (!MOj.isRegister())
+      if (!MOj.isReg())
         continue;
       unsigned RegJ = MOj.getReg();
       if (RegJ == 0 || TargetRegisterInfo::isPhysicalRegister(RegJ))
@@ -1609,7 +1631,7 @@ LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
       NewLIs.push_back(&getOrCreateInterval(NewVReg));
       for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
         MachineOperand &MO = MI->getOperand(i);
-        if (MO.isRegister() && MO.getReg() == li.reg)
+        if (MO.isReg() && MO.getReg() == li.reg)
           MO.setReg(NewVReg);
       }
     }
@@ -1653,7 +1675,7 @@ addIntervalsForSpillsFast(const LiveInterval &li,
     
     for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
       MachineOperand& mop = MI->getOperand(i);
-      if (!mop.isRegister() || mop.getReg() != li.reg) continue;
+      if (!mop.isReg() || mop.getReg() != li.reg) continue;
       
       HasUse |= MI->getOperand(i).isUse();
       HasDef |= MI->getOperand(i).isDef();
@@ -1728,6 +1750,7 @@ addIntervalsForSpillsFast(const LiveInterval &li,
 
 std::vector<LiveInterval*> LiveIntervals::
 addIntervalsForSpills(const LiveInterval &li,
+                      SmallVectorImpl<LiveInterval*> &SpillIs,
                       const MachineLoopInfo *loopInfo, VirtRegMap &vrm,
                       float &SSWeight) {
   
@@ -1831,7 +1854,7 @@ addIntervalsForSpills(const LiveInterval &li,
     MachineInstr *ReMatDefMI = (DefIdx == ~0u)
       ? 0 : getInstructionFromIndex(DefIdx);
     bool dummy;
-    if (ReMatDefMI && isReMaterializable(li, VNI, ReMatDefMI, dummy)) {
+    if (ReMatDefMI && isReMaterializable(li, VNI, ReMatDefMI, SpillIs, dummy)) {
       // Remember how to remat the def of this val#.
       ReMatOrigDefs[VN] = ReMatDefMI;
       // Original def may be modified so we have to make a copy here.
@@ -1906,7 +1929,7 @@ addIntervalsForSpills(const LiveInterval &li,
           CanFold = true;
           for (unsigned j = 0, ee = MI->getNumOperands(); j != ee; ++j) {
             MachineOperand &MO = MI->getOperand(j);
-            if (!MO.isRegister() || MO.getReg() != VReg)
+            if (!MO.isReg() || MO.getReg() != VReg)
               continue;
 
             Ops.push_back(j);
@@ -1977,7 +2000,7 @@ addIntervalsForSpills(const LiveInterval &li,
         CanFold = true;
         for (unsigned j = 0, ee = MI->getNumOperands(); j != ee; ++j) {
           MachineOperand &MO = MI->getOperand(j);
-          if (!MO.isRegister() || MO.getReg() != VReg)
+          if (!MO.isReg() || MO.getReg() != VReg)
             continue;
 
           if (MO.isDef()) {