Index: lib/Analysis/CodeMetrics.cpp
===================================================================
--- lib/Analysis/CodeMetrics.cpp	(revision 169123)
+++ lib/Analysis/CodeMetrics.cpp	(working copy)
@@ -165,6 +165,10 @@
     if (isa<ExtractElementInst>(II) || II->getType()->isVectorTy())
       ++NumVectorInsts;
 
+    if (const CallInst *CI = dyn_cast<CallInst>(II))
+      if (CI->hasFnAttr(Attributes::NoDuplicate))
+        notDuplicatable = true;
+
     ++NumInsts;
   }
 
@@ -185,6 +189,8 @@
   if (isa<IndirectBrInst>(BB->getTerminator()))
     containsIndirectBr = true;
 
+  notDuplicatable |= containsIndirectBr;
+
   // Remember NumInsts for this BB.
   NumBBInsts[BB] = NumInsts - NumInstsBeforeThisBB;
 }
Index: lib/Analysis/InlineCost.cpp
===================================================================
--- lib/Analysis/InlineCost.cpp	(revision 169123)
+++ lib/Analysis/InlineCost.cpp	(working copy)
@@ -54,6 +54,8 @@
   bool IsRecursiveCall;
   bool ExposesReturnsTwice;
   bool HasDynamicAlloca;
+  bool ContainsNoDuplicateCall;
+
   /// Number of bytes allocated statically by the callee.
   uint64_t AllocatedSize;
   unsigned NumInstructions, NumVectorInstructions;
@@ -128,8 +130,8 @@
   CallAnalyzer(const DataLayout *TD, Function &Callee, int Threshold)
     : TD(TD), F(Callee), Threshold(Threshold), Cost(0),
       IsCallerRecursive(false), IsRecursiveCall(false),
-      ExposesReturnsTwice(false), HasDynamicAlloca(false), AllocatedSize(0),
-      NumInstructions(0), NumVectorInstructions(0),
+      ExposesReturnsTwice(false), HasDynamicAlloca(false), ContainsNoDuplicateCall(false),
+      AllocatedSize(0), NumInstructions(0), NumVectorInstructions(0),
       FiftyPercentVectorBonus(0), TenPercentVectorBonus(0), VectorBonus(0),
       NumConstantArgs(0), NumConstantOffsetPtrArgs(0), NumAllocaArgs(0),
       NumConstantPtrCmps(0), NumConstantPtrDiffs(0),
@@ -615,6 +617,9 @@
     ExposesReturnsTwice = true;
     return false;
   }
+  if (CS.isCall() &&
+      cast<CallInst>(CS.getInstruction())->hasFnAttr(Attributes::NoDuplicate))
+	  ContainsNoDuplicateCall = true;
 
   if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) {
     switch (II->getIntrinsicID()) {
@@ -842,7 +847,9 @@
 
   // If there is only one call of the function, and it has internal linkage,
   // the cost of inlining it drops dramatically.
-  if (F.hasLocalLinkage() && F.hasOneUse() && &F == CS.getCalledFunction())
+  bool OnlyOneCallAndLocalLinkage = F.hasLocalLinkage() && F.hasOneUse() &&
+	  &F == CS.getCalledFunction();
+  if (OnlyOneCallAndLocalLinkage)
     Cost += InlineConstants::LastCallToStaticBonus;
 
   // If the instruction after the call, or if the normal destination of the
@@ -1008,6 +1015,12 @@
     }
   }
 
+  // If this is a noduplicate call, we can still inline as long as 
+  // inlining this would cause the removal of the caller (so the instruction
+  // is not actually duplicated, just moved).
+  if (!OnlyOneCallAndLocalLinkage && ContainsNoDuplicateCall)
+	  return false;
+
   Threshold += VectorBonus;
 
   return Cost < Threshold;
@@ -1025,6 +1038,7 @@
   DEBUG_PRINT_STAT(NumInstructionsSimplified);
   DEBUG_PRINT_STAT(SROACostSavings);
   DEBUG_PRINT_STAT(SROACostSavingsLost);
