[llvm-commits] [llvm] r101154 - /llvm/trunk/lib/CodeGen/MachineLICM.cpp

Evan Cheng evan.cheng at apple.com
Tue Apr 13 11:16:00 PDT 2010


Author: evancheng
Date: Tue Apr 13 13:16:00 2010
New Revision: 101154

URL: http://llvm.org/viewvc/llvm-project?rev=101154&view=rev
Log:
Teach postra machine licm to hoist more obvious invariants, e.g. instructions with no source operands.

Modified:
    llvm/trunk/lib/CodeGen/MachineLICM.cpp

Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=101154&r1=101153&r2=101154&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Tue Apr 13 13:16:00 2010
@@ -101,10 +101,10 @@
     /// CandidateInfo - Keep track of information about hoisting candidates.
     struct CandidateInfo {
       MachineInstr *MI;
-      int           FI;
       unsigned      Def;
-      CandidateInfo(MachineInstr *mi, int fi, unsigned def)
-        : MI(mi), FI(fi), Def(def) {}
+      int           FI;
+      CandidateInfo(MachineInstr *mi, unsigned def, int fi)
+        : MI(mi), Def(def), FI(fi) {}
     };
 
     /// HoistRegionPostRA - Walk the specified region of the CFG and hoist loop
@@ -127,6 +127,11 @@
     void AddToLiveIns(unsigned Reg,
                       MachineBasicBlock *MBB, MachineBasicBlock *LoopHeader);    
 
+    /// IsLICMCandidate - Returns true if the instruction may be a suitable
+    /// candidate for LICM. e.g. If the instruction is a call, then it's obviously
+    /// not safe to hoist it.
+    bool IsLICMCandidate(MachineInstr &I);
+
     /// IsLoopInvariantInst - Returns true if the instruction is loop
     /// invariant. I.e., all virtual register operands are defined outside of
     /// the loop, physical registers aren't accessed (explicitly or implicitly),
@@ -271,6 +276,7 @@
                             SmallSet<int, 32> &StoredFIs,
                             SmallVector<CandidateInfo, 32> &Candidates) {
   bool RuledOut = false;
+  bool HasRegFIUse = false;
   unsigned Def = 0;
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
     const MachineOperand &MO = MI->getOperand(i);
@@ -281,6 +287,7 @@
           MFI->isSpillSlotObjectIndex(FI) &&
           InstructionStoresToFI(MI, FI))
         StoredFIs.insert(FI);
+      HasRegFIUse = true;
       continue;
     }
 
@@ -292,8 +299,10 @@
     assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
            "Not expecting virtual register!");
 
-    if (!MO.isDef())
+    if (!MO.isDef()) {
+      HasRegFIUse = true;
       continue;
+    }
 
     if (MO.isImplicit()) {
       ++PhysRegDefs[Reg];
@@ -325,13 +334,15 @@
         RuledOut = true;
   }
 
-  // FIXME: Only consider reloads for now. We should be able to handle
-  // remats which does not have register operands.
+  // Only consider reloads for now and remats which do not have register
+  // operands. FIXME: Consider unfold load folding instructions.
   if (Def && !RuledOut) {
-    int FI;
-    if (TII->isLoadFromStackSlot(MI, FI) &&
-        MFI->isSpillSlotObjectIndex(FI))
-      Candidates.push_back(CandidateInfo(MI, FI, Def));
+    int FI = INT_MIN;
+    // FIXME: Also hoist instructions if all source operands are live in
+    // to the loop.
+    if ((!HasRegFIUse && IsLICMCandidate(*MI)) ||
+        (TII->isLoadFromStackSlot(MI, FI) && MFI->isSpillSlotObjectIndex(FI)))
+      Candidates.push_back(CandidateInfo(MI, Def, FI));
   }
 }
 
@@ -385,7 +396,8 @@
   // 2. If the candidate is a load from stack slot (always true for now),
   //    check if the slot is stored anywhere in the loop.
   for (unsigned i = 0, e = Candidates.size(); i != e; ++i) {
-    if (StoredFIs.count(Candidates[i].FI))
+    if (Candidates[i].FI != INT_MIN &&
+        StoredFIs.count(Candidates[i].FI))
       continue;
 
     if (PhysRegDefs[Candidates[i].Def] == 1)
@@ -470,12 +482,10 @@
     HoistRegion(Children[I]);
 }
 
-/// IsLoopInvariantInst - Returns true if the instruction is loop
-/// invariant. I.e., all virtual register operands are defined outside of the
-/// loop, physical registers aren't accessed explicitly, and there are no side
-/// effects that aren't captured by the operands or other flags.
-/// 
-bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
+/// IsLICMCandidate - Returns true if the instruction may be a suitable
+/// candidate for LICM. e.g. If the instruction is a call, then it's obviously
+/// not safe to hoist it.
+bool MachineLICM::IsLICMCandidate(MachineInstr &I) {
   const TargetInstrDesc &TID = I.getDesc();
   
   // Ignore stuff that we obviously can't hoist.
@@ -493,6 +503,17 @@
       // This is a trivial form of alias analysis.
       return false;
   }
+  return true;
+}
+
+/// IsLoopInvariantInst - Returns true if the instruction is loop
+/// invariant. I.e., all virtual register operands are defined outside of the
+/// loop, physical registers aren't accessed explicitly, and there are no side
+/// effects that aren't captured by the operands or other flags.
+/// 
+bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
+  if (!IsLICMCandidate(I))
+    return false;
 
   // The instruction is loop invariant if all of its operands are.
   for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {





More information about the llvm-commits mailing list