[CFLAA] Handle global/arg attrs more sanely.

Prior to this patch, we used argument/global stratified attributes in
order to note that a value could have come from either dereferencing a
global/arg, or from the assignment from a global/arg.

Now, AttrUnknown is placed on sets when we see a dereference, instead of
the global/arg attributes. This allows us to be more aggressive in the
future when we see global/arg attributes without AttrUnknown.

Patch by Jia Chen.

Differential Revision: http://reviews.llvm.org/D21110

llvm-svn: 272335
diff --git a/llvm/lib/Analysis/StratifiedSets.h b/llvm/lib/Analysis/StratifiedSets.h
index ae1befb..0e20343 100644
--- a/llvm/lib/Analysis/StratifiedSets.h
+++ b/llvm/lib/Analysis/StratifiedSets.h
@@ -395,6 +395,17 @@
     return addAtMerging(ToAdd, Below);
   }
 
+  /// \brief Set the StratifiedAttrs of the set below "Main". If there is no set
+  /// below "Main", create one for it.
+  void addAttributesBelow(const T &Main, StratifiedAttrs Attr) {
+    assert(has(Main));
+    auto Index = *indexOf(Main);
+    auto Link = linksAt(Index);
+
+    auto BelowIndex = Link.hasBelow() ? Link.getBelow() : addLinkBelow(Index);
+    linksAt(BelowIndex).setAttrs(Attr);
+  }
+
   bool addWith(const T &Main, const T &ToAdd) {
     assert(has(Main));
     auto MainIndex = *indexOf(Main);