[llvm-commits] [llvm] r54000 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h include/llvm/CodeGen/MachineRegisterInfo.h include/llvm/CodeGen/PseudoSourceValue.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/PseudoSourceValue.cpp test/CodeGen/X86/remat-constant.ll

Dan Gohman gohman at apple.com
Thu Jul 24 17:02:31 PDT 2008


Author: djg
Date: Thu Jul 24 19:02:30 2008
New Revision: 54000

URL: http://llvm.org/viewvc/llvm-project?rev=54000&view=rev
Log:
Enable rematerialization of constants using AliasAnalysis::pointsToConstantMemory,
and knowledge of PseudoSourceValues. This unfortunately isn't sufficient to allow
constants to be rematerialized in PIC mode -- the extra indirection is a
complication.

Added:
    llvm/trunk/test/CodeGen/X86/remat-constant.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
    llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h
    llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h
    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp

Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=54000&r1=53999&r2=54000&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Jul 24 19:02:30 2008
@@ -32,6 +32,7 @@
 
 namespace llvm {
 
+  class AliasAnalysis;
   class LiveVariables;
   class MachineLoopInfo;
   class TargetRegisterInfo;
@@ -61,6 +62,7 @@
     const TargetMachine* tm_;
     const TargetRegisterInfo* tri_;
     const TargetInstrInfo* tii_;
+    AliasAnalysis *aa_;
     LiveVariables* lv_;
 
     /// Special pool allocator for VNInfo's (LiveInterval val#).

Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h?rev=54000&r1=53999&r2=54000&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Thu Jul 24 19:02:30 2008
@@ -206,6 +206,14 @@
   liveout_iterator liveout_begin() const { return LiveOuts.begin(); }
   liveout_iterator liveout_end()   const { return LiveOuts.end(); }
   bool             liveout_empty() const { return LiveOuts.empty(); }
+
+  bool isLiveIn(unsigned Reg) const {
+    for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I)
+      if (I->first == Reg || I->second == Reg)
+        return true;
+    return false;
+  }
+
 private:
   void HandleVRegListReallocation();
   

Modified: llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h?rev=54000&r1=53999&r2=54000&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h (original)
+++ llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h Thu Jul 24 19:02:30 2008
@@ -17,6 +17,8 @@
 #include "llvm/Value.h"
 
 namespace llvm {
+  class MachineFrameInfo;
+
   /// PseudoSourceValue - Special value supplied for machine level alias
   /// analysis. It indicates that the a memory access references the functions
   /// stack frame (e.g., a spill slot), below the stack frame (e.g., argument
@@ -27,6 +29,10 @@
 
     virtual void print(std::ostream &OS) const;
 
+    /// isConstant - Test whether this PseudoSourceValue has a constant value.
+    ///
+    virtual bool isConstant(const MachineFrameInfo *) const;
+
     /// classof - Methods for support type inquiry through isa, cast, and
     /// dyn_cast:
     ///

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=54000&r1=53999&r2=54000&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Jul 24 19:02:30 2008
@@ -19,12 +19,14 @@
 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "VirtRegMap.h"
 #include "llvm/Value.h"
+#include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
@@ -54,6 +56,8 @@
 static RegisterPass<LiveIntervals> X("liveintervals", "Live Interval Analysis");
 
 void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<AliasAnalysis>();
+  AU.addPreserved<AliasAnalysis>();
   AU.addPreserved<LiveVariables>();
   AU.addRequired<LiveVariables>();
   AU.addPreservedID(MachineLoopInfoID);
@@ -212,6 +216,7 @@
   tm_ = &fn.getTarget();
   tri_ = tm_->getRegisterInfo();
   tii_ = tm_->getInstrInfo();
+  aa_ = &getAnalysis<AliasAnalysis>();
   lv_ = &getAnalysis<LiveVariables>();
   allocatableRegs_ = tri_->getAllocatableSet(fn);
 
@@ -750,7 +755,9 @@
     assert(!RegOp &&
            "Can't rematerialize instruction with multiple register operand!");
     RegOp = MO.getReg();
+#ifndef NDEBUG
     break;
+#endif
   }
   return RegOp;
 }
@@ -773,7 +780,6 @@
   if (DisableReMat)
     return false;
 
-  isLoad = false;
   if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
     return true;
 
@@ -786,27 +792,95 @@
     // This is a load from fixed stack slot. It can be rematerialized.
     return true;
 