+  DEBUG_PRINT_STAT(ContainsNoDuplicateCall);
 #undef DEBUG_PRINT_STAT
 }
 #endif
Index: lib/Analysis/LoopInfo.cpp
===================================================================
--- lib/Analysis/LoopInfo.cpp	(revision 169123)
+++ lib/Analysis/LoopInfo.cpp	(working copy)
@@ -213,10 +213,17 @@
 /// isSafeToClone - Return true if the loop body is safe to clone in practice.
 /// Routines that reform the loop CFG and split edges often fail on indirectbr.
 bool Loop::isSafeToClone() const {
-  // Return false if any loop blocks contain indirectbrs.
+  // Return false if any loop blocks contain indirectbrs, or there are any calls
+  // to noduplicate functions.
   for (Loop::block_iterator I = block_begin(), E = block_end(); I != E; ++I) {
     if (isa<IndirectBrInst>((*I)->getTerminator()))
       return false;
+    for (BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end(); BI != BE; ++BI) {
+      if (const CallInst *CI = dyn_cast<CallInst>(BI)) {
+        if (CI->hasFnAttr(Attributes::NoDuplicate))
+          return false;
+      }
+    }
   }
   return true;
 }
Index: lib/VMCore/Attributes.cpp
===================================================================
--- lib/VMCore/Attributes.cpp	(revision 169123)
+++ lib/VMCore/Attributes.cpp	(working copy)
@@ -213,6 +213,8 @@
     Result += utostr(getAlignment());
     Result += " ";
   }
+  if (hasAttribute(Attributes::NoDuplicate))
+	  Result += "noduplicate ";
   // Trim the trailing space.
   assert(!Result.empty() && "Unknown attribute!");
   Result.erase(Result.end()-1);
@@ -327,6 +329,7 @@
   case Attributes::NonLazyBind:     return 1U << 31;
   case Attributes::AddressSafety:   return 1ULL << 32;
   case Attributes::MinSize:         return 1ULL << 33;
+  case Attributes::NoDuplicate:     return 1ULL << 34;
   }
   llvm_unreachable("Unsupported attribute type");
 }
Index: lib/AsmParser/LLToken.h
===================================================================
--- lib/AsmParser/LLToken.h	(revision 169123)
+++ lib/AsmParser/LLToken.h	(working copy)
@@ -116,6 +116,7 @@
     kw_nonlazybind,
     kw_address_safety,
     kw_minsize,
+    kw_noduplicate,
 
     kw_type,
     kw_opaque,
Index: lib/AsmParser/LLParser.cpp
===================================================================
--- lib/AsmParser/LLParser.cpp	(revision 169123)
+++ lib/AsmParser/LLParser.cpp	(working copy)
@@ -953,6 +953,7 @@
     case lltok::kw_nonlazybind:     B.addAttribute(Attributes::NonLazyBind); break;
     case lltok::kw_address_safety:  B.addAttribute(Attributes::AddressSafety); break;
     case lltok::kw_minsize:         B.addAttribute(Attributes::MinSize); break;
