Basic "in frame" alias analysis.
authorJim Laskey <jlaskey@mac.com>
Thu, 21 Sep 2006 16:28:59 +0000 (16:28 +0000)
committerJim Laskey <jlaskey@mac.com>
Thu, 21 Sep 2006 16:28:59 +0000 (16:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30568 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp

index f093bf46f68037455798fe5cdbd0b1db77e08d5a..371dd8e5f5b9d6c44195bcaf736bc4dd498cb6ee 100644 (file)
@@ -35,6 +35,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/CommandLine.h"
 #include <algorithm>
 #include <cmath>
 #include <iostream>
@@ -43,8 +44,17 @@ using namespace llvm;
 namespace {
   static Statistic<> NodesCombined ("dagcombiner", 
                                    "Number of dag nodes combined");
-
-  class VISIBILITY_HIDDEN DAGCombiner {
+            
+
+#ifndef NDEBUG
+static cl::opt<bool>
+  CombinerAA("combiner-alias-analysis", cl::Hidden,
+             cl::desc("Turn on alias analysis turning testing"));
+#else
+  static const bool CombinerAA = 0;
+#endif
+class VISIBILITY_HIDDEN DAGCombiner {
     SelectionDAG &DAG;
     TargetLowering &TLI;
     bool AfterLegalize;
@@ -231,6 +241,7 @@ namespace {
     SDOperand BuildSDIV(SDNode *N);
     SDOperand BuildUDIV(SDNode *N);
     SDNode *MatchRotate(SDOperand LHS, SDOperand RHS);
+    bool isNotAlias(SDOperand Ptr1, SDOperand Ptr2);
 public:
     DAGCombiner(SelectionDAG &D)
       : DAG(D), TLI(D.getTargetLoweringInfo()), AfterLegalize(false) {}
@@ -2577,6 +2588,27 @@ SDOperand DAGCombiner::visitXEXTLOAD(SDNode *N) {
   return SDOperand();
 }
 
+/// isNotAlias - Return true if we have definitive knowlege that the two
+/// addresses don't overlap.
+bool DAGCombiner::isNotAlias(SDOperand Ptr1, SDOperand Ptr2) {
+  // Mind the flag.
+  if (!CombinerAA) return false;
+  
+  // If they are the same then they are simple aliases.
+  if (Ptr1 == Ptr2) return false;
+  
+  // If either operand is a frame value (not the same location from above test)
+  // then they can't alias.
+  FrameIndexSDNode *FI1 = dyn_cast<FrameIndexSDNode>(Ptr1);
+  FrameIndexSDNode *FI2 = dyn_cast<FrameIndexSDNode>(Ptr2);
+  if (FI1 || FI2) {
+    return true;
+  }
+  
+  // Otherwise we don't know and have to play it safe.
+  return false;
+}
+
 SDOperand DAGCombiner::visitSTORE(SDNode *N) {
   SDOperand Chain    = N->getOperand(0);
   SDOperand Value    = N->getOperand(1);
@@ -2607,6 +2639,22 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
   if (0 && Value.getOpcode() == ISD::BIT_CONVERT)
     return DAG.getNode(ISD::STORE, MVT::Other, Chain, Value.getOperand(0),
                        Ptr, SrcValue);
+                       
+  // If the previous store is not an alias then break artificial chain.
+  if (Chain.getOpcode() == ISD::STORE && isNotAlias(Ptr, Chain.getOperand(2))) {
+    // Replace the chain to void dependency.
+    SDNode *PrevStore = Chain.Val;
+    SDOperand ReplStore = DAG.getNode(ISD::STORE, MVT::Other,
+                                     PrevStore->getOperand(0), Value, Ptr,
+                                     SrcValue);
+    // Create token to keep both stores around.
+    SDOperand Token = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                      Chain, ReplStore);
+    // Replace uses with token.
+    CombineTo(N, Token);
+    // Don't recombine on token.
+    return SDOperand(N, 0);
+  }
   
   return SDOperand();
 }