-  if (tii_->isTriviallyReMaterializable(MI)) {
+  // If the target-specific rules don't identify an instruction as
+  // being trivially rematerializable, use some target-independent
+  // rules.
+  if (!MI->getDesc().isRematerializable() ||
+      !tii_->isTriviallyReMaterializable(MI)) {
+
+    // If the instruction access memory but the memoperands have been lost,
+    // we can't analyze it.
     const TargetInstrDesc &TID = MI->getDesc();
-    isLoad = TID.isSimpleLoad();
+    if ((TID.mayLoad() || TID.mayStore()) && MI->memoperands_empty())
+      return false;
 
-    unsigned ImpUse = getReMatImplicitUse(li, MI);
-    if (ImpUse) {
-      const LiveInterval &ImpLi = getInterval(ImpUse);
-      for (MachineRegisterInfo::use_iterator ri = mri_->use_begin(li.reg),
-             re = mri_->use_end(); ri != re; ++ri) {
-        MachineInstr *UseMI = &*ri;
-        unsigned UseIdx = getInstructionIndex(UseMI);
-        if (li.FindLiveRangeContaining(UseIdx)->valno != ValNo)
+    // Avoid instructions obviously unsafe for remat.
+    if (TID.hasUnmodeledSideEffects() || TID.isNotDuplicable())
+      return false;
+
+    // If the instruction accesses memory and the memory could be non-constant,
+    // assume the instruction is not rematerializable.
+    for (alist<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;
+      const Value *V = MMO.getValue();
+      if (!V)
+        return false;
+      if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V)) {
+        if (!PSV->isConstant(mf_->getFrameInfo()))
+          return false;
+      } else if (!aa_->pointsToConstantMemory(V))
+        return false;
+    }
+
+    // If any of the registers accessed are non-constant, conservatively assume
+    // the instruction is not rematerializable.
+    unsigned ImpUse = 0;
+    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+      const MachineOperand &MO = MI->getOperand(i);
+      if (MO.isReg()) {
+        unsigned Reg = MO.getReg();
+        if (Reg == 0)
           continue;
-        if (!isValNoAvailableAt(ImpLi, MI, UseIdx))
+        if (TargetRegisterInfo::isPhysicalRegister(Reg))
+          return false;
+
+        // Only allow one def, and that in the first operand.
+        if (MO.isDef() != (i == 0))
+          return false;
+
+        // Only allow constant-valued registers.
+        bool IsLiveIn = mri_->isLiveIn(Reg);
+        MachineRegisterInfo::def_iterator I = mri_->def_begin(Reg),
+                                          E = mri_->def_end();
+
+        // For the def, it should be the only def.
+        if (MO.isDef() && (next(I) != E || IsLiveIn))
           return false;
+
+        if (MO.isUse()) {
+          // Only allow one use other register use, as that's all the
+          // remat mechanisms support currently.
+          if (Reg != li.reg) {
+            if (ImpUse == 0)
+              ImpUse = Reg;
+            else if (Reg != ImpUse)
+              return false;
+          }
+          // For uses, there should be only one associate def.
+          if (I != E && (next(I) != E || IsLiveIn))
+            return false;
+        }
       }
     }
-    return true;
   }
 
-  return false;
+  unsigned ImpUse = getReMatImplicitUse(li, MI);
+  if (ImpUse) {
+    const LiveInterval &ImpLi = getInterval(ImpUse);
+    for (MachineRegisterInfo::use_iterator ri = mri_->use_begin(li.reg),
+           re = mri_->use_end(); ri != re; ++ri) {
+      MachineInstr *UseMI = &*ri;
+      unsigned UseIdx = getInstructionIndex(UseMI);
+      if (li.FindLiveRangeContaining(UseIdx)->valno != ValNo)
+        continue;
+      if (!isValNoAvailableAt(ImpLi, MI, UseIdx))
+        return false;
+    }
+  }
+  return true;
 }
 
 /// isReMaterializable - Returns true if every definition of MI of every

Modified: llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp?rev=54000&r1=53999&r2=54000&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp (original)
+++ llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp Thu Jul 24 19:02:30 2008
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Support/Compiler.h"
@@ -51,6 +52,9 @@
     const int FI;
   public:
     explicit FixedStackPseudoSourceValue(int fi) : FI(fi) {}
+
+    virtual bool isConstant(const MachineFrameInfo *MFI) const;
+
     virtual void print(std::ostream &OS) const {
       OS << "FixedStack" << FI;
     }
@@ -64,4 +68,20 @@
       V = new FixedStackPseudoSourceValue(FI);
     return V;
   }
+
+  bool PseudoSourceValue::isConstant(const MachineFrameInfo *) const {
+    if (this == getStack())
+      return false;
+    if (this == getGOT() ||
+        this == getConstantPool() ||
+        this == getJumpTable())
+      return true;
+    assert(0 && "Unknown PseudoSourceValue!");
+    return false;
+  }
+
+  bool
+  FixedStackPseudoSourceValue::isConstant(const MachineFrameInfo *MFI) const {
+    return MFI && MFI->isImmutableObjectIndex(FI);
+  }
 }

Added: llvm/trunk/test/CodeGen/X86/remat-constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/remat-constant.ll?rev=54000&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/remat-constant.ll (added)
+++ llvm/trunk/test/CodeGen/X86/remat-constant.ll Thu Jul 24 19:02:30 2008
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | llc -march=x86-64 -relocation-model=static | grep xmm | count 2
+
+declare void @bar() nounwind
+
+ at a = external constant float
+
+declare void @qux(float %f) nounwind 
+
+define void @foo() nounwind  {
+  %f = load float* @a
+  call void @bar()
+  call void @qux(float %f)
+  call void @qux(float %f)
+  ret void
+}





More information about the llvm-commits mailing list