+    case lltok::kw_noduplicate:     B.addAttribute(Attributes::NoDuplicate); break;
 
     case lltok::kw_alignstack: {
       unsigned Alignment;
@@ -1012,6 +1013,7 @@
     case lltok::kw_returns_twice:
     case lltok::kw_address_safety:
     case lltok::kw_minsize:
+    case lltok::kw_noduplicate:
       if (AttrKind != 2)
         HaveError |= Error(AttrLoc, "invalid use of function-only attribute");
       break;
Index: lib/AsmParser/LLLexer.cpp
===================================================================
--- lib/AsmParser/LLLexer.cpp	(revision 169123)
+++ lib/AsmParser/LLLexer.cpp	(working copy)
@@ -564,6 +564,7 @@
   KEYWORD(nonlazybind);
   KEYWORD(address_safety);
   KEYWORD(minsize);
+  KEYWORD(noduplicate);
 
   KEYWORD(type);
   KEYWORD(opaque);
Index: lib/Transforms/Utils/CloneFunction.cpp
===================================================================
--- lib/Transforms/Utils/CloneFunction.cpp	(revision 169123)
+++ lib/Transforms/Utils/CloneFunction.cpp	(working copy)
@@ -46,6 +46,14 @@
   // Loop over all instructions, and copy them over.
   for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
        II != IE; ++II) {
+    // It is illegal to clone a noduplicate call into the same parent function.
+    // If F is NULL or not BB->getParent(), we can't tell whether this is legal or
+    // not so we won't assert here.
+    if (const CallInst *CI = dyn_cast<CallInst>(II)) {
+      assert((F != BB->getParent() || !CI->hasFnAttr(Attributes::NoDuplicate)) &&
+             "Cannot clone a call marked 'noduplicate' into the same function!");
+    }
+
     Instruction *NewInst = II->clone();
     if (II->hasName())
       NewInst->setName(II->getName()+NameSuffix);
Index: lib/Transforms/Scalar/LoopRotation.cpp
===================================================================
--- lib/Transforms/Scalar/LoopRotation.cpp	(revision 169123)
+++ lib/Transforms/Scalar/LoopRotation.cpp	(working copy)
@@ -274,10 +274,16 @@
   if (OrigLatch == 0 || L->isLoopExiting(OrigLatch))
     return false;
 
-  // Check size of original header and reject loop if it is very big.
+  // Check size of original header and reject loop if it is very big or we can't
+  // duplicate blocks inside it.
   {
-    CodeMetrics Metrics;
+	  CodeMetrics Metrics;
     Metrics.analyzeBasicBlock(OrigHeader);
+    if (Metrics.notDuplicatable) {
+      DEBUG(dbgs() << "LoopRotation: NOT rotating - contains non duplicatable"
+            << " instructions: "; L->dump());
+      return false;
+    }
     if (Metrics.NumInsts > MAX_HEADER_SIZE)
       return false;
   }
Index: lib/Transforms/Scalar/LoopUnrollPass.cpp
===================================================================
--- lib/Transforms/Scalar/LoopUnrollPass.cpp	(revision 169123)
+++ lib/Transforms/Scalar/LoopUnrollPass.cpp	(working copy)
@@ -113,12 +113,13 @@
 
 /// ApproximateLoopSize - Approximate the size of the loop.
 static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls,
-                                    const DataLayout *TD) {
+                                    bool &NotDuplicatable, const DataLayout *TD) {
   CodeMetrics Metrics;
   for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
        I != E; ++I)
     Metrics.analyzeBasicBlock(*I, TD);
   NumCalls = Metrics.NumInlineCandidates;
+  NotDuplicatable = Metrics.notDuplicatable;
 
   unsigned LoopSize = Metrics.NumInsts;
 
@@ -181,8 +182,15 @@
   if (Threshold != NoThreshold) {
     const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
     unsigned NumInlineCandidates;
-    unsigned LoopSize = ApproximateLoopSize(L, NumInlineCandidates, TD);
+    bool notDuplicatable;
+    unsigned LoopSize = ApproximateLoopSize(L, NumInlineCandidates,
+                                            notDuplicatable, TD);
     DEBUG(dbgs() << "  Loop Size = " << LoopSize << "\n");
+    if (notDuplicatable) {
+      DEBUG(dbgs() << "  Not unrolling loop which contains non duplicatable"
+            << " instructions.\n");
+      return false;
+    }
     if (NumInlineCandidates != 0) {
       DEBUG(dbgs() << "  Not unrolling loop with inlinable calls.\n");
       return false;
Index: lib/Transforms/Scalar/LoopUnswitch.cpp
===================================================================
--- lib/Transforms/Scalar/LoopUnswitch.cpp	(revision 169123)
+++ lib/Transforms/Scalar/LoopUnswitch.cpp	(working copy)
@@ -248,6 +248,13 @@
     Props.SizeEstimation = std::min(Metrics.NumInsts, Metrics.NumBlocks * 5);
     Props.CanBeUnswitchedCount = MaxSize / (Props.SizeEstimation);
     MaxSize -= Props.SizeEstimation * Props.CanBeUnswitchedCount;
+
+    if (Metrics.notDuplicatable) {
+      DEBUG(dbgs() << "NOT unswitching loop %"
+            << L->getHeader()->getName() << ", contents cannot be "
+            << "duplicated!\n");
+      return false;
+    }
   }
 
   if (!Props.CanBeUnswitchedCount) {
Index: lib/Transforms/Scalar/JumpThreading.cpp
===================================================================
--- lib/Transforms/Scalar/JumpThreading.cpp	(revision 169123)
+++ lib/Transforms/Scalar/JumpThreading.cpp	(working copy)
@@ -244,7 +244,11 @@
     // as having cost of 2 total, and if they are a vector intrinsic, we model
     // them as having cost 1.
     if (const CallInst *CI = dyn_cast<CallInst>(I)) {
-      if (!isa<IntrinsicInst>(CI))
+      if (CI->hasFnAttr(Attributes::NoDuplicate))
+        // Blocks with NoDuplicate are modelled as having infinite cost, so they
+        // are never duplicated.
+        return ~0U;
+      else if (!isa<IntrinsicInst>(CI))
         Size += 3;
       else if (!CI->getType()->isVectorTy())
         Size += 1;
Index: test/Transforms/LoopUnswitch/noduplicate.ll
===================================================================
--- test/Transforms/LoopUnswitch/noduplicate.ll	(revision 0)
+++ test/Transforms/LoopUnswitch/noduplicate.ll	(revision 0)
@@ -0,0 +1,39 @@
+; RUN: opt -S -loop-unswitch -verify-loop-info < %s 2>&1 | FileCheck %s
+
+; This simple test would normally unswitch, but should be inhibited by the presence of
+; the noduplicate call.
+
+; CHECK: @test
+define i32 @test(i32* %var) {
+  %mem = alloca i32
+  store i32 2, i32* %mem
+  %c = load i32* %mem
+
+  br label %loop_begin
+
+loop_begin:
+
+  %var_val = load i32* %var
+
+  switch i32 %c, label %default [
+      i32 1, label %inc
+      i32 2, label %dec
+  ]
+
+inc:
+  call void @incf() noreturn nounwind
+  br label %loop_begin
+dec:
+; CHECK: call void @decf()
+; CHECK-NOT: call void @decf()
+  call void @decf() noreturn nounwind noduplicate
+  br label %loop_begin
+default:
+  br label %loop_exit
+loop_exit:
+  ret i32 0
+; CHECK: }
+}
+
+declare void @incf() noreturn
+declare void @decf() noreturn
Index: test/Transforms/LoopUnroll/noduplicate.ll
===================================================================
--- test/Transforms/LoopUnroll/noduplicate.ll	(revision 0)
+++ test/Transforms/LoopUnroll/noduplicate.ll	(revision 0)
@@ -0,0 +1,24 @@
+; RUN: opt -S < %s -loop-unroll 2>&1 | FileCheck %s
+
+; This should not unroll since the call is 'noduplicate'.
+
+; CHECK: @test1
+define i32 @test1(i8** %P) nounwind ssp {
+entry:
+  br label %l1
+
+l1:                                               ; preds = %l1, %entry
+  %x.0 = phi i32 [ 0, %entry ], [ %inc, %l1 ]
+; CHECK: call void @f()
+; CHECK-NOT: call void @f()
+  call void @f() noduplicate
+  %inc = add nsw i32 %x.0, 1
+  %exitcond = icmp eq i32 %inc, 3
+  br i1 %exitcond, label %l2, label %l1
+
+l2:                                               ; preds = %l1
+  ret i32 0
+; CHECK: }
+}
+
+declare void @f()
Index: test/Transforms/LoopRotate/noduplicate.ll
===================================================================
--- test/Transforms/LoopRotate/noduplicate.ll	(revision 0)
+++ test/Transforms/LoopRotate/noduplicate.ll	(revision 0)
@@ -0,0 +1,28 @@
+; RUN: opt -S -loop-rotate < %s 2>&1 | FileCheck %s
+
+; CHECK: @test1
+define void @test1() nounwind ssp {
+entry:
+  %array = alloca [20 x i32], align 16
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i32 %i.0, 100
+; CHECK: call void @f
+; CHECK-NOT: call void @f
+  call void @f() noduplicate 
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %inc = add nsw i32 %i.0, 1
+  call void @g()
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+; CHECK: }
+}
+
+declare void @f() noduplicate
+declare void @g()
Index: test/Transforms/JumpThreading/noduplicate.ll
===================================================================
--- test/Transforms/JumpThreading/noduplicate.ll	(revision 0)
+++ test/Transforms/JumpThreading/noduplicate.ll	(revision 0)
@@ -0,0 +1,38 @@
+; RUN: opt -jump-threading -S < %s | FileCheck %s
+
+; In this test we check that block duplication is inhibited by the presence
+; of a function with the 'noduplicate' attribute.
+
+declare void @g()
+declare void @j()
+declare void @k()
+
+; CHECK: define void @h(i32 %p) {
+define void @h(i32 %p) {
+  %x = icmp ult i32 %p, 5
+  br i1 %x, label %l1, label %l2
+
+l1:
+  call void @j()
+  br label %l3
+
+l2:
+  call void @k()
+  br label %l3
+
+l3:
+; CHECK: call void @g() noduplicate
+; CHECK-NOT: call void @g() noduplicate
+  call void @g() noduplicate
+  %y = icmp ult i32 %p, 5
+  br i1 %y, label %l4, label %l5
+
+l4:
+  call void @j()
+  ret void
+
+l5:
+  call void @k()
+  ret void
+; CHECK: }
+}
Index: test/Transforms/Inline/noduplicate.ll
===================================================================
--- test/Transforms/Inline/noduplicate.ll	(revision 0)
+++ test/Transforms/Inline/noduplicate.ll	(revision 0)
@@ -0,0 +1,46 @@
+; RUN: opt < %s -inline -S | FileCheck %s
+
+declare void @barrier() noduplicate
+
+define internal i32 @f() {
+  call void @barrier() noduplicate
+  ret i32 1
+}
+
+define i32 @g() {
+  call void @barrier() noduplicate
+  ret i32 2
+}
+
+define internal i32 @h() {
+  call void @barrier() noduplicate
+  ret i32 3
+}
+
+define i32 @test2() {
+  %b = call i32 @f()
+  ret i32 %b
+}
+
+; The call to @f cannot be inlined as there is another callsite
+; calling @f, and @f contains a noduplicate call.
+;
+; The call to @g cannot be inlined as it has external linkage.
+;
+; The call to @h *can* be inlined.
+
+; CHECK: @test
+define i32 @test() {
+; CHECK: call i32 @f()
+  %a = call i32 @f()
+; CHECK: call i32 @g()
+  %b = call i32 @g()
+; CHECK-NOT: call i32 @h()
+  %c = call i32 @h()
+
+  %d = add i32 %a, %b
+  %e = add i32 %d, %c
+
+  ret i32 %e
+; CHECK: }
+}
Index: include/llvm/Instructions.h
===================================================================
--- include/llvm/Instructions.h	(revision 169123)
+++ include/llvm/Instructions.h	(working copy)
@@ -1325,6 +1325,13 @@
                  Attributes::get(getContext(), Attributes::NoUnwind));
   }
 
