diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index e5a1ad294b5..28ec9db62e7 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -116,10 +116,16 @@ public:
   /// value.
   unsigned getAlignment() const;
 
+  /// \brief Set the alignment field of an attribute.
+  void setAlignment(unsigned Align);
+
   /// \brief Returns the stack alignment field of an attribute as a byte
   /// alignment value.
   unsigned getStackAlignment() const;
 
+  /// \brief Set the stack alignment field of an attribute.
+  void setStackAlignment(unsigned Align);
+
   /// \brief Equality and non-equality query methods.
   bool operator==(AttrKind K) const;
   bool operator!=(AttrKind K) const;
@@ -233,6 +239,15 @@ public:
   /// the form used internally in Attribute.
   AttrBuilder &addStackAlignmentAttr(unsigned Align);
 
+  typedef DenseSet<Attribute::AttrKind>::iterator       iterator;
+  typedef DenseSet<Attribute::AttrKind>::const_iterator const_iterator;
+
+  iterator begin() { return Attrs.begin(); }
+  iterator end()   { return Attrs.end(); }
+
+  const_iterator begin() const { return Attrs.begin(); }
+  const_iterator end() const   { return Attrs.end(); }
+
   /// \brief Add the raw value to the internal representation.
   /// 
   /// N.B. This should be used ONLY for decoding LLVM bitcode!
@@ -329,6 +344,7 @@ public:
 
   /// \brief Return an AttributeSet with the specified parameters in it.
   static AttributeSet get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
+  static AttributeSet get(LLVMContext &C, unsigned Idx, AttrBuilder &B);
 
   /// \brief Add the specified attribute at the specified index to this
   /// attribute list.  Since attribute lists are immutable, this returns the new
diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h
index 42b4fe36b22..a2a5218d806 100644
--- a/lib/IR/AttributeImpl.h
+++ b/lib/IR/AttributeImpl.h
@@ -29,6 +29,7 @@ class LLVMContext;
 /// \brief This class represents a single, uniqued attribute. That attribute
 /// could be a single enum, a tuple, or a string.
 class AttributeImpl : public FoldingSetNode {
+  LLVMContext &Context;
   Constant *Data;
   SmallVector<Constant*, 0> Vals;
 public:
@@ -47,7 +48,10 @@ public:
   bool hasAttributes() const;
 
   uint64_t getAlignment() const;
+  void setAlignment(unsigned Align);
+
   uint64_t getStackAlignment() const;
+  void setStackAlignment(unsigned Align);
 
   bool operator==(Attribute::AttrKind Kind) const;
   bool operator!=(Attribute::AttrKind Kind) const;
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp
index 068b5042948..84f90ade8b2 100644
--- a/lib/IR/Attributes.cpp
+++ b/lib/IR/Attributes.cpp
@@ -76,6 +76,12 @@ unsigned Attribute::getAlignment() const {
   return 1U << ((pImpl->getAlignment() >> 16) - 1);
 }
 
+void Attribute::setAlignment(unsigned Align) {
+  assert(hasAttribute(Attribute::Alignment) &&
+         "Trying to set the alignment on a non-alignment attribute!");
+  pImpl->setAlignment(Align);
+}
+
 /// This returns the stack alignment field of an attribute as a byte alignment
 /// value.
 unsigned Attribute::getStackAlignment() const {
@@ -84,6 +90,12 @@ unsigned Attribute::getStackAlignment() const {
   return 1U << ((pImpl->getStackAlignment() >> 26) - 1);
 }
 
+void Attribute::setStackAlignment(unsigned Align) {
+  assert(hasAttribute(Attribute::StackAlignment) &&
+         "Trying to set the stack alignment on a non-alignment attribute!");
+  pImpl->setStackAlignment(Align);
+}
+
 bool Attribute::operator==(AttrKind K) const {
   return pImpl && *pImpl == K;
 }
@@ -367,19 +379,23 @@ bool AttrBuilder::operator==(const AttrBuilder &B) {
 // AttributeImpl Definition
 //===----------------------------------------------------------------------===//
 
-AttributeImpl::AttributeImpl(LLVMContext &C, uint64_t data) {
+AttributeImpl::AttributeImpl(LLVMContext &C, uint64_t data)
+  : Context(C) {
   Data = ConstantInt::get(Type::getInt64Ty(C), data);
 }
-AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) {
+AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data)
+  : Context(C) {
   Data = ConstantInt::get(Type::getInt64Ty(C), data);
 }
 AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data,
-                             ArrayRef<Constant*> values) {
+                             ArrayRef<Constant*> values)
+  : Context(C) {
   Data = ConstantInt::get(Type::getInt64Ty(C), data);
   Vals.reserve(values.size());
   Vals.append(values.begin(), values.end());
 }
-AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data) {
+AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data)
+  : Context(C) {
   Data = ConstantDataArray::getString(C, data);
 }
 
@@ -456,10 +472,18 @@ uint64_t AttributeImpl::getAlignment() const {
   return getBitMask() & getAttrMask(Attribute::Alignment);
 }
 
+void AttributeImpl::setAlignment(unsigned Align) {
+  Vals.push_back(ConstantInt::get(Type::getInt64Ty(Context), Align));
+}
+
 uint64_t AttributeImpl::getStackAlignment() const {
   return getBitMask() & getAttrMask(Attribute::StackAlignment);
 }
 
+void AttributeImpl::setStackAlignment(unsigned Align) {
+  Vals.push_back(ConstantInt::get(Type::getInt64Ty(Context), Align));
+}
+
 //===----------------------------------------------------------------------===//
 // AttributeSetImpl Definition
 //===----------------------------------------------------------------------===//
@@ -485,8 +509,7 @@ AttributeSet AttributeSet::get(LLVMContext &C,
   AttributeSetImpl::Profile(ID, Attrs);
 
   void *InsertPoint;
-  AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID,
-                                                                InsertPoint);
+  AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
 
   // If we didn't find any existing attributes of the same shape then
   // create a new one and insert it.
@@ -499,6 +522,23 @@ AttributeSet AttributeSet::get(LLVMContext &C,
   return AttributeSet(PA);
 }
 
+AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) {
+  SmallVector<AttributeWithIndex, 8> Attrs;
+  for (AttrBuilder::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+    Attribute::AttrKind Kind = *I;
+    Attribute A = Attribute::get(C, Kind);
+
+    if (Kind == Attribute::Alignment)
+      A.setAlignment(B.getAlignment());
+    else if (Kind == Attribute::StackAlignment)
+      A.setStackAlignment(B.getStackAlignment());
+
+    Attrs.push_back(AttributeWithIndex::get(Idx, A));
+  }
+
+  return get(C, Attrs);
+}
+
 //===----------------------------------------------------------------------===//
 // AttributeSet Method Implementations
 //===----------------------------------------------------------------------===//