Disable compare sinking in CodeGenPrepare when multiple condition registers are available
authorHal Finkel <hfinkel@anl.gov>
Thu, 2 Jan 2014 21:13:43 +0000 (21:13 +0000)
committerHal Finkel <hfinkel@anl.gov>
Thu, 2 Jan 2014 21:13:43 +0000 (21:13 +0000)
As noted in the comment above CodeGenPrepare::OptimizeInst, which aggressively
sinks compares to reduce pressure on the condition register(s), for targets
such as PowerPC with multiple condition registers, this may not be the right
thing to do. This adds an HasMultipleConditionRegisters boolean to TLI, and
CodeGenPrepare::OptimizeInst is skipped when HasMultipleConditionRegisters is
true.

This functionality will be used by the PowerPC backend in an upcoming commit.
Especially when the PowerPC backend starts tracking individual condition
register bits as separate allocatable entities (which will happen in this
upcoming commit), this sinking from CodeGenPrepare::OptimizeInst is
significantly suboptimial.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198354 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/CodeGen/TargetLoweringBase.cpp
lib/Transforms/Scalar/CodeGenPrepare.cpp

index 57e142139b4050a07b3f1b852af6b25aa39a1ac7..e6917b74e7dcd4cd0a05a51b41fe3ff1852e93b6 100644 (file)
@@ -173,6 +173,11 @@ public:
     return true;
   }
 
+  /// Return true if multiple condition registers are available.
+  bool hasMultipleConditionRegisters() const {
+    return HasMultipleConditionRegisters;
+  }
+
   /// Return true if a vector of the given type should be split
   /// (TypeSplitVector) instead of promoted (TypePromoteInteger) during type
   /// legalization.
@@ -926,6 +931,15 @@ protected:
     SelectIsExpensive = isExpensive;
   }
 
+  /// Tells the code generator that the target has multiple (allocatable)
+  /// condition registers that can be used to store the results of comparisons
+  /// for use by selects and conditional branches. With multiple condition
+  /// registers, the code generator will not aggressively sink comparisons into
+  /// the blocks of their users.
+  void setHasMultipleConditionRegisters(bool hasManyRegs = true) {
+    HasMultipleConditionRegisters = hasManyRegs;
+  }
+
   /// Tells the code generator not to expand sequence of operations into a
   /// separate sequences that increases the amount of flow control.
   void setJumpIsExpensive(bool isExpensive = true) {
@@ -1321,6 +1335,13 @@ private:
   /// the select operations if possible.
   bool SelectIsExpensive;
 
+  /// Tells the code generator that the target has multiple (allocatable)
+  /// condition registers that can be used to store the results of comparisons
+  /// for use by selects and conditional branches. With multiple condition
+  /// registers, the code generator will not aggressively sink comparisons into
+  /// the blocks of their users.
+  bool HasMultipleConditionRegisters;
+
   /// Tells the code generator not to expand integer divides by constants into a
   /// sequence of muls, adds, and shifts.  This is a hack until a real cost
   /// model is in place.  If we ever optimize for size, this will be set to true
index 7b1931d407751720d6bf83b1a77cc93a993b50bb..beaa9b9f7405a0859203f8738f36791a9992e6ea 100644 (file)
@@ -672,6 +672,7 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm,
   UseUnderscoreSetJmp = false;
   UseUnderscoreLongJmp = false;
   SelectIsExpensive = false;
+  HasMultipleConditionRegisters = false;
   IntDivIsCheap = false;
   Pow2DivIsCheap = false;
   JumpIsExpensive = false;
index 007e9b79e20a9afb9a7b8a8a468ac8ad043c2035..79d92ce5a5348dea175568b4ce608f8b8a4fc21e 100644 (file)
@@ -1916,7 +1916,8 @@ bool CodeGenPrepare::OptimizeInst(Instruction *I) {
   }
 
   if (CmpInst *CI = dyn_cast<CmpInst>(I))
-    return OptimizeCmpExpression(CI);
+    if (!TLI || !TLI->hasMultipleConditionRegisters())
+      return OptimizeCmpExpression(CI);
 
   if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
     if (TLI)