+  /// \brief Determine if the call cannot be duplicated.
+  bool cannotDuplicate() const {return hasFnAttr(Attributes::NoDuplicate); }
+  void setCannotDuplicate() {
+    addAttribute(AttrListPtr::FunctionIndex,
+                 Attributes::get(getContext(), Attributes::NoDuplicate));
+  }
+
   /// \brief Determine if the call returns a structure through first
   /// pointer argument.
   bool hasStructRetAttr() const {
Index: include/llvm/Attributes.h
===================================================================
--- include/llvm/Attributes.h	(revision 169123)
+++ include/llvm/Attributes.h	(working copy)
@@ -65,6 +65,7 @@
     Nest,                  ///< Nested function static chain
     NoAlias,               ///< Considered to not alias after call
     NoCapture,             ///< Function creates no aliases of pointer
+    NoDuplicate,           ///< Call cannot be duplicated
     NoImplicitFloat,       ///< Disable implicit floating point insts
     NoInline,              ///< inline=never
     NonLazyBind,           ///< Function is called early and/or
@@ -149,7 +150,8 @@
       hasAttribute(Attributes::NonLazyBind) ||
       hasAttribute(Attributes::ReturnsTwice) ||
       hasAttribute(Attributes::AddressSafety) ||
-      hasAttribute(Attributes::MinSize);
+      hasAttribute(Attributes::MinSize) ||
+      hasAttribute(Attributes::NoDuplicate);
   }
 
   bool operator==(const Attributes &A) const {
@@ -260,7 +262,8 @@
       .removeAttribute(Attributes::NonLazyBind)
       .removeAttribute(Attributes::ReturnsTwice)
       .removeAttribute(Attributes::AddressSafety)
-      .removeAttribute(Attributes::MinSize);
+      .removeAttribute(Attributes::MinSize)
+      .removeAttribute(Attributes::NoDuplicate);
   }
 
   uint64_t Raw() const { return Bits; }
