Add a new optimization pass: Stack Coloring, that merges disjoint static allocations (allocas). Allocas are known to be
disjoint if they are marked by disjoint lifetime markers (@llvm.lifetime.XXX intrinsics).



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163299 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 31d633c..b587884 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -19,6 +19,7 @@
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Constants.h"
 #include "llvm/CallingConv.h"
 #include "llvm/DebugInfo.h"
@@ -5215,14 +5216,30 @@
                                         rw==1)); /* write */
     return 0;
   }
-
-  case Intrinsic::invariant_start:
   case Intrinsic::lifetime_start:
+  case Intrinsic::lifetime_end: {
+    SDValue Ops[2];
+    AllocaInst *LifetimeObject =dyn_cast_or_null<AllocaInst>(
+                                   GetUnderlyingObject(I.getArgOperand(1), TD));
+    // Could not find an Alloca.
+    if (!LifetimeObject)
+      return 0;
+
+    int FI = FuncInfo.StaticAllocaMap[LifetimeObject];
+    Ops[0] = getRoot();
+    Ops[1] = DAG.getFrameIndex(FI, TLI.getPointerTy(), true);
+    bool IsStart = (Intrinsic == Intrinsic::lifetime_start);
+    unsigned Opcode = (IsStart ? ISD::LIFETIME_START : ISD::LIFETIME_END);
+
+    Res = DAG.getNode(Opcode, dl, MVT::Other, Ops, 2);
+    DAG.setRoot(Res);
+    return 0;
+  }
+  case Intrinsic::invariant_start:
     // Discard region information.
     setValue(&I, DAG.getUNDEF(TLI.getPointerTy()));
     return 0;
   case Intrinsic::invariant_end:
-  case Intrinsic::lifetime_end:
     // Discard region information.
     return 0;
   case Intrinsic::donothing: