diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h
new file mode 100644
index 0000000..b7de04c
--- /dev/null
+++ b/include/llvm/Analysis/AliasSetTracker.h
@@ -0,0 +1,109 @@
+//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
+//
+// This file defines two classes: AliasSetTracker and AliasSet.  These interface
+// are used to classify a collection of pointer references into a maximal number
+// of disjoint sets.  Each AliasSet object constructed by the AliasSetTracker
+// object refers to memory disjoint from the other sets.
+// 
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
+#define LLVM_ANALYSIS_ALIASSETTRACKER_H
+
+#include <vector>
+class AliasAnalysis;
+class LoadInst;
+class StoreInst;
+class CallInst;
+class InvokeInst;
+class Value;
+class AliasSetTracker;
+
+class AliasSet {
+  friend class AliasSetTracker;
+  std::vector<LoadInst*> Loads;
+  std::vector<StoreInst*> Stores;
+  std::vector<CallInst*> Calls;
+  std::vector<InvokeInst*> Invokes;
+public:
+  /// AccessType - Keep track of whether this alias set merely refers to the
+  /// locations of memory, whether it modifies the memory, or whether it does
+  /// both.  The lattice goes from "None" (alias set not present) to either Refs
+  /// or Mods, then to ModRef as neccesary.
+  ///
+  enum AccessType {
+    Refs, Mods, ModRef
+  };
+
+  /// AliasType - Keep track the relationships between the pointers in the set.
+  /// Lattice goes from MustAlias to MayAlias.
+  ///
+  enum AliasType {
+    MustAlias, MayAlias
+  };
+private:
+  enum AccessType AccessTy;
+  enum AliasType  AliasTy;
+public:
+  /// Accessors...
+  enum AccessType getAccessType() const { return AccessTy; }
+  enum AliasType  getAliasType()  const { return AliasTy; }
+
+  // TODO: in the future, add a fixed size (4? 2?) cache of pointers that we
+  // know are in the alias set, to cut down time answering "pointeraliasesset"
+  // queries.
+
+  /// pointerAliasesSet - Return true if the specified pointer "may" (or must)
+  /// alias one of the members in the set.
+  ///
+  bool pointerAliasesSet(const Value *Ptr, AliasAnalysis &AA) const;
+
+  /// mergeSetIn - Merge the specified alias set into this alias set...
+  ///
+  void mergeSetIn(const AliasSet &AS);
+
+  const std::vector<LoadInst*>   &getLoads()   const { return Loads; }
+  const std::vector<StoreInst*>  &getStores()  const { return Stores; }
+  const std::vector<CallInst*>   &getCalls()   const { return Calls; }
+  const std::vector<InvokeInst*> &getInvokes() const { return Invokes; }
+
+private:
+  AliasSet() : AliasTy(MustAlias) {} // Can only be created by AliasSetTracker
+  void updateAccessType();
+  Value *getSomePointer() const;
+};
+
+
+class AliasSetTracker {
+  AliasAnalysis &AA;
+  std::vector<AliasSet> AliasSets;
+public:
+  /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
+  /// the specified alias analysis object to disambiguate load and store
+  /// addresses.
+  AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
+
+
+  /// add methods - These methods are used to add different types of
+  /// instructions to the alias sets.  Adding a new instruction can result in
+  /// one of three actions happening:
+  ///
+  ///   1. If the instruction doesn't alias any other sets, create a new set.
+  ///   2. If the instruction aliases exactly one set, add it to the set
+  ///   3. If the instruction aliases multiple sets, merge the sets, and add
+  ///      the instruction to the result.
+  ///
+  void add(LoadInst *LI);
+  void add(StoreInst *SI);
+  void add(CallInst *CI);
+  void add(InvokeInst *II);
+
+  /// getAliasSets - Return the alias sets that are active.
+  const std::vector<AliasSet> &getAliasSets() const { return AliasSets; }
+
+private:
+  AliasSet *findAliasSetForPointer(const Value *Ptr);
+  void mergeAllSets();
+};
+
+#endif
diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp
new file mode 100644
index 0000000..1413660
--- /dev/null
+++ b/lib/Analysis/AliasSetTracker.cpp
@@ -0,0 +1,172 @@
+//===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
+//
+// This file implements the AliasSetTracker and AliasSet classes.
+// 
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/iMemory.h"
+#include "llvm/iOther.h"
+#include "llvm/iTerminators.h"
+
+/// updateAccessTypes - Depending on what type of accesses are in this set,
+/// decide whether the set contains just references, just modifications, or a
+/// mix.
+///
+void AliasSet::updateAccessType() {
+  if (!Calls.empty() || !Invokes.empty()) {
+    AccessTy = ModRef;
+  } else if (!Loads.empty()) {
+    if (Stores.empty())
+      AccessTy = Refs;
+    else
+      AccessTy = ModRef;
+  } else {
+    AccessTy = Mods;
+  }
+}
+
+/// mergeSetIn - Merge the specified alias set into this alias set...
+///
+void AliasSet::mergeSetIn(const AliasSet &AS) {
+  // Merge instruction sets...
+    Loads.insert(  Loads.end(), AS.Loads.begin()  , AS.Loads.end());
+   Stores.insert( Stores.end(), AS.Stores.begin() , AS.Stores.end());
+    Calls.insert(  Calls.end(), AS.Calls.begin()  , AS.Calls.end());
+  Invokes.insert(Invokes.end(), AS.Invokes.begin(), AS.Invokes.end());
+
+  // Update the alias and access types of this set...
+  if (AS.getAliasType() == MayAlias)
+    AliasTy = MayAlias;
+  updateAccessType();
+}
+
+/// pointerAliasesSet - Return true if the specified pointer "may" (or must)
+/// alias one of the members in the set.
+///
+bool AliasSet::pointerAliasesSet(const Value *Ptr, AliasAnalysis &AA) const {
+  if (!Calls.empty() || !Invokes.empty())
+    return true;
+  for (unsigned i = 0, e = Loads.size(); i != e; ++i)
+    if (AA.alias(Ptr, Loads[i]->getOperand(0)))
+      return true;
+  for (unsigned i = 0, e = Stores.size(); i != e; ++i)
+    if (AA.alias(Ptr, Stores[i]->getOperand(1)))
+      return true;
+  return false;
+}
+
+/// getSomePointer - This method may only be called when the AliasType of the
+/// set is MustAlias.  This is used to return any old pointer (which must alias
+/// all other pointers in the set) so that the caller can decide whether to turn
+/// this set into a may alias set or not.
+///
+Value *AliasSet::getSomePointer() const {
+  assert(getAliasType() == MustAlias &&
+         "Cannot call getSomePointer on a 'MayAlias' set!");
+  assert(Calls.empty() && Invokes.empty() && "Call/invokes mean may alias!");
+
+  if (!Loads.empty())
+    return Loads[0]->getOperand(0);
+  assert(!Stores.empty() && "There are no instructions in this set!");
+  return Stores[0]->getOperand(1);
+}
+
+
+
+/// findAliasSetForPointer - Given a pointer, find the one alias set to put the
+/// instruction referring to the pointer into.  If there are multiple alias sets
+/// that may alias the pointer, merge them together and return the unified set.
+///
+AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr) {
+  AliasSet *FoundSet = 0;
+  for (unsigned i = 0; i != AliasSets.size(); ++i) {
+    if (AliasSets[i].pointerAliasesSet(Ptr, AA)) {
+      if (FoundSet == 0) {  // If this is the first alias set ptr can go into...
+        FoundSet = &AliasSets[i];   // Remember it.
+      } else {              // Otherwise, we must merge the sets...
+        FoundSet->mergeSetIn(AliasSets[i]);     // Merge in contents...
+        AliasSets.erase(AliasSets.begin()+i);   // Remove the set...
+        --i;                                    // Don't skip the next set
+      }
+    }
+  }
+
+  return FoundSet;
+}
+
+
+void AliasSetTracker::add(LoadInst *LI) {
+  Value *Pointer = LI->getOperand(0);
+
+  // Check to see if the loaded pointer aliases any sets...
+  AliasSet *AS = findAliasSetForPointer(Pointer);
+  if (AS) {
+    AS->Loads.push_back(LI);
+    // Check to see if we need to change this into a MayAlias set now...
+    if (AS->getAliasType() == AliasSet::MustAlias)
+      if (AA.alias(AS->getSomePointer(), Pointer) != AliasAnalysis::MustAlias)
+        AS->AliasTy = AliasSet::MayAlias;
+    AS->updateAccessType();
+  } else {
+    // Otherwise create a new alias set to hold the load...
+    AliasSets.push_back(AliasSet());
+    AliasSets.back().Loads.push_back(LI);
+    AliasSets.back().AccessTy = AliasSet::Refs;
+  }
+}
+
+void AliasSetTracker::add(StoreInst *SI) {
+  Value *Pointer = SI->getOperand(1);
+
+  // Check to see if the loaded pointer aliases any sets...
+  AliasSet *AS = findAliasSetForPointer(Pointer);
+  if (AS) {
+    AS->Stores.push_back(SI);
+    // Check to see if we need to change this into a MayAlias set now...
+    if (AS->getAliasType() == AliasSet::MustAlias)
+      if (AA.alias(AS->getSomePointer(), Pointer) != AliasAnalysis::MustAlias)
+        AS->AliasTy = AliasSet::MayAlias;
+    AS->updateAccessType();
+  } else {
+    // Otherwise create a new alias set to hold the load...
+    AliasSets.push_back(AliasSet());
+    AliasSets.back().Stores.push_back(SI);
+    AliasSets.back().AccessTy = AliasSet::Mods;
+  }
+}
+
+
+void AliasSetTracker::mergeAllSets() {
+  if (AliasSets.size() < 2) return;  // Noop
+
+  // Merge all of the sets into set #0
+  for (unsigned i = 1, e = AliasSets.size(); i != e; ++i)
+    AliasSets[0].mergeSetIn(AliasSets[i]);
+
+  // Delete extraneous sets...
+  AliasSets.erase(AliasSets.begin()+1, AliasSets.end());
+}
+
+void AliasSetTracker::add(CallInst *CI) {
+  if (!AliasSets.empty()) {
+    mergeAllSets();
+  } else {
+    AliasSets.push_back(AliasSet());
+  }
+  AliasSets[0].AccessTy = AliasSet::ModRef;
+  AliasSets[0].AliasTy = AliasSet::MayAlias;
+  AliasSets[0].Calls.push_back(CI);
+}
+
+void AliasSetTracker::add(InvokeInst *II) {
+  if (!AliasSets.empty()) {
+    mergeAllSets();
+  } else {
+    AliasSets.push_back(AliasSet());
+  }
+  AliasSets[0].AccessTy = AliasSet::ModRef;
+  AliasSets[0].AliasTy = AliasSet::MayAlias;
+  AliasSets[0].Invokes.push_back(II);
+}