Index: include/llvm/Analysis/CodeMetrics.h
===================================================================
--- include/llvm/Analysis/CodeMetrics.h	(revision 169123)
+++ include/llvm/Analysis/CodeMetrics.h	(working copy)
@@ -46,9 +46,15 @@
     /// \brief True if this function calls itself.
     bool isRecursive;
 
-    /// \brief True if this function contains one or more indirect branches.
+    /// \brief True if this fucntion contains one or more indirect branches.
     bool containsIndirectBr;
 
+    /// \brief True if this function cannot be duplicated.
+    ///
+    /// True if this function contains one or more indirect branches, or it contains
+    /// one or more 'noduplicate' instructions.
+    bool notDuplicatable;
+
     /// \brief True if this function calls alloca (in the C sense).
     bool usesDynamicAlloca;
 
@@ -79,7 +85,8 @@
     unsigned NumRets;
 
     CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
-                    containsIndirectBr(false), usesDynamicAlloca(false),
+                    containsIndirectBr(false), notDuplicatable(false),
+                    usesDynamicAlloca(false),
                     NumInsts(0), NumBlocks(0), NumCalls(0),
                     NumInlineCandidates(0), NumVectorInsts(0),
                     NumRets(0) {}
Index: docs/LangRef.html
===================================================================
--- docs/LangRef.html	(revision 169123)
+++ docs/LangRef.html	(working copy)
@@ -1320,6 +1320,28 @@
       show that no exceptions passes by it. This is normally the case for
       the ELF x86-64 abi, but it can be disabled for some compilation
       units.</dd>
+
+   <dt><tt><b>noduplicate</b></tt></dt>
+   <dd><p>This attribute indicates that calls to the function cannot
+          be duplicated.  A call to a <tt>noduplicate</tt> function
+          may be moved within its parent function, but may not be duplicated
+          within its parent function.</p>
+
+       <p>The <tt>noduplicate</tt> attribute is not transitive. If function A
+         calls B which calls C, and the B -> C call is <tt>noduplicate</tt>, it
+         is legal for the optimizer to duplicate or inline the A -> B
+         call.</p>
+
+       <p>A function containing a <tt>noduplicate</tt> call may still
+         be an inlining candidate, provided that the call is not
+         duplicated by inlining. That implies that the function has
+         internal linkage and only has one call site, so the original
+         call is dead after inlining.</p>
+
+       <p>The noduplicate attribute is intended to model the behaviour
+         of OpenCL's <tt>barrier()</tt> intrinsic.</p>
+   </dd>
+         
 </dl>
 
 </div>
