Index: include/algorithm
===================================================================
--- include/algorithm	(revision 212587)
+++ include/algorithm	(working copy)
@@ -4794,47 +4794,6 @@
 
 template <class _Compare, class _RandomAccessIterator>
 void
-__push_heap_front(_RandomAccessIterator __first, _RandomAccessIterator, _Compare __comp,
-                  typename iterator_traits<_RandomAccessIterator>::difference_type __len)
-{
-    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
-    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
-    if (__len > 1)
-    {
-        difference_type __p = 0;
-        _RandomAccessIterator __pp = __first;
-        difference_type __c = 2;
-        _RandomAccessIterator __cp = __first + __c;
-        if (__c == __len || __comp(*__cp, *(__cp - 1)))
-        {
-            --__c;
-            --__cp;
-        }
-        if (__comp(*__pp, *__cp))
-        {
-            value_type __t(_VSTD::move(*__pp));
-            do
-            {
-                *__pp = _VSTD::move(*__cp);
-                __pp = __cp;
-                __p = __c;
-                __c = (__p + 1) * 2;
-                if (__c > __len)
-                    break;
-                __cp = __first + __c;
-                if (__c == __len || __comp(*__cp, *(__cp - 1)))
-                {
-                    --__c;
-                    --__cp;
-                }
-            } while (__comp(__t, *__cp));
-            *__pp = _VSTD::move(__t);
-        }
-    }
-}
-
-template <class _Compare, class _RandomAccessIterator>
-void
 __push_heap_back(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
                  typename iterator_traits<_RandomAccessIterator>::difference_type __len)
 {
@@ -4887,6 +4846,36 @@
 // pop_heap
 
 template <class _Compare, class _RandomAccessIterator>
+void
+__sift_down(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+            typename iterator_traits<_RandomAccessIterator>::difference_type __start)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    // left-child of __start is at 2 * __start + 1
+    // right-child of __start is at 2 * __start + 2
+    difference_type __child = 2 * __start + 1;
+
+    while (__first + __child < __last)
+    {
+        if ((__first + __child + 1) < __last &&
+                __comp(*(__first + __child), *(__first + __child + 1)))
+            // right-child exists and is greater than left-child
+            ++__child;
+
+        // check if we are in heap-order
+        if (__comp(*(__first + __child), *(__first + __start)))
+            // we are, __start is larger than it's largest child
+            break;
+
+        // we are not in heap-order, swap the parent with it's largest child
+        swap(*(__first + __child), *(__first + __start));
+        __start = __child;
+        // recompute the child based off of the updated parent
+        __child = 2 * __start + 1;
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
 inline _LIBCPP_INLINE_VISIBILITY
 void
 __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
@@ -4895,7 +4884,7 @@
     if (__len > 1)
     {
         swap(*__first, *--__last);
-        __push_heap_front<_Compare>(__first, __last, __comp, __len-1);
+        __sift_down<_Compare>(__first, __last, __comp, 0);
     }
 }
 
@@ -4932,14 +4921,15 @@
     difference_type __n = __last - __first;
     if (__n > 1)
     {
-        __last = __first;
-        ++__last;
-        for (difference_type __i = 1; __i < __n;)
-            __push_heap_back<_Compare>(__first, ++__last, __comp, ++__i);
+        // start from the first parent, there is no need to consider children
+        for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start)
+        {
+            __sift_down<_Compare>(__first, __last, __comp, __start);
+        }
     }
 }
 
-template <class _RandomAccessIterator, class _Compare>
+template <class _Compare, class _RandomAccessIterator>
 inline _LIBCPP_INLINE_VISIBILITY
 void
 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
@@ -5004,13 +4994,12 @@
              _Compare __comp)
 {
     __make_heap<_Compare>(__first, __middle, __comp);
-    typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
     for (_RandomAccessIterator __i = __middle; __i != __last; ++__i)
     {
         if (__comp(*__i, *__first))
         {
             swap(*__i, *__first);
-            __push_heap_front<_Compare>(__first, __middle, __comp, __len);
+            __sift_down<_Compare>(__first, __middle, __comp, 0);
         }
     }
     __sort_heap<_Compare>(__first, __middle, __comp);
@@ -5051,15 +5040,14 @@
     _RandomAccessIterator __r = __result_first;
     if (__r != __result_last)
     {
-        typename iterator_traits<_RandomAccessIterator>::difference_type __len = 0;
-        for (; __first != __last && __r != __result_last; ++__first, ++__r, ++__len)
+        for (; __first != __last && __r != __result_last; ++__first, ++__r)
             *__r = *__first;
         __make_heap<_Compare>(__result_first, __r, __comp);
         for (; __first != __last; ++__first)
             if (__comp(*__first, *__result_first))
             {
                 *__result_first = *__first;
-                __push_heap_front<_Compare>(__result_first, __r, __comp, __len);
+                __sift_down<_Compare>(__result_first, __r, __comp, 0);
             }
         __sort_heap<_Compare>(__result_first, __r, __comp);
     }
Index: test/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap.pass.cpp
===================================================================
--- test/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap.pass.cpp	(revision 212587)
+++ test/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap.pass.cpp	(working copy)
@@ -23,8 +23,15 @@
     for (int i = 0; i < N; ++i)
         ia[i] = i;
     std::random_shuffle(ia, ia+N);
-    std::make_heap(ia, ia+N);
+    size_t cmp_count = 0;
+    auto cmp = [&](int x, int y) {
+        ++cmp_count;
+        return x < y;
+    };
+    std::make_heap(ia, ia+N, cmp);
     assert(std::is_heap(ia, ia+N));
+    // Complexity: At most 3 * (last - first) comparisons.
+    assert(cmp_count <= 3 * N);
     delete [] ia;
 }
 
