<commit_before>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "encoded_frame.h"
#include "generic_encoder.h"
#include "jitter_buffer_common.h"
#include "video_coding_defines.h"

namespace webrtc {

VCMEncodedFrame::VCMEncodedFrame()
:
webrtc::EncodedImage(),
_renderTimeMs(-1),
_payloadType(0),
_missingFrame(false),
_codecSpecificInfo(NULL),
_codecSpecificInfoLength(0),
_codec(kVideoCodecUnknown)
{
}

VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs)
:
webrtc::EncodedImage(rhs),
_renderTimeMs(-1),
_payloadType(0),
_missingFrame(false),
_codecSpecificInfo(NULL),
_codecSpecificInfoLength(0),
_codec(kVideoCodecUnknown)
{
    _buffer = NULL;
    _size = NULL;
    _length = NULL;
    if (rhs._buffer != NULL)
    {
        VerifyAndAllocate(rhs._length);
        memcpy(_buffer, rhs._buffer, rhs._length);
    }
}

VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame& rhs)
:
webrtc::EncodedImage(rhs),
_renderTimeMs(rhs._renderTimeMs),
_payloadType(rhs._payloadType),
_missingFrame(rhs._missingFrame),
_codecSpecificInfo(NULL),
_codecSpecificInfoLength(0),
_codec(rhs._codec)
{
    _buffer = NULL;
    _size = NULL;
    _length = NULL;
    if (rhs._buffer != NULL)
    {
        VerifyAndAllocate(rhs._size);
        memcpy(_buffer, rhs._buffer, rhs._length);
    }
}

VCMEncodedFrame::~VCMEncodedFrame()
{
    Free();
}

void VCMEncodedFrame::Free()
{
    Reset();
    if (_buffer != NULL)
    {
        delete [] _buffer;
        _buffer = NULL;
    }
}

void VCMEncodedFrame::Reset()
{
    _renderTimeMs = -1;
    _timeStamp = 0;
    _payloadType = 0;
    _codecSpecificInfo = NULL;
    _codecSpecificInfoLength = 0;
    _frameType = kDeltaFrame;
    _encodedWidth = 0;
    _encodedHeight = 0;
    _completeFrame = false;
    _missingFrame = false;
    _length = 0;
    _codec = kVideoCodecUnknown;
}

WebRtc_Word32
VCMEncodedFrame::Store(VCMFrameStorageCallback& storeCallback) const
{
    EncodedVideoData frameToStore;
    frameToStore.codec = _codec;
    if (_buffer != NULL)
    {
        frameToStore.VerifyAndAllocate(_length);
        memcpy(frameToStore.payloadData, _buffer, _length);
        frameToStore.payloadSize = _length;
    }
    frameToStore.completeFrame = _completeFrame;
    frameToStore.encodedWidth = _encodedWidth;
    frameToStore.encodedHeight = _encodedHeight;
    frameToStore.frameType = ConvertFrameType(_frameType);
    frameToStore.missingFrame = _missingFrame;
    frameToStore.payloadType = _payloadType;
    frameToStore.renderTimeMs = _renderTimeMs;
    frameToStore.timeStamp = _timeStamp;
    storeCallback.StoreReceivedFrame(frameToStore);
    return VCM_OK;
}

WebRtc_Word32
VCMEncodedFrame::VerifyAndAllocate(const WebRtc_UWord32 minimumSize)
{
    if(minimumSize > _size)
    {
        // create buffer of sufficient size
        WebRtc_UWord8* newBuffer = new WebRtc_UWord8[minimumSize];
        if (newBuffer == NULL)
        {
            return -1;
        }
        if(_buffer)
        {
            // copy old data
            memcpy(newBuffer, _buffer, _size);
            delete [] _buffer;
        }
        _buffer = newBuffer;
        _size = minimumSize;
    }
    return 0;
}

webrtc::FrameType VCMEncodedFrame::ConvertFrameType(VideoFrameType frameType)
{
    switch(frameType)
    {
    case kKeyFrame:
        {
            return  kVideoFrameKey;
        }
    case kDeltaFrame:
        {
            return kVideoFrameDelta;
        }
    case kGoldenFrame:
        {
            return kVideoFrameGolden;
        }
    case kAltRefFrame:
        {
            return kVideoFrameAltRef;
        }
    default:
        {
            return kVideoFrameDelta;
        }
    }
}

VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frameType)
{
    switch (frameType)
    {
    case kVideoFrameKey:
        {
            return kKeyFrame;
        }
    case kVideoFrameDelta:
        {
            return kDeltaFrame;
        }
    case kVideoFrameGolden:
        {
            return kGoldenFrame;
        }
    case kVideoFrameAltRef:
        {
            return kAltRefFrame;
        }
    default:
        {
            return kDeltaFrame;
        }
    }
}

}
<commit_msg>Fix "converting to non-pointer type from NULL" warnings. Review URL: http://webrtc-codereview.appspot.com/93005<commit_after>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "encoded_frame.h"
#include "generic_encoder.h"
#include "jitter_buffer_common.h"
#include "video_coding_defines.h"

namespace webrtc {

VCMEncodedFrame::VCMEncodedFrame()
:
webrtc::EncodedImage(),
_renderTimeMs(-1),
_payloadType(0),
_missingFrame(false),
_codecSpecificInfo(NULL),
_codecSpecificInfoLength(0),
_codec(kVideoCodecUnknown)
{
}

VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs)
:
webrtc::EncodedImage(rhs),
_renderTimeMs(-1),
_payloadType(0),
_missingFrame(false),
_codecSpecificInfo(NULL),
_codecSpecificInfoLength(0),
_codec(kVideoCodecUnknown)
{
    _buffer = NULL;
    _size = 0;
    _length = 0;
    if (rhs._buffer != NULL)
    {
        VerifyAndAllocate(rhs._length);
        memcpy(_buffer, rhs._buffer, rhs._length);
    }
}

VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame& rhs)
:
webrtc::EncodedImage(rhs),
_renderTimeMs(rhs._renderTimeMs),
_payloadType(rhs._payloadType),
_missingFrame(rhs._missingFrame),
_codecSpecificInfo(NULL),
_codecSpecificInfoLength(0),
_codec(rhs._codec)
{
    _buffer = NULL;
    _size = 0;
    _length = 0;
    if (rhs._buffer != NULL)
    {
        VerifyAndAllocate(rhs._size);
        memcpy(_buffer, rhs._buffer, rhs._length);
    }
}

VCMEncodedFrame::~VCMEncodedFrame()
{
    Free();
}

void VCMEncodedFrame::Free()
{
    Reset();
    if (_buffer != NULL)
    {
        delete [] _buffer;
        _buffer = NULL;
    }
}

void VCMEncodedFrame::Reset()
{
    _renderTimeMs = -1;
    _timeStamp = 0;
    _payloadType = 0;
    _codecSpecificInfo = NULL;
    _codecSpecificInfoLength = 0;
    _frameType = kDeltaFrame;
    _encodedWidth = 0;
    _encodedHeight = 0;
    _completeFrame = false;
    _missingFrame = false;
    _length = 0;
    _codec = kVideoCodecUnknown;
}

WebRtc_Word32
VCMEncodedFrame::Store(VCMFrameStorageCallback& storeCallback) const
{
    EncodedVideoData frameToStore;
    frameToStore.codec = _codec;
    if (_buffer != NULL)
    {
        frameToStore.VerifyAndAllocate(_length);
        memcpy(frameToStore.payloadData, _buffer, _length);
        frameToStore.payloadSize = _length;
    }
    frameToStore.completeFrame = _completeFrame;
    frameToStore.encodedWidth = _encodedWidth;
    frameToStore.encodedHeight = _encodedHeight;
    frameToStore.frameType = ConvertFrameType(_frameType);
    frameToStore.missingFrame = _missingFrame;
    frameToStore.payloadType = _payloadType;
    frameToStore.renderTimeMs = _renderTimeMs;
    frameToStore.timeStamp = _timeStamp;
    storeCallback.StoreReceivedFrame(frameToStore);
    return VCM_OK;
}

WebRtc_Word32
VCMEncodedFrame::VerifyAndAllocate(const WebRtc_UWord32 minimumSize)
{
    if(minimumSize > _size)
    {
        // create buffer of sufficient size
        WebRtc_UWord8* newBuffer = new WebRtc_UWord8[minimumSize];
        if (newBuffer == NULL)
        {
            return -1;
        }
        if(_buffer)
        {
            // copy old data
            memcpy(newBuffer, _buffer, _size);
            delete [] _buffer;
        }
        _buffer = newBuffer;
        _size = minimumSize;
    }
    return 0;
}

webrtc::FrameType VCMEncodedFrame::ConvertFrameType(VideoFrameType frameType)
{
    switch(frameType)
    {
    case kKeyFrame:
        {
            return  kVideoFrameKey;
        }
    case kDeltaFrame:
        {
            return kVideoFrameDelta;
        }
    case kGoldenFrame:
        {
            return kVideoFrameGolden;
        }
    case kAltRefFrame:
        {
            return kVideoFrameAltRef;
        }
    default:
        {
            return kVideoFrameDelta;
        }
    }
}

VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frameType)
{
    switch (frameType)
    {
    case kVideoFrameKey:
        {
            return kKeyFrame;
        }
    case kVideoFrameDelta:
        {
            return kDeltaFrame;
        }
    case kVideoFrameGolden:
        {
            return kGoldenFrame;
        }
    case kVideoFrameAltRef:
        {
            return kAltRefFrame;
        }
    default:
        {
            return kDeltaFrame;
        }
    }
}

}
<|endoftext|>


<commit_before>#include "Judge.h"
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace WinnerPoker;

std::vector<size_t> test(const std::vector<size_t> &t)
{
    std::stringstream ss;
    ss << "{ ";
    for (auto &&item : t)
    {
        ss << item << ", ";
    }
    ss.seekp(-2, ss.end);
    ss << " }" << std::endl;

    // std::cout << ss.str();

    std::vector<size_t> vector;
    auto                zip = Judge::getInstance().zip(t);
    for (auto &&x : zip)
    {
        for (int i = 1; i <= x.second; ++i)
        {
            vector.push_back((x.first << 8) | i);
        }
    }

    ss.str("");
    ss << "{ ";
    for (auto &&item : vector)
    {
        ss << item << ", ";
    }
    ss.seekp(-2, ss.end);
    ss << " }" << std::endl;

    // std::cout << ss.str();

    return vector;
}

int main()
{
    // std::vector<size_t> hands = { 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7 };
    // std::vector<size_t> hands = { 3, 3, 4, 6, 6, 7, 8, 10, 10, 11, 12, 13, 13, 14, 15 };
    // std::vector<size_t> hands = { 3, 3, 4, 4, 5, 5, 7, 7 };
    // std::vector<size_t> hands = { 3, 4, 5, 5, 5, 5, 7, 7, 8, 9, 10 };

    std::vector<size_t> hands = {
        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 10, 10, 10, 10, 14, 14, 14
    };

    std::vector<size_t> tv = { 4,4,4 };
    Judge::getInstance().setCurrentHandsCategory(test(tv));

    /*
   auto              ret = Judge::getInstance().cardIntentions(test(hands));
   std::stringstream ss;

   for (auto &&item : ret)
   {
       ss.str("");

       ss << "{ ";
       for (auto &&element : item)
       {
           ss << element << ", ";
       }
       ss.seekp(-2, ss.end);
       ss << " }" << std::endl;

       std::cout << ss.str();
   }

   for (auto &&item : ret)
   {
       ss.str("");

       ss << "{ ";
       for (auto &&element : item)
       {
           ss << (element >> 8) << ", ";
       }
       ss.seekp(-2, ss.end);
       ss << " }" << std::endl;

       std::cout << ss.str();
   }
  */

    for (int i = 0; i < 24; ++i)
    {
        const auto &ret = Judge::getInstance().hint(test(hands));

        std::stringstream ss;

        ss.str("");
        ss << "{ ";
        for (auto &&item : ret)
        {
            ss << (item >> 8) << ", ";
        }
        ss.seekp(-2, ss.end);
        ss << " }" << std::endl;

        std::cout << ss.str();
    }

    return 0;
}
<commit_msg>workaround for ant being a pile of fail<commit_after>#include "Judge.h"
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace WinnerPoker;

std::vector<size_t> test(const std::vector<size_t> &t)
{
    std::stringstream ss;
    ss << "{ ";
    for (auto &&item : t)
    {
        ss << item << ", ";
    }
    ss.seekp(-2, ss.end);
    ss << " }" << std::endl;

    // std::cout << ss.str();

    std::vector<size_t> vector;
    auto                zip = Judge::getInstance().zip(t);
    for (auto &&x : zip)
    {
        for (int i = 1; i <= x.second; ++i)
        {
            vector.push_back((x.first << 8) | i);
        }
    }

    ss.str("");
    ss << "{ ";
    for (auto &&item : vector)
    {
        ss << item << ", ";
    }
    ss.seekp(-2, ss.end);
    ss << " }" << std::endl;

    // std::cout << ss.str();

    return vector;
}

int main()
{
    // std::vector<size_t> hands = { 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7 };
    // std::vector<size_t> hands = { 3, 3, 4, 6, 6, 7, 8, 10, 10, 11, 12, 13, 13, 14, 15 };
    // std::vector<size_t> hands = { 3, 3, 4, 4, 5, 5, 7, 7 };
    // std::vector<size_t> hands = { 3, 4, 5, 5, 5, 5, 7, 7, 8, 9, 10 };

    std::vector<size_t> hands = {
            3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 10, 10, 10, 10, 14, 14, 14
    };

    std::vector<size_t> tv = { 4,4,4 };
    Judge::getInstance().setCurrentHandsCategory(test(tv));

    /*
   auto              ret = Judge::getInstance().cardIntentions(test(hands));
   std::stringstream ss;

   for (auto &&item : ret)
   {
       ss.str("");

       ss << "{ ";
       for (auto &&element : item)
       {
           ss << element << ", ";
       }
       ss.seekp(-2, ss.end);
       ss << " }" << std::endl;

       std::cout << ss.str();
   }

   for (auto &&item : ret)
   {
       ss.str("");

       ss << "{ ";
       for (auto &&element : item)
       {
           ss << (element >> 8) << ", ";
       }
       ss.seekp(-2, ss.end);
       ss << " }" << std::endl;

       std::cout << ss.str();
   }
  */

    for (int i = 0; i < 24; ++i)
    {
        const auto &ret = Judge::getInstance().hint(test(hands));

        std::stringstream ss;

        ss.str("");
        ss << "{ ";
        for (auto &&item : ret)
        {
            ss << (item >> 8) << ", ";
        }
        ss.seekp(-2, ss.end);
        ss << " }" << std::endl;

        std::cout << ss.str();
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include "elements.h"

using namespace std;

//open coordinates.csv array

int main()
{
using R_ji (x_j, x_i, y_j, y_i, z_j, z_i)
{
    return ((sqrt((x_i-x_j) pow 2) + (y_i-y_j) pow 2) + (z_i-z_j) pow 2)))
    };

using R_jk (x_k,x_j,y_k,y_j,z_k,z_j)
{
    return ((sqrt((x_j-x_k) pow 2) + (y_j-y_k) pow 2) + (z_j-z_k) pow 2))))
    };

using R_kl (x_l,x_k,y_l,y_k,z_l,z_k)
{
    return ((sqrt((x_k-x_l) pow 2) + (y_k-y_l) pow 2) + (z_k-z_l) pow 2))))
    };

return 0;
}
<commit_msg>delelted #endif which shouldn't have been there<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include "elements.h"

using namespace std;

//open coordinates.csv array

int main()
{
using R_ji (x_j, x_i, y_j, y_i, z_j, z_i)
{
    return ((sqrt((x_i-x_j) pow 2) + (y_i-y_j) pow 2) + (z_i-z_j) pow 2)))
    };

using R_jk (x_k,x_j,y_k,y_j,z_k,z_j)
{
    return ((sqrt((x_j-x_k) pow 2) + (y_j-y_k) pow 2) + (z_j-z_k) pow 2))))
    };

using R_kl (x_l,x_k,y_l,y_k,z_l,z_k)
{
    return ((sqrt((x_k-x_l) pow 2) + (y_k-y_l) pow 2) + (z_k-z_l) pow 2))))
    };

return 0;

<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/path_service.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "net/url_request/url_request_context.h"

// Prerender tests work as follows:
//
// A page with a prefetch link to the test page is loaded.  Once prerendered,
// its Javascript function DidPrerenderPass() is called, which returns true if
// the page behaves as expected when prerendered.
//
// The prerendered page is then displayed on a tab.  The Javascript function
// DidDisplayPass() is called, and returns true if the page behaved as it
// should while being displayed.

namespace {

// PrerenderContents that stops the UI message loop on DidStopLoading().
class TestPrerenderContents : public PrerenderContents {
 public:
  TestPrerenderContents(
      PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
      const std::vector<GURL>& alias_urls)
      : PrerenderContents(prerender_manager, profile, url, alias_urls),
        did_finish_loading_(false) {
  }

  virtual ~TestPrerenderContents() {
    // In the event we are destroyed, say if the prerender was canceled, quit
    // the UI message loop.
    if (!did_finish_loading_)
      MessageLoopForUI::current()->Quit();
  }

  virtual void DidStopLoading() {
    PrerenderContents::DidStopLoading();
    did_finish_loading_ = true;
    MessageLoopForUI::current()->Quit();
  }

  bool did_finish_loading() const { return did_finish_loading_; }

 private:
  bool did_finish_loading_;
};

// PrerenderManager that uses TestPrerenderContents.
class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory {
 public:
  virtual PrerenderContents* CreatePrerenderContents(
      PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
      const std::vector<GURL>& alias_urls) {
    return new TestPrerenderContents(prerender_manager, profile, url,
                                     alias_urls);
  }
};

}  // namespace

class PrerenderBrowserTest : public InProcessBrowserTest {
 public:
  PrerenderBrowserTest() {
    EnableDOMAutomation();
  }

  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kEnablePagePrerender);
#if defined(OS_MACOSX)
    // The plugins directory isn't read by default on the Mac, so it needs to be
    // explicitly registered.
    FilePath app_dir;
    PathService::Get(chrome::DIR_APP, &app_dir);
    command_line->AppendSwitchPath(
        switches::kExtraPluginDir,
        app_dir.Append(FILE_PATH_LITERAL("plugins")));
#endif
  }

  void PrerenderTestURL(const std::string& html_file, bool expect_success) {
    ASSERT_TRUE(test_server()->Start());

    std::string src_path = "files/prerender/prerender_loader.html?";
    src_path.append(html_file);
    std::string dest_path = "files/prerender/";
    dest_path.append(html_file);

    GURL src_url = test_server()->GetURL(src_path);
    dest_url_ = test_server()->GetURL(dest_path);

    Profile* profile = browser()->GetSelectedTabContents()->profile();
    PrerenderManager* prerender_manager = profile->GetPrerenderManager();
    ASSERT_TRUE(prerender_manager);

    // This is needed to exit the event loop once the prerendered page has
    // stopped loading or was cancelled.
    prerender_manager->SetPrerenderContentsFactory(
        new WaitForLoadPrerenderContentsFactory());

    // ui_test_utils::NavigateToURL uses its own observer and message loop.
    // Since the test needs to wait until the prerendered page has stopped
    // loading, rathather than the page directly navigated to, need to
    // handle browser navigation directly.
    browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED);

    ui_test_utils::RunMessageLoop();

    TestPrerenderContents* prerender_contents =
        static_cast<TestPrerenderContents*>(
            prerender_manager->FindEntry(dest_url_));

    if (expect_success) {
      ASSERT_TRUE(prerender_contents != NULL);
      ASSERT_TRUE(prerender_contents->did_finish_loading());

      // Check if page behaves as expected while in prerendered state.
      bool prerender_test_result = false;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
          prerender_contents->render_view_host(), L"",
          L"window.domAutomationController.send(DidPrerenderPass())",
          &prerender_test_result));
      EXPECT_TRUE(prerender_test_result);
    } else {
      // In the failure case, we should have removed dest_url_ from the
      // prerender_manager.
      EXPECT_TRUE(prerender_contents == NULL);
    }
  }

  void NavigateToDestURL() const {
    ui_test_utils::NavigateToURL(browser(), dest_url_);

    Profile* profile = browser()->GetSelectedTabContents()->profile();
    PrerenderManager* prerender_manager = profile->GetPrerenderManager();
    ASSERT_TRUE(prerender_manager);

    // Make sure the PrerenderContents found earlier was used or removed
    EXPECT_TRUE(prerender_manager->FindEntry(dest_url_) == NULL);

    // Check if page behaved as expected when actually displayed.
    bool display_test_result = false;
    ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
        browser()->GetSelectedTabContents()->render_view_host(), L"",
        L"window.domAutomationController.send(DidDisplayPass())",
        &display_test_result));
    EXPECT_TRUE(display_test_result);
  }

 private:
  GURL dest_url_;
};

// Checks that a page is correctly prerendered in the case of a
// <link rel=prefetch> tag and then loaded into a tab in response to a
// navigation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
  PrerenderTestURL("prerender_page.html", true);
  NavigateToDestURL();
}

// Checks that the prerendering of a page is canceled correctly when a
// Javascript alert is called.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
  PrerenderTestURL("prerender_alert_before_onload.html", false);
}

// Checks that the prerendering of a page is canceled correctly when a
// Javascript alert is called.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
  PrerenderTestURL("prerender_alert_after_onload.html", false);
}

// Checks that plugins are not loaded while a page is being preloaded, but
// are loaded when the page is displayed.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDelayLoadPlugin) {
  PrerenderTestURL("plugin_delay_load.html", true);
  NavigateToDestURL();
}

// Renders a page that contains a prerender link to a page that contains an
// iframe with a source that requires http authentication. This should not
// prerender successfully.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) {
  PrerenderTestURL("prerender_http_auth_container.html", false);
}
<commit_msg>Add FinalStatus expectations to PrerenderBrowserTest tests.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/path_service.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "net/url_request/url_request_context.h"

// Prerender tests work as follows:
//
// A page with a prefetch link to the test page is loaded.  Once prerendered,
// its Javascript function DidPrerenderPass() is called, which returns true if
// the page behaves as expected when prerendered.
//
// The prerendered page is then displayed on a tab.  The Javascript function
// DidDisplayPass() is called, and returns true if the page behaved as it
// should while being displayed.

namespace {

// PrerenderContents that stops the UI message loop on DidStopLoading().
class TestPrerenderContents : public PrerenderContents {
 public:
  TestPrerenderContents(
      PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
      const std::vector<GURL>& alias_urls,
      PrerenderContents::FinalStatus expected_final_status)
      : PrerenderContents(prerender_manager, profile, url, alias_urls),
        did_finish_loading_(false),
        expected_final_status_(expected_final_status) {
  }

  virtual ~TestPrerenderContents() {
    EXPECT_EQ(expected_final_status_, final_status());
    // In the event we are destroyed, say if the prerender was canceled, quit
    // the UI message loop.
    if (!did_finish_loading_)
      MessageLoopForUI::current()->Quit();
  }

  virtual void DidStopLoading() {
    PrerenderContents::DidStopLoading();
    did_finish_loading_ = true;
    MessageLoopForUI::current()->Quit();
  }

  bool did_finish_loading() const { return did_finish_loading_; }

 private:
  bool did_finish_loading_;
  PrerenderContents::FinalStatus expected_final_status_;
};

// PrerenderManager that uses TestPrerenderContents.
class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory {
 public:
  explicit WaitForLoadPrerenderContentsFactory(
      PrerenderContents::FinalStatus expected_final_status)
      : expected_final_status_(expected_final_status) {
  }

  virtual PrerenderContents* CreatePrerenderContents(
      PrerenderManager* prerender_manager, Profile* profile, const GURL& url,
      const std::vector<GURL>& alias_urls) {
    return new TestPrerenderContents(prerender_manager, profile, url,
                                     alias_urls, expected_final_status_);
  }

 private:
  PrerenderContents::FinalStatus expected_final_status_;
};

}  // namespace

class PrerenderBrowserTest : public InProcessBrowserTest {
 public:
  PrerenderBrowserTest() {
    EnableDOMAutomation();
  }

  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kEnablePagePrerender);
#if defined(OS_MACOSX)
    // The plugins directory isn't read by default on the Mac, so it needs to be
    // explicitly registered.
    FilePath app_dir;
    PathService::Get(chrome::DIR_APP, &app_dir);
    command_line->AppendSwitchPath(
        switches::kExtraPluginDir,
        app_dir.Append(FILE_PATH_LITERAL("plugins")));
#endif
  }

  void PrerenderTestURL(const std::string& html_file,
                        PrerenderContents::FinalStatus expected_final_status) {
    ASSERT_TRUE(test_server()->Start());

    std::string src_path = "files/prerender/prerender_loader.html?";
    src_path.append(html_file);
    std::string dest_path = "files/prerender/";
    dest_path.append(html_file);

    GURL src_url = test_server()->GetURL(src_path);
    dest_url_ = test_server()->GetURL(dest_path);

    Profile* profile = browser()->GetSelectedTabContents()->profile();
    PrerenderManager* prerender_manager = profile->GetPrerenderManager();
    ASSERT_TRUE(prerender_manager);

    // This is needed to exit the event loop once the prerendered page has
    // stopped loading or was cancelled.
    prerender_manager->SetPrerenderContentsFactory(
        new WaitForLoadPrerenderContentsFactory(expected_final_status));

    // ui_test_utils::NavigateToURL uses its own observer and message loop.
    // Since the test needs to wait until the prerendered page has stopped
    // loading, rathather than the page directly navigated to, need to
    // handle browser navigation directly.
    browser()->OpenURL(src_url, GURL(), CURRENT_TAB, PageTransition::TYPED);

    ui_test_utils::RunMessageLoop();

    TestPrerenderContents* prerender_contents =
        static_cast<TestPrerenderContents*>(
            prerender_manager->FindEntry(dest_url_));

    switch (expected_final_status) {
      case PrerenderContents::FINAL_STATUS_USED: {
        ASSERT_TRUE(prerender_contents != NULL);
        ASSERT_TRUE(prerender_contents->did_finish_loading());

        // Check if page behaves as expected while in prerendered state.
        bool prerender_test_result = false;
        ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
            prerender_contents->render_view_host(), L"",
            L"window.domAutomationController.send(DidPrerenderPass())",
            &prerender_test_result));
        EXPECT_TRUE(prerender_test_result);
        break;
      }
      default:
        // In the failure case, we should have removed dest_url_ from the
        // prerender_manager.
        EXPECT_TRUE(prerender_contents == NULL);
        break;
    }
  }

  void NavigateToDestURL() const {
    ui_test_utils::NavigateToURL(browser(), dest_url_);

    Profile* profile = browser()->GetSelectedTabContents()->profile();
    PrerenderManager* prerender_manager = profile->GetPrerenderManager();
    ASSERT_TRUE(prerender_manager);

    // Make sure the PrerenderContents found earlier was used or removed
    EXPECT_TRUE(prerender_manager->FindEntry(dest_url_) == NULL);

    // Check if page behaved as expected when actually displayed.
    bool display_test_result = false;
    ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
        browser()->GetSelectedTabContents()->render_view_host(), L"",
        L"window.domAutomationController.send(DidDisplayPass())",
        &display_test_result));
    EXPECT_TRUE(display_test_result);
  }

 private:
  GURL dest_url_;
};

// Checks that a page is correctly prerendered in the case of a
// <link rel=prefetch> tag and then loaded into a tab in response to a
// navigation.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
  PrerenderTestURL("prerender_page.html",
                   PrerenderContents::FINAL_STATUS_USED);
  NavigateToDestURL();
}

// Checks that the prerendering of a page is canceled correctly when a
// Javascript alert is called.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
  PrerenderTestURL(
      "prerender_alert_before_onload.html",
      PrerenderContents::FINAL_STATUS_JAVASCRIPT_ALERT);
}

// Checks that the prerendering of a page is canceled correctly when a
// Javascript alert is called.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
  PrerenderTestURL(
      "prerender_alert_after_onload.html",
      PrerenderContents::FINAL_STATUS_JAVASCRIPT_ALERT);
}

// Checks that plugins are not loaded while a page is being preloaded, but
// are loaded when the page is displayed.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDelayLoadPlugin) {
  PrerenderTestURL("plugin_delay_load.html",
                   PrerenderContents::FINAL_STATUS_USED);
  NavigateToDestURL();
}

// Renders a page that contains a prerender link to a page that contains an
// iframe with a source that requires http authentication. This should not
// prerender successfully.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) {
  PrerenderTestURL("prerender_http_auth_container.html",
                   PrerenderContents::FINAL_STATUS_AUTH_NEEDED);
}
<|endoftext|>


<commit_before>//===- ADCE.cpp - Code to perform agressive dead code elimination ---------===//
//
// This file implements "agressive" dead code elimination.  ADCE is DCe where
// values are assumed to be dead until proven otherwise.  This is similar to
// SCCP, except applied to the liveness of values.
//
//===----------------------------------------------------------------------===//

#include "llvm/Optimizations/DCE.h"
#include "llvm/Instruction.h"
#include "llvm/Type.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Support/STLExtras.h"
#include "llvm/Analysis/Writer.h"
#include "llvm/CFG.h"
#include "llvm/iTerminators.h"
#include <set>
#include <algorithm>

//#define DEBUG_ADCE 1

//===----------------------------------------------------------------------===//
// ADCE Class
//
// This class does all of the work of Agressive Dead Code Elimination.
// It's public interface consists of a constructor and a doADCE() method.
//
class ADCE {
  Method *M;                            // The method that we are working on...
  vector<Instruction*>   WorkList;      // Instructions that just became live
  set<Instruction*>      LiveSet;       // The set of live instructions
  bool MadeChanges;

  //===--------------------------------------------------------------------===//
  // The public interface for this class
  //
public:
  // ADCE Ctor - Save the method to operate on...
  inline ADCE(Method *m) : M(m), MadeChanges(false) {}

  // doADCE() - Run the Agressive Dead Code Elimination algorithm, returning
  // true if the method was modified.
  bool doADCE();

  //===--------------------------------------------------------------------===//
  // The implementation of this class
  //
private:
  inline void markInstructionLive(Instruction *I) {
    if (LiveSet.count(I)) return;
#ifdef DEBUG_ADCE
    cerr << "Insn Live: " << I;
#endif
    LiveSet.insert(I);
    WorkList.push_back(I);
  }

  inline void markTerminatorLive(const BasicBlock *BB) {
#ifdef DEBUG_ADCE
    cerr << "Terminat Live: " << BB->getTerminator();
#endif
    markInstructionLive((Instruction*)BB->getTerminator());
  }

  // fixupCFG - Walk the CFG in depth first order, eliminating references to
  // dead blocks.
  //
  BasicBlock *fixupCFG(BasicBlock *Head, set<BasicBlock*> &VisitedBlocks,
		       const set<BasicBlock*> &AliveBlocks);
};

// doADCE() - Run the Agressive Dead Code Elimination algorithm, returning
// true if the method was modified.
//
bool ADCE::doADCE() {
  // Compute the control dependence graph...  Note that this has a side effect
  // on the CFG: a new return bb is added and all returns are merged here.
  //
  cfg::DominanceFrontier CDG(cfg::DominatorSet(M, true));

#ifdef DEBUG_ADCE
  cerr << "Method: " << M;
#endif

  // Iterate over all of the instructions in the method, eliminating trivially
  // dead instructions, and marking instructions live that are known to be
  // needed.  Perform the walk in depth first order so that we avoid marking any
  // instructions live in basic blocks that are unreachable.  These blocks will
  // be eliminated later, along with the instructions inside.
  //
  for (cfg::df_iterator BBI = cfg::df_begin(M), BBE = cfg::df_end(M);
       BBI != BBE; ++BBI) {
    BasicBlock *BB = *BBI;
    for (BasicBlock::iterator II = BB->begin(), EI = BB->end(); II != EI; ) {
      Instruction *I = *II;

      if (I->hasSideEffects() || I->getOpcode() == Instruction::Ret) {
	markInstructionLive(I);
      } else {
	// Check to see if anything is trivially dead
	if (I->use_size() == 0 && I->getType() != Type::VoidTy) {
	  // Remove the instruction from it's basic block...
	  delete BB->getInstList().remove(II);
	  MadeChanges = true;
	  continue;  // Don't increment the iterator past the current slot
	}
      }

      ++II;  // Increment the inst iterator if the inst wasn't deleted
    }
  }

#ifdef DEBUG_ADCE
  cerr << "Processing work list\n";
#endif

  // AliveBlocks - Set of basic blocks that we know have instructions that are
  // alive in them...
  //
  set<BasicBlock*> AliveBlocks;

  // Process the work list of instructions that just became live... if they
  // became live, then that means that all of their operands are neccesary as
  // well... make them live as well.
  //
  while (!WorkList.empty()) {
    Instruction *I = WorkList.back(); // Get an instruction that became live...
    WorkList.pop_back();

    BasicBlock *BB = I->getParent();
    if (AliveBlocks.count(BB) == 0) {   // Basic block not alive yet...
      // Mark the basic block as being newly ALIVE... and mark all branches that
      // this block is control dependant on as being alive also...
      //
      AliveBlocks.insert(BB);   // Block is now ALIVE!
      cfg::DominanceFrontier::const_iterator It = CDG.find(BB);
      if (It != CDG.end()) {
	// Get the blocks that this node is control dependant on...
	const cfg::DominanceFrontier::DomSetType &CDB = It->second;
	for_each(CDB.begin(), CDB.end(),   // Mark all their terminators as live
		 bind_obj(this, &ADCE::markTerminatorLive));
      }

      // If this basic block is live, then the terminator must be as well!
      markTerminatorLive(BB);
    }

    // Loop over all of the operands of the live instruction, making sure that
    // they are known to be alive as well...
    //
    for (unsigned op = 0, End = I->getNumOperands(); op != End; ++op) {
      if (Instruction *Operand = I->getOperand(op)->castInstruction())
	markInstructionLive(Operand);
    }
  }

#ifdef DEBUG_ADCE
  cerr << "Current Method: X = Live\n";
  for (Method::inst_iterator IL = M->inst_begin(); IL != M->inst_end(); ++IL) {
    if (LiveSet.count(*IL)) cerr << "X ";
    cerr << *IL;
  }
#endif

  // After the worklist is processed, recursively walk the CFG in depth first
  // order, patching up references to dead blocks...
  //
  set<BasicBlock*> VisitedBlocks;
  BasicBlock *EntryBlock = fixupCFG(M->front(), VisitedBlocks, AliveBlocks);
  if (EntryBlock && EntryBlock != M->front()) {
    if (EntryBlock->front()->isPHINode()) {
      // Cannot make the first block be a block with a PHI node in it! Instead,
      // strip the first basic block of the method to contain no instructions,
      // then add a simple branch to the "real" entry node...
      //
      BasicBlock *E = M->front();
      if (!E->front()->isTerminator() ||   // Check for an actual change...
	  ((TerminatorInst*)E->front())->getNumSuccessors() != 1 ||
	  ((TerminatorInst*)E->front())->getSuccessor(0) != EntryBlock) {
	E->getInstList().delete_all();      // Delete all instructions in block
	E->getInstList().push_back(new BranchInst(EntryBlock));
	MadeChanges = true;
      }
      AliveBlocks.insert(E);
    } else {
      // We need to move the new entry block to be the first bb of the method.
      Method::iterator EBI = find(M->begin(), M->end(), EntryBlock);
      swap(*EBI, *M->begin());  // Exchange old location with start of method
      MadeChanges = true;
    }
  }

  // Now go through and tell dead blocks to drop all of their references so they
  // can be safely deleted.
  //
  for (Method::iterator BI = M->begin(), BE = M->end(); BI != BE; ++BI) {
    BasicBlock *BB = *BI;
    if (!AliveBlocks.count(BB)) {
      BB->dropAllReferences();
    }
  }

  // Now loop through all of the blocks and delete them.  We can safely do this
  // now because we know that there are no references to dead blocks (because
  // they have dropped all of their references...
  //
  for (Method::iterator BI = M->begin(); BI != M->end();) {
    if (!AliveBlocks.count(*BI)) {
      delete M->getBasicBlocks().remove(BI);
      MadeChanges = true;
      continue;                                     // Don't increment iterator
    }
    ++BI;                                           // Increment iterator...
  }

  return MadeChanges;
}

// fixupCFG - Walk the CFG in depth first order, eliminating references to
// dead blocks:
//  If the BB is alive (in AliveBlocks):
//   1. Eliminate all dead instructions in the BB
//   2. Recursively traverse all of the successors of the BB:
//      - If the returned successor is non-null, update our terminator to
//         reference the returned BB
//   3. Return 0 (no update needed)
//
//  If the BB is dead (not in AliveBlocks):
//   1. Add the BB to the dead set
//   2. Recursively traverse all of the successors of the block:
//      - Only one shall return a nonnull value (or else this block should have
//        been in the alive set).
//   3. Return the nonnull child, or 0 if no non-null children.
//
BasicBlock *ADCE::fixupCFG(BasicBlock *BB, set<BasicBlock*> &VisitedBlocks,
			   const set<BasicBlock*> &AliveBlocks) {
  if (VisitedBlocks.count(BB)) return 0;   // Revisiting a node? No update.
  VisitedBlocks.insert(BB);                // We have now visited this node!

#ifdef DEBUG_ADCE
  cerr << "Fixing up BB: " << BB;
#endif

  if (AliveBlocks.count(BB)) {             // Is the block alive?
    // Yes it's alive: loop through and eliminate all dead instructions in block
    for (BasicBlock::iterator II = BB->begin(); II != BB->end()-1; ) {
      Instruction *I = *II;
      if (!LiveSet.count(I)) {             // Is this instruction alive?
	// Nope... remove the instruction from it's basic block...
	delete BB->getInstList().remove(II);
	MadeChanges = true;
	continue;                          // Don't increment II
      }
      ++II;
    }

    // Recursively traverse successors of this basic block.
    cfg::succ_iterator SI = cfg::succ_begin(BB), SE = cfg::succ_end(BB);
    for (; SI != SE; ++SI) {
      BasicBlock *Succ = *SI;
      BasicBlock *Repl = fixupCFG(Succ, VisitedBlocks, AliveBlocks);
      if (Repl && Repl != Succ) {          // We have to replace the successor
	Succ->replaceAllUsesWith(Repl);
	MadeChanges = true;
      }
    }
    return BB;
  } else {                                 // Otherwise the block is dead...
    BasicBlock *ReturnBB = 0;              // Default to nothing live down here

    // Recursively traverse successors of this basic block.
    cfg::succ_iterator SI = cfg::succ_begin(BB), SE = cfg::succ_end(BB);
    for (; SI != SE; ++SI) {
      BasicBlock *RetBB = fixupCFG(*SI, VisitedBlocks, AliveBlocks);
      if (RetBB) {
	assert(ReturnBB == 0 && "One one live child allowed!");
	ReturnBB = RetBB;
      }
    }
    return ReturnBB;                       // Return the result of traversal
  }
}

// DoADCE - Execute the Agressive Dead Code Elimination Algorithm
//
bool opt::DoADCE(Method *M) {
  if (M->isExternal()) return false;
  ADCE DCE(M);
  return DCE.doADCE();
}
<commit_msg>ADCE is broken but at least we know why<commit_after>//===- ADCE.cpp - Code to perform agressive dead code elimination ---------===//
//
// This file implements "agressive" dead code elimination.  ADCE is DCe where
// values are assumed to be dead until proven otherwise.  This is similar to
// SCCP, except applied to the liveness of values.
//
//===----------------------------------------------------------------------===//

#include "llvm/Optimizations/DCE.h"
#include "llvm/Instruction.h"
#include "llvm/Type.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Support/STLExtras.h"
#include "llvm/Analysis/Writer.h"
#include "llvm/CFG.h"
#include "llvm/iTerminators.h"
#include <set>
#include <algorithm>

#define DEBUG_ADCE 1

//===----------------------------------------------------------------------===//
// ADCE Class
//
// This class does all of the work of Agressive Dead Code Elimination.
// It's public interface consists of a constructor and a doADCE() method.
//
class ADCE {
  Method *M;                            // The method that we are working on...
  vector<Instruction*>   WorkList;      // Instructions that just became live
  set<Instruction*>      LiveSet;       // The set of live instructions
  bool MadeChanges;

  //===--------------------------------------------------------------------===//
  // The public interface for this class
  //
public:
  // ADCE Ctor - Save the method to operate on...
  inline ADCE(Method *m) : M(m), MadeChanges(false) {}

  // doADCE() - Run the Agressive Dead Code Elimination algorithm, returning
  // true if the method was modified.
  bool doADCE();

  //===--------------------------------------------------------------------===//
  // The implementation of this class
  //
private:
  inline void markInstructionLive(Instruction *I) {
    if (LiveSet.count(I)) return;
#ifdef DEBUG_ADCE
    cerr << "Insn Live: " << I;
#endif
    LiveSet.insert(I);
    WorkList.push_back(I);
  }

  inline void markTerminatorLive(const BasicBlock *BB) {
#ifdef DEBUG_ADCE
    cerr << "Terminat Live: " << BB->getTerminator();
#endif
    markInstructionLive((Instruction*)BB->getTerminator());
  }

  // fixupCFG - Walk the CFG in depth first order, eliminating references to
  // dead blocks.
  //
  BasicBlock *fixupCFG(BasicBlock *Head, set<BasicBlock*> &VisitedBlocks,
		       const set<BasicBlock*> &AliveBlocks);
};

// doADCE() - Run the Agressive Dead Code Elimination algorithm, returning
// true if the method was modified.
//
bool ADCE::doADCE() {
  // Compute the control dependence graph...  Note that this has a side effect
  // on the CFG: a new return bb is added and all returns are merged here.
  //
  cfg::DominanceFrontier CDG(cfg::DominatorSet(M, true));

#ifdef DEBUG_ADCE
  cerr << "Method: " << M;
#endif

  // Iterate over all of the instructions in the method, eliminating trivially
  // dead instructions, and marking instructions live that are known to be
  // needed.  Perform the walk in depth first order so that we avoid marking any
  // instructions live in basic blocks that are unreachable.  These blocks will
  // be eliminated later, along with the instructions inside.
  //
  for (cfg::df_iterator BBI = cfg::df_begin(M), BBE = cfg::df_end(M);
       BBI != BBE; ++BBI) {
    BasicBlock *BB = *BBI;
    for (BasicBlock::iterator II = BB->begin(), EI = BB->end(); II != EI; ) {
      Instruction *I = *II;

      if (I->hasSideEffects() || I->getOpcode() == Instruction::Ret) {
	markInstructionLive(I);
      } else {
	// Check to see if anything is trivially dead
	if (I->use_size() == 0 && I->getType() != Type::VoidTy) {
	  // Remove the instruction from it's basic block...
	  delete BB->getInstList().remove(II);
	  MadeChanges = true;
	  continue;  // Don't increment the iterator past the current slot
	}
      }

      ++II;  // Increment the inst iterator if the inst wasn't deleted
    }
  }

#ifdef DEBUG_ADCE
  cerr << "Processing work list\n";
#endif

  // AliveBlocks - Set of basic blocks that we know have instructions that are
  // alive in them...
  //
  set<BasicBlock*> AliveBlocks;

  // Process the work list of instructions that just became live... if they
  // became live, then that means that all of their operands are neccesary as
  // well... make them live as well.
  //
  while (!WorkList.empty()) {
    Instruction *I = WorkList.back(); // Get an instruction that became live...
    WorkList.pop_back();

    BasicBlock *BB = I->getParent();
    if (AliveBlocks.count(BB) == 0) {   // Basic block not alive yet...
      // Mark the basic block as being newly ALIVE... and mark all branches that
      // this block is control dependant on as being alive also...
      //
      AliveBlocks.insert(BB);   // Block is now ALIVE!
      cfg::DominanceFrontier::const_iterator It = CDG.find(BB);
      if (It != CDG.end()) {
	// Get the blocks that this node is control dependant on...
	const cfg::DominanceFrontier::DomSetType &CDB = It->second;
	for_each(CDB.begin(), CDB.end(),   // Mark all their terminators as live
		 bind_obj(this, &ADCE::markTerminatorLive));
      }

      // If this basic block is live, then the terminator must be as well!
      markTerminatorLive(BB);
    }

    // Loop over all of the operands of the live instruction, making sure that
    // they are known to be alive as well...
    //
    for (unsigned op = 0, End = I->getNumOperands(); op != End; ++op) {
      if (Instruction *Operand = I->getOperand(op)->castInstruction())
	markInstructionLive(Operand);
    }
  }

#ifdef DEBUG_ADCE
  cerr << "Current Method: X = Live\n";
  for (Method::inst_iterator IL = M->inst_begin(); IL != M->inst_end(); ++IL) {
    if (LiveSet.count(*IL)) cerr << "X ";
    cerr << *IL;
  }
#endif

  // After the worklist is processed, recursively walk the CFG in depth first
  // order, patching up references to dead blocks...
  //
  set<BasicBlock*> VisitedBlocks;
  BasicBlock *EntryBlock = fixupCFG(M->front(), VisitedBlocks, AliveBlocks);
  if (EntryBlock && EntryBlock != M->front()) {
    if (EntryBlock->front()->isPHINode()) {
      // Cannot make the first block be a block with a PHI node in it! Instead,
      // strip the first basic block of the method to contain no instructions,
      // then add a simple branch to the "real" entry node...
      //
      BasicBlock *E = M->front();
      if (!E->front()->isTerminator() ||   // Check for an actual change...
	  ((TerminatorInst*)E->front())->getNumSuccessors() != 1 ||
	  ((TerminatorInst*)E->front())->getSuccessor(0) != EntryBlock) {
	E->getInstList().delete_all();      // Delete all instructions in block
	E->getInstList().push_back(new BranchInst(EntryBlock));
	MadeChanges = true;
      }
      AliveBlocks.insert(E);

      // Next we need to change any PHI nodes in the entry block to refer to the
      // new predecessor node...

    } else {
      // We need to move the new entry block to be the first bb of the method.
      Method::iterator EBI = find(M->begin(), M->end(), EntryBlock);
      swap(*EBI, *M->begin());  // Exchange old location with start of method
      MadeChanges = true;
    }
  }

  // Now go through and tell dead blocks to drop all of their references so they
  // can be safely deleted.
  //
  for (Method::iterator BI = M->begin(), BE = M->end(); BI != BE; ++BI) {
    BasicBlock *BB = *BI;
    if (!AliveBlocks.count(BB)) {
      BB->dropAllReferences();
    }
  }

  // Now loop through all of the blocks and delete them.  We can safely do this
  // now because we know that there are no references to dead blocks (because
  // they have dropped all of their references...
  //
  for (Method::iterator BI = M->begin(); BI != M->end();) {
    if (!AliveBlocks.count(*BI)) {
      delete M->getBasicBlocks().remove(BI);
      MadeChanges = true;
      continue;                                     // Don't increment iterator
    }
    ++BI;                                           // Increment iterator...
  }

  return MadeChanges;
}

// fixupCFG - Walk the CFG in depth first order, eliminating references to
// dead blocks:
//  If the BB is alive (in AliveBlocks):
//   1. Eliminate all dead instructions in the BB
//   2. Recursively traverse all of the successors of the BB:
//      - If the returned successor is non-null, update our terminator to
//         reference the returned BB
//   3. Return 0 (no update needed)
//
//  If the BB is dead (not in AliveBlocks):
//   1. Add the BB to the dead set
//   2. Recursively traverse all of the successors of the block:
//      - Only one shall return a nonnull value (or else this block should have
//        been in the alive set).
//   3. Return the nonnull child, or 0 if no non-null children.
//
BasicBlock *ADCE::fixupCFG(BasicBlock *BB, set<BasicBlock*> &VisitedBlocks,
			   const set<BasicBlock*> &AliveBlocks) {
  if (VisitedBlocks.count(BB)) return 0;   // Revisiting a node? No update.
  VisitedBlocks.insert(BB);                // We have now visited this node!

#ifdef DEBUG_ADCE
  cerr << "Fixing up BB: " << BB;
#endif

  if (AliveBlocks.count(BB)) {             // Is the block alive?
    // Yes it's alive: loop through and eliminate all dead instructions in block
    for (BasicBlock::iterator II = BB->begin(); II != BB->end()-1; ) {
      Instruction *I = *II;
      if (!LiveSet.count(I)) {             // Is this instruction alive?
	// Nope... remove the instruction from it's basic block...
	delete BB->getInstList().remove(II);
	MadeChanges = true;
	continue;                          // Don't increment II
      }
      ++II;
    }

    // Recursively traverse successors of this basic block.
    cfg::succ_iterator SI = cfg::succ_begin(BB), SE = cfg::succ_end(BB);
    for (; SI != SE; ++SI) {
      BasicBlock *Succ = *SI;
      BasicBlock *Repl = fixupCFG(Succ, VisitedBlocks, AliveBlocks);
      if (Repl && Repl != Succ) {          // We have to replace the successor
	Succ->replaceAllUsesWith(Repl);
	MadeChanges = true;
      }
    }
    return BB;
  } else {                                 // Otherwise the block is dead...
    BasicBlock *ReturnBB = 0;              // Default to nothing live down here

    // Recursively traverse successors of this basic block.
    cfg::succ_iterator SI = cfg::succ_begin(BB), SE = cfg::succ_end(BB);
    for (; SI != SE; ++SI) {
      BasicBlock *RetBB = fixupCFG(*SI, VisitedBlocks, AliveBlocks);
      if (RetBB) {
	assert(ReturnBB == 0 && "One one live child allowed!");
	ReturnBB = RetBB;
      }
    }
    return ReturnBB;                       // Return the result of traversal
  }
}

// DoADCE - Execute the Agressive Dead Code Elimination Algorithm
//
bool opt::DoADCE(Method *M) {
  if (M->isExternal()) return false;
  ADCE DCE(M);
  return DCE.doADCE();
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/prerender/prerender_field_trial.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/common/chrome_switches.h"

namespace prerender {

void ConfigurePrefetchAndPrerender(const CommandLine& command_line) {
  enum PrerenderOption {
    PRERENDER_OPTION_AUTO,
    PRERENDER_OPTION_DISABLED,
    PRERENDER_OPTION_ENABLED,
    PRERENDER_OPTION_PREFETCH_ONLY,
  };

  PrerenderOption prerender_option = PRERENDER_OPTION_AUTO;
  if (command_line.HasSwitch(switches::kPrerender)) {
    const std::string switch_value =
        command_line.GetSwitchValueASCII(switches::kPrerender);

    if (switch_value == switches::kPrerenderSwitchValueAuto) {
#if defined(OS_CHROMEOS)
      // Prerender is temporarily disabled on CrOS.
      // http://crosbug.com/12483
      prerender_option = PRERENDER_OPTION_DISABLED;
#else
      prerender_option = PRERENDER_OPTION_AUTO;
#endif
    } else if (switch_value == switches::kPrerenderSwitchValueDisabled) {
      prerender_option = PRERENDER_OPTION_DISABLED;
    } else if (switch_value.empty() ||
               switch_value == switches::kPrerenderSwitchValueEnabled) {
      // The empty string means the option was provided with no value, and that
      // means enable.
      prerender_option = PRERENDER_OPTION_ENABLED;
    } else if (switch_value == switches::kPrerenderSwitchValuePrefetchOnly) {
      prerender_option = PRERENDER_OPTION_PREFETCH_ONLY;
    } else {
      prerender_option = PRERENDER_OPTION_DISABLED;
      LOG(ERROR) << "Invalid --prerender option received on command line: "
                 << switch_value;
      LOG(ERROR) << "Disabling prerendering!";
    }
  }

  switch (prerender_option) {
    case PRERENDER_OPTION_AUTO: {
      const base::FieldTrial::Probability kPrefetchDivisor = 1000;
      const base::FieldTrial::Probability kYesPrefetchProbability = 0;
      const base::FieldTrial::Probability kPrerenderExperimentProbability = 50;
      const base::FieldTrial::Probability kPrerenderControlProbability = 50;

      scoped_refptr<base::FieldTrial> trial(
          new base::FieldTrial("Prefetch", kPrefetchDivisor,
                               "ContentPrefetchDisabled", 2011, 6, 30));

      const int kNoPrefetchGroup = trial->kDefaultGroupNumber;
      const int kYesPrefetchGroup =
          trial->AppendGroup("ContentPrefetchEnabled", kYesPrefetchProbability);
      const int kPrerenderExperimentGroup =
          trial->AppendGroup("ContentPrefetchPrerender",
                             kPrerenderExperimentProbability);
      const int kPrerenderControlGroup =
          trial->AppendGroup("ContentPrefetchPrerenderControl",
                             kPrerenderControlProbability);
      const int trial_group = trial->group();
      if (trial_group == kYesPrefetchGroup) {
        ResourceDispatcherHost::set_is_prefetch_enabled(true);
        PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      } else if (trial_group == kNoPrefetchGroup) {
        ResourceDispatcherHost::set_is_prefetch_enabled(false);
        PrerenderManager::SetMode(
            PrerenderManager::PRERENDER_MODE_DISABLED);
      } else if (trial_group == kPrerenderExperimentGroup) {
        ResourceDispatcherHost::set_is_prefetch_enabled(true);
        PrerenderManager::SetMode(
            PrerenderManager::PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP);
      } else if (trial_group == kPrerenderControlGroup) {
        ResourceDispatcherHost::set_is_prefetch_enabled(false);
        PrerenderManager::SetMode(
            PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
      } else {
        NOTREACHED();
      }
      break;
    }
    case PRERENDER_OPTION_DISABLED:
      ResourceDispatcherHost::set_is_prefetch_enabled(false);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    case PRERENDER_OPTION_ENABLED:
      ResourceDispatcherHost::set_is_prefetch_enabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_ENABLED);
      break;
    case PRERENDER_OPTION_PREFETCH_ONLY:
      ResourceDispatcherHost::set_is_prefetch_enabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    default:
      NOTREACHED();
  }

  UMA_HISTOGRAM_ENUMERATION("Prerender.Sessions",
                            PrerenderManager::GetMode(),
                            PrerenderManager::PRERENDER_MODE_MAX);
}

}  // namespace prerender
<commit_msg>Update prerender field trial in canary from 5% control & 5% experiment to 30% control & 30% experiment<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/prerender/prerender_field_trial.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/common/chrome_switches.h"

namespace prerender {

void ConfigurePrefetchAndPrerender(const CommandLine& command_line) {
  enum PrerenderOption {
    PRERENDER_OPTION_AUTO,
    PRERENDER_OPTION_DISABLED,
    PRERENDER_OPTION_ENABLED,
    PRERENDER_OPTION_PREFETCH_ONLY,
  };

  PrerenderOption prerender_option = PRERENDER_OPTION_AUTO;
  if (command_line.HasSwitch(switches::kPrerender)) {
    const std::string switch_value =
        command_line.GetSwitchValueASCII(switches::kPrerender);

    if (switch_value == switches::kPrerenderSwitchValueAuto) {
#if defined(OS_CHROMEOS)
      // Prerender is temporarily disabled on CrOS.
      // http://crosbug.com/12483
      prerender_option = PRERENDER_OPTION_DISABLED;
#else
      prerender_option = PRERENDER_OPTION_AUTO;
#endif
    } else if (switch_value == switches::kPrerenderSwitchValueDisabled) {
      prerender_option = PRERENDER_OPTION_DISABLED;
    } else if (switch_value.empty() ||
               switch_value == switches::kPrerenderSwitchValueEnabled) {
      // The empty string means the option was provided with no value, and that
      // means enable.
      prerender_option = PRERENDER_OPTION_ENABLED;
    } else if (switch_value == switches::kPrerenderSwitchValuePrefetchOnly) {
      prerender_option = PRERENDER_OPTION_PREFETCH_ONLY;
    } else {
      prerender_option = PRERENDER_OPTION_DISABLED;
      LOG(ERROR) << "Invalid --prerender option received on command line: "
                 << switch_value;
      LOG(ERROR) << "Disabling prerendering!";
    }
  }

  switch (prerender_option) {
    case PRERENDER_OPTION_AUTO: {
      const base::FieldTrial::Probability kPrefetchDivisor = 1000;
      const base::FieldTrial::Probability kYesPrefetchProbability = 0;
      const base::FieldTrial::Probability kPrerenderExperimentProbability = 300;
      const base::FieldTrial::Probability kPrerenderControlProbability = 300;

      scoped_refptr<base::FieldTrial> trial(
          new base::FieldTrial("Prefetch", kPrefetchDivisor,
                               "ContentPrefetchDisabled", 2011, 6, 30));

      const int kNoPrefetchGroup = trial->kDefaultGroupNumber;
      const int kYesPrefetchGroup =
          trial->AppendGroup("ContentPrefetchEnabled", kYesPrefetchProbability);
      const int kPrerenderExperimentGroup =
          trial->AppendGroup("ContentPrefetchPrerender",
                             kPrerenderExperimentProbability);
      const int kPrerenderControlGroup =
          trial->AppendGroup("ContentPrefetchPrerenderControl",
                             kPrerenderControlProbability);
      const int trial_group = trial->group();
      if (trial_group == kYesPrefetchGroup) {
        ResourceDispatcherHost::set_is_prefetch_enabled(true);
        PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      } else if (trial_group == kNoPrefetchGroup) {
        ResourceDispatcherHost::set_is_prefetch_enabled(false);
        PrerenderManager::SetMode(
            PrerenderManager::PRERENDER_MODE_DISABLED);
      } else if (trial_group == kPrerenderExperimentGroup) {
        ResourceDispatcherHost::set_is_prefetch_enabled(true);
        PrerenderManager::SetMode(
            PrerenderManager::PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP);
      } else if (trial_group == kPrerenderControlGroup) {
        ResourceDispatcherHost::set_is_prefetch_enabled(false);
        PrerenderManager::SetMode(
            PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
      } else {
        NOTREACHED();
      }
      break;
    }
    case PRERENDER_OPTION_DISABLED:
      ResourceDispatcherHost::set_is_prefetch_enabled(false);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    case PRERENDER_OPTION_ENABLED:
      ResourceDispatcherHost::set_is_prefetch_enabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_ENABLED);
      break;
    case PRERENDER_OPTION_PREFETCH_ONLY:
      ResourceDispatcherHost::set_is_prefetch_enabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    default:
      NOTREACHED();
  }

  UMA_HISTOGRAM_ENUMERATION("Prerender.Sessions",
                            PrerenderManager::GetMode(),
                            PrerenderManager::PRERENDER_MODE_MAX);
}

}  // namespace prerender
<|endoftext|>


<commit_before>//===- ADCE.cpp - Code to perform aggressive dead code elimination --------===//
//
// This file implements "aggressive" dead code elimination.  ADCE is DCe where
// values are assumed to be dead until proven otherwise.  This is similar to
// SCCP, except applied to the liveness of values.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Type.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/Constant.h"
#include "llvm/Support/CFG.h"
#include "Support/STLExtras.h"
#include "Support/DepthFirstIterator.h"
#include "Support/StatisticReporter.h"
#include <algorithm>
#include <iostream>
using std::cerr;
using std::vector;

static Statistic<> NumBlockRemoved("adce\t\t- Number of basic blocks removed");
static Statistic<> NumInstRemoved ("adce\t\t- Number of instructions removed");

namespace {

//===----------------------------------------------------------------------===//
// ADCE Class
//
// This class does all of the work of Aggressive Dead Code Elimination.
// It's public interface consists of a constructor and a doADCE() method.
//
class ADCE : public FunctionPass {
  Function *Func;                       // The function that we are working on
  std::vector<Instruction*> WorkList;   // Instructions that just became live
  std::set<Instruction*>    LiveSet;    // The set of live instructions

  //===--------------------------------------------------------------------===//
  // The public interface for this class
  //
public:
  // Execute the Aggressive Dead Code Elimination Algorithm
  //
  virtual bool runOnFunction(Function &F) {
    Func = &F;
    bool Changed = doADCE();
    assert(WorkList.empty());
    LiveSet.clear();
    return Changed;
  }
  // getAnalysisUsage - We require post dominance frontiers (aka Control
  // Dependence Graph)
  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    AU.addRequired<PostDominatorTree>();
    AU.addRequired<PostDominanceFrontier>();
  }

  //===--------------------------------------------------------------------===//
  // The implementation of this class
  //
private:
  // doADCE() - Run the Aggressive Dead Code Elimination algorithm, returning
  // true if the function was modified.
  //
  bool doADCE();

  void markBlockAlive(BasicBlock *BB);

  // dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the
  // instructions in the specified basic block, dropping references on
  // instructions that are dead according to LiveSet.
  bool dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB);

  inline void markInstructionLive(Instruction *I) {
    if (LiveSet.count(I)) return;
    DEBUG(cerr << "Insn Live: " << I);
    LiveSet.insert(I);
    WorkList.push_back(I);
  }

  inline void markTerminatorLive(const BasicBlock *BB) {
    DEBUG(cerr << "Terminat Live: " << BB->getTerminator());
    markInstructionLive((Instruction*)BB->getTerminator());
  }
};

  RegisterOpt<ADCE> X("adce", "Aggressive Dead Code Elimination");
} // End of anonymous namespace

Pass *createAggressiveDCEPass() { return new ADCE(); }

void ADCE::markBlockAlive(BasicBlock *BB) {
  // Mark the basic block as being newly ALIVE... and mark all branches that
  // this block is control dependant on as being alive also...
  //
  PostDominanceFrontier &CDG = getAnalysis<PostDominanceFrontier>();

  PostDominanceFrontier::const_iterator It = CDG.find(BB);
  if (It != CDG.end()) {
    // Get the blocks that this node is control dependant on...
    const PostDominanceFrontier::DomSetType &CDB = It->second;
    for_each(CDB.begin(), CDB.end(),   // Mark all their terminators as live
             bind_obj(this, &ADCE::markTerminatorLive));
  }

  // If this basic block is live, then the terminator must be as well!
  markTerminatorLive(BB);
}

// dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the
// instructions in the specified basic block, dropping references on
// instructions that are dead according to LiveSet.
bool ADCE::dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB) {
  bool Changed = false;
  for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; )
    if (!LiveSet.count(I)) {              // Is this instruction alive?
      I->dropAllReferences();             // Nope, drop references...
      if (PHINode *PN = dyn_cast<PHINode>(&*I)) {
        // We don't want to leave PHI nodes in the program that have
        // #arguments != #predecessors, so we remove them now.
        //
        PN->replaceAllUsesWith(Constant::getNullValue(PN->getType()));

        // Delete the instruction...
        I = BB->getInstList().erase(I);
        Changed = true;
      } else {
        ++I;
      }
    } else {
      ++I;
    }
  return Changed;
}

// doADCE() - Run the Aggressive Dead Code Elimination algorithm, returning
// true if the function was modified.
//
bool ADCE::doADCE() {
  bool MadeChanges = false;

  // Iterate over all of the instructions in the function, eliminating trivially
  // dead instructions, and marking instructions live that are known to be
  // needed.  Perform the walk in depth first order so that we avoid marking any
  // instructions live in basic blocks that are unreachable.  These blocks will
  // be eliminated later, along with the instructions inside.
  //
  for (df_iterator<Function*> BBI = df_begin(Func), BBE = df_end(Func);
       BBI != BBE; ++BBI) {
    BasicBlock *BB = *BBI;
    for (BasicBlock::iterator II = BB->begin(), EI = BB->end(); II != EI; ) {
      if (II->hasSideEffects() || II->getOpcode() == Instruction::Ret) {
	markInstructionLive(II);
        ++II;  // Increment the inst iterator if the inst wasn't deleted
      } else if (isInstructionTriviallyDead(II)) {
        // Remove the instruction from it's basic block...
        II = BB->getInstList().erase(II);
        ++NumInstRemoved;
        MadeChanges = true;
      } else {
        ++II;  // Increment the inst iterator if the inst wasn't deleted
      }
    }
  }

  DEBUG(cerr << "Processing work list\n");

  // AliveBlocks - Set of basic blocks that we know have instructions that are
  // alive in them...
  //
  std::set<BasicBlock*> AliveBlocks;

  // Process the work list of instructions that just became live... if they
  // became live, then that means that all of their operands are neccesary as
  // well... make them live as well.
  //
  while (!WorkList.empty()) {
    Instruction *I = WorkList.back(); // Get an instruction that became live...
    WorkList.pop_back();

    BasicBlock *BB = I->getParent();
    if (!AliveBlocks.count(BB)) {     // Basic block not alive yet...
      AliveBlocks.insert(BB);         // Block is now ALIVE!
      markBlockAlive(BB);             // Make it so now!
    }

    // PHI nodes are a special case, because the incoming values are actually
    // defined in the predecessor nodes of this block, meaning that the PHI
    // makes the predecessors alive.
    //
    if (PHINode *PN = dyn_cast<PHINode>(I))
      for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI)
        if (!AliveBlocks.count(*PI)) {
          AliveBlocks.insert(BB);         // Block is now ALIVE!
          markBlockAlive(*PI);
        }

    // Loop over all of the operands of the live instruction, making sure that
    // they are known to be alive as well...
    //
    for (unsigned op = 0, End = I->getNumOperands(); op != End; ++op)
      if (Instruction *Operand = dyn_cast<Instruction>(I->getOperand(op)))
	markInstructionLive(Operand);
  }

  if (DebugFlag) {
    cerr << "Current Function: X = Live\n";
    for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
      for (BasicBlock::iterator BI = I->begin(), BE = I->end(); BI != BE; ++BI){
        if (LiveSet.count(BI)) cerr << "X ";
        cerr << *BI;
      }
  }

  // Find the first postdominator of the entry node that is alive.  Make it the
  // new entry node...
  //
  PostDominatorTree &DT = getAnalysis<PostDominatorTree>();

  if (AliveBlocks.size() == Func->size()) {  // No dead blocks?
    for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
      // Loop over all of the instructions in the function, telling dead
      // instructions to drop their references.  This is so that the next sweep
      // over the program can safely delete dead instructions without other dead
      // instructions still refering to them.
      //
      dropReferencesOfDeadInstructionsInLiveBlock(I);

  } else {                                   // If there are some blocks dead...
    // Insert a new entry node to eliminate the entry node as a special case.
    BasicBlock *NewEntry = new BasicBlock();
    NewEntry->getInstList().push_back(new BranchInst(&Func->front()));
    Func->getBasicBlockList().push_front(NewEntry);
    AliveBlocks.insert(NewEntry);    // This block is always alive!

    // Loop over all of the alive blocks in the function.  If any successor
    // blocks are not alive, we adjust the outgoing branches to branch to the
    // first live postdominator of the live block, adjusting any PHI nodes in
    // the block to reflect this.
    //
    for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
      if (AliveBlocks.count(I)) {
        BasicBlock *BB = I;
        TerminatorInst *TI = BB->getTerminator();

        // Loop over all of the successors, looking for ones that are not alive.
        // We cannot save the number of successors in the terminator instruction
        // here because we may remove them if we don't have a postdominator...
        //
        for (unsigned i = 0; i != TI->getNumSuccessors(); ++i)
          if (!AliveBlocks.count(TI->getSuccessor(i))) {
            // Scan up the postdominator tree, looking for the first
            // postdominator that is alive, and the last postdominator that is
            // dead...
            //
            PostDominatorTree::Node *LastNode = DT[TI->getSuccessor(i)];

            // There is a special case here... if there IS no post-dominator for
            // the block we have no owhere to point our branch to.  Instead,
            // convert it to a return.  This can only happen if the code
            // branched into an infinite loop.  Note that this may not be
            // desirable, because we _are_ altering the behavior of the code.
            // This is a well known drawback of ADCE, so in the future if we
            // choose to revisit the decision, this is where it should be.
            //
            if (LastNode == 0) {        // No postdominator!
              // Call RemoveSuccessor to transmogrify the terminator instruction
              // to not contain the outgoing branch, or to create a new
              // terminator if the form fundementally changes (ie unconditional
              // branch to return).  Note that this will change a branch into an
              // infinite loop into a return instruction!
              //
              RemoveSuccessor(TI, i);

              // RemoveSuccessor may replace TI... make sure we have a fresh
              // pointer... and e variable.
              //
              TI = BB->getTerminator();

              // Rescan this successor...
              --i;
            } else {
              PostDominatorTree::Node *NextNode = LastNode->getIDom();

              while (!AliveBlocks.count(NextNode->getNode())) {
                LastNode = NextNode;
                NextNode = NextNode->getIDom();
              }

              // Get the basic blocks that we need...
              BasicBlock *LastDead = LastNode->getNode();
              BasicBlock *NextAlive = NextNode->getNode();

              // Make the conditional branch now go to the next alive block...
              TI->getSuccessor(i)->removePredecessor(BB);
              TI->setSuccessor(i, NextAlive);

              // If there are PHI nodes in NextAlive, we need to add entries to
              // the PHI nodes for the new incoming edge.  The incoming values
              // should be identical to the incoming values for LastDead.
              //
              for (BasicBlock::iterator II = NextAlive->begin();
                   PHINode *PN = dyn_cast<PHINode>(&*II); ++II) {
                // Get the incoming value for LastDead...
                int OldIdx = PN->getBasicBlockIndex(LastDead);
                assert(OldIdx != -1 && "LastDead is not a pred of NextAlive!");
                Value *InVal = PN->getIncomingValue(OldIdx);

                // Add an incoming value for BB now...
                PN->addIncoming(InVal, BB);
              }
            }
          }

        // Now loop over all of the instructions in the basic block, telling
        // dead instructions to drop their references.  This is so that the next
        // sweep over the program can safely delete dead instructions without
        // other dead instructions still refering to them.
        //
        dropReferencesOfDeadInstructionsInLiveBlock(BB);
      }
  }

  // Loop over all of the basic blocks in the function, dropping references of
  // the dead basic blocks
  //
  for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) {
    if (!AliveBlocks.count(BB)) {
      // Remove all outgoing edges from this basic block and convert the
      // terminator into a return instruction.
      vector<BasicBlock*> Succs(succ_begin(BB), succ_end(BB));

      if (!Succs.empty()) {
        // Loop over all of the successors, removing this block from PHI node
        // entries that might be in the block...
        while (!Succs.empty()) {
          Succs.back()->removePredecessor(BB);
          Succs.pop_back();
        }

        // Delete the old terminator instruction...
        BB->getInstList().pop_back();
        const Type *RetTy = Func->getReturnType();
        Instruction *New = new ReturnInst(RetTy != Type::VoidTy ?
                                          Constant::getNullValue(RetTy) : 0);
        BB->getInstList().push_back(New);
      }

      BB->dropAllReferences();
      ++NumBlockRemoved;
      MadeChanges = true;
    }
  }

  // Now loop through all of the blocks and delete the dead ones.  We can safely
  // do this now because we know that there are no references to dead blocks
  // (because they have dropped all of their references...  we also remove dead
  // instructions from alive blocks.
  //
  for (Function::iterator BI = Func->begin(); BI != Func->end(); )
    if (!AliveBlocks.count(BI)) {                // Delete dead blocks...
      BI = Func->getBasicBlockList().erase(BI);
    } else {                                     // Scan alive blocks...
      for (BasicBlock::iterator II = BI->begin(); II != --BI->end(); )
        if (!LiveSet.count(II)) {             // Is this instruction alive?
          // Nope... remove the instruction from it's basic block...
          II = BI->getInstList().erase(II);
          ++NumInstRemoved;
          MadeChanges = true;
        } else {
          ++II;
        }

      ++BI;                                           // Increment iterator...
    }

  return MadeChanges;
}
<commit_msg>Avoid inserting an entry block unless we need it<commit_after>//===- ADCE.cpp - Code to perform aggressive dead code elimination --------===//
//
// This file implements "aggressive" dead code elimination.  ADCE is DCe where
// values are assumed to be dead until proven otherwise.  This is similar to
// SCCP, except applied to the liveness of values.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Type.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/Constant.h"
#include "llvm/Support/CFG.h"
#include "Support/STLExtras.h"
#include "Support/DepthFirstIterator.h"
#include "Support/StatisticReporter.h"
#include <algorithm>
#include <iostream>
using std::cerr;
using std::vector;

static Statistic<> NumBlockRemoved("adce\t\t- Number of basic blocks removed");
static Statistic<> NumInstRemoved ("adce\t\t- Number of instructions removed");

namespace {

//===----------------------------------------------------------------------===//
// ADCE Class
//
// This class does all of the work of Aggressive Dead Code Elimination.
// It's public interface consists of a constructor and a doADCE() method.
//
class ADCE : public FunctionPass {
  Function *Func;                       // The function that we are working on
  std::vector<Instruction*> WorkList;   // Instructions that just became live
  std::set<Instruction*>    LiveSet;    // The set of live instructions

  //===--------------------------------------------------------------------===//
  // The public interface for this class
  //
public:
  // Execute the Aggressive Dead Code Elimination Algorithm
  //
  virtual bool runOnFunction(Function &F) {
    Func = &F;
    bool Changed = doADCE();
    assert(WorkList.empty());
    LiveSet.clear();
    return Changed;
  }
  // getAnalysisUsage - We require post dominance frontiers (aka Control
  // Dependence Graph)
  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    AU.addRequired<PostDominatorTree>();
    AU.addRequired<PostDominanceFrontier>();
  }

  //===--------------------------------------------------------------------===//
  // The implementation of this class
  //
private:
  // doADCE() - Run the Aggressive Dead Code Elimination algorithm, returning
  // true if the function was modified.
  //
  bool doADCE();

  void markBlockAlive(BasicBlock *BB);

  // dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the
  // instructions in the specified basic block, dropping references on
  // instructions that are dead according to LiveSet.
  bool dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB);

  inline void markInstructionLive(Instruction *I) {
    if (LiveSet.count(I)) return;
    DEBUG(cerr << "Insn Live: " << I);
    LiveSet.insert(I);
    WorkList.push_back(I);
  }

  inline void markTerminatorLive(const BasicBlock *BB) {
    DEBUG(cerr << "Terminat Live: " << BB->getTerminator());
    markInstructionLive((Instruction*)BB->getTerminator());
  }
};

  RegisterOpt<ADCE> X("adce", "Aggressive Dead Code Elimination");
} // End of anonymous namespace

Pass *createAggressiveDCEPass() { return new ADCE(); }

void ADCE::markBlockAlive(BasicBlock *BB) {
  // Mark the basic block as being newly ALIVE... and mark all branches that
  // this block is control dependant on as being alive also...
  //
  PostDominanceFrontier &CDG = getAnalysis<PostDominanceFrontier>();

  PostDominanceFrontier::const_iterator It = CDG.find(BB);
  if (It != CDG.end()) {
    // Get the blocks that this node is control dependant on...
    const PostDominanceFrontier::DomSetType &CDB = It->second;
    for_each(CDB.begin(), CDB.end(),   // Mark all their terminators as live
             bind_obj(this, &ADCE::markTerminatorLive));
  }

  // If this basic block is live, then the terminator must be as well!
  markTerminatorLive(BB);
}

// dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the
// instructions in the specified basic block, dropping references on
// instructions that are dead according to LiveSet.
bool ADCE::dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB) {
  bool Changed = false;
  for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; )
    if (!LiveSet.count(I)) {              // Is this instruction alive?
      I->dropAllReferences();             // Nope, drop references...
      if (PHINode *PN = dyn_cast<PHINode>(&*I)) {
        // We don't want to leave PHI nodes in the program that have
        // #arguments != #predecessors, so we remove them now.
        //
        PN->replaceAllUsesWith(Constant::getNullValue(PN->getType()));

        // Delete the instruction...
        I = BB->getInstList().erase(I);
        Changed = true;
      } else {
        ++I;
      }
    } else {
      ++I;
    }
  return Changed;
}

// doADCE() - Run the Aggressive Dead Code Elimination algorithm, returning
// true if the function was modified.
//
bool ADCE::doADCE() {
  bool MadeChanges = false;

  // Iterate over all of the instructions in the function, eliminating trivially
  // dead instructions, and marking instructions live that are known to be
  // needed.  Perform the walk in depth first order so that we avoid marking any
  // instructions live in basic blocks that are unreachable.  These blocks will
  // be eliminated later, along with the instructions inside.
  //
  for (df_iterator<Function*> BBI = df_begin(Func), BBE = df_end(Func);
       BBI != BBE; ++BBI) {
    BasicBlock *BB = *BBI;
    for (BasicBlock::iterator II = BB->begin(), EI = BB->end(); II != EI; ) {
      if (II->hasSideEffects() || II->getOpcode() == Instruction::Ret) {
	markInstructionLive(II);
        ++II;  // Increment the inst iterator if the inst wasn't deleted
      } else if (isInstructionTriviallyDead(II)) {
        // Remove the instruction from it's basic block...
        II = BB->getInstList().erase(II);
        ++NumInstRemoved;
        MadeChanges = true;
      } else {
        ++II;  // Increment the inst iterator if the inst wasn't deleted
      }
    }
  }

  DEBUG(cerr << "Processing work list\n");

  // AliveBlocks - Set of basic blocks that we know have instructions that are
  // alive in them...
  //
  std::set<BasicBlock*> AliveBlocks;

  // Process the work list of instructions that just became live... if they
  // became live, then that means that all of their operands are neccesary as
  // well... make them live as well.
  //
  while (!WorkList.empty()) {
    Instruction *I = WorkList.back(); // Get an instruction that became live...
    WorkList.pop_back();

    BasicBlock *BB = I->getParent();
    if (!AliveBlocks.count(BB)) {     // Basic block not alive yet...
      AliveBlocks.insert(BB);         // Block is now ALIVE!
      markBlockAlive(BB);             // Make it so now!
    }

    // PHI nodes are a special case, because the incoming values are actually
    // defined in the predecessor nodes of this block, meaning that the PHI
    // makes the predecessors alive.
    //
    if (PHINode *PN = dyn_cast<PHINode>(I))
      for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI)
        if (!AliveBlocks.count(*PI)) {
          AliveBlocks.insert(BB);         // Block is now ALIVE!
          markBlockAlive(*PI);
        }

    // Loop over all of the operands of the live instruction, making sure that
    // they are known to be alive as well...
    //
    for (unsigned op = 0, End = I->getNumOperands(); op != End; ++op)
      if (Instruction *Operand = dyn_cast<Instruction>(I->getOperand(op)))
	markInstructionLive(Operand);
  }

  if (DebugFlag) {
    cerr << "Current Function: X = Live\n";
    for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
      for (BasicBlock::iterator BI = I->begin(), BE = I->end(); BI != BE; ++BI){
        if (LiveSet.count(BI)) cerr << "X ";
        cerr << *BI;
      }
  }

  // Find the first postdominator of the entry node that is alive.  Make it the
  // new entry node...
  //
  PostDominatorTree &DT = getAnalysis<PostDominatorTree>();

  if (AliveBlocks.size() == Func->size()) {  // No dead blocks?
    for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
      // Loop over all of the instructions in the function, telling dead
      // instructions to drop their references.  This is so that the next sweep
      // over the program can safely delete dead instructions without other dead
      // instructions still refering to them.
      //
      dropReferencesOfDeadInstructionsInLiveBlock(I);

  } else {                                   // If there are some blocks dead...
    // If the entry node is dead, insert a new entry node to eliminate the entry
    // node as a special case.
    //
    if (!AliveBlocks.count(&Func->front())) {
      BasicBlock *NewEntry = new BasicBlock();
      NewEntry->getInstList().push_back(new BranchInst(&Func->front()));
      Func->getBasicBlockList().push_front(NewEntry);
      AliveBlocks.insert(NewEntry);    // This block is always alive!
    }

    // Loop over all of the alive blocks in the function.  If any successor
    // blocks are not alive, we adjust the outgoing branches to branch to the
    // first live postdominator of the live block, adjusting any PHI nodes in
    // the block to reflect this.
    //
    for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
      if (AliveBlocks.count(I)) {
        BasicBlock *BB = I;
        TerminatorInst *TI = BB->getTerminator();

        // Loop over all of the successors, looking for ones that are not alive.
        // We cannot save the number of successors in the terminator instruction
        // here because we may remove them if we don't have a postdominator...
        //
        for (unsigned i = 0; i != TI->getNumSuccessors(); ++i)
          if (!AliveBlocks.count(TI->getSuccessor(i))) {
            // Scan up the postdominator tree, looking for the first
            // postdominator that is alive, and the last postdominator that is
            // dead...
            //
            PostDominatorTree::Node *LastNode = DT[TI->getSuccessor(i)];

            // There is a special case here... if there IS no post-dominator for
            // the block we have no owhere to point our branch to.  Instead,
            // convert it to a return.  This can only happen if the code
            // branched into an infinite loop.  Note that this may not be
            // desirable, because we _are_ altering the behavior of the code.
            // This is a well known drawback of ADCE, so in the future if we
            // choose to revisit the decision, this is where it should be.
            //
            if (LastNode == 0) {        // No postdominator!
              // Call RemoveSuccessor to transmogrify the terminator instruction
              // to not contain the outgoing branch, or to create a new
              // terminator if the form fundementally changes (ie unconditional
              // branch to return).  Note that this will change a branch into an
              // infinite loop into a return instruction!
              //
              RemoveSuccessor(TI, i);

              // RemoveSuccessor may replace TI... make sure we have a fresh
              // pointer... and e variable.
              //
              TI = BB->getTerminator();

              // Rescan this successor...
              --i;
            } else {
              PostDominatorTree::Node *NextNode = LastNode->getIDom();

              while (!AliveBlocks.count(NextNode->getNode())) {
                LastNode = NextNode;
                NextNode = NextNode->getIDom();
              }

              // Get the basic blocks that we need...
              BasicBlock *LastDead = LastNode->getNode();
              BasicBlock *NextAlive = NextNode->getNode();

              // Make the conditional branch now go to the next alive block...
              TI->getSuccessor(i)->removePredecessor(BB);
              TI->setSuccessor(i, NextAlive);

              // If there are PHI nodes in NextAlive, we need to add entries to
              // the PHI nodes for the new incoming edge.  The incoming values
              // should be identical to the incoming values for LastDead.
              //
              for (BasicBlock::iterator II = NextAlive->begin();
                   PHINode *PN = dyn_cast<PHINode>(&*II); ++II) {
                // Get the incoming value for LastDead...
                int OldIdx = PN->getBasicBlockIndex(LastDead);
                assert(OldIdx != -1 && "LastDead is not a pred of NextAlive!");
                Value *InVal = PN->getIncomingValue(OldIdx);

                // Add an incoming value for BB now...
                PN->addIncoming(InVal, BB);
              }
            }
          }

        // Now loop over all of the instructions in the basic block, telling
        // dead instructions to drop their references.  This is so that the next
        // sweep over the program can safely delete dead instructions without
        // other dead instructions still refering to them.
        //
        dropReferencesOfDeadInstructionsInLiveBlock(BB);
      }
  }

  // Loop over all of the basic blocks in the function, dropping references of
  // the dead basic blocks
  //
  for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) {
    if (!AliveBlocks.count(BB)) {
      // Remove all outgoing edges from this basic block and convert the
      // terminator into a return instruction.
      vector<BasicBlock*> Succs(succ_begin(BB), succ_end(BB));

      if (!Succs.empty()) {
        // Loop over all of the successors, removing this block from PHI node
        // entries that might be in the block...
        while (!Succs.empty()) {
          Succs.back()->removePredecessor(BB);
          Succs.pop_back();
        }

        // Delete the old terminator instruction...
        BB->getInstList().pop_back();
        const Type *RetTy = Func->getReturnType();
        Instruction *New = new ReturnInst(RetTy != Type::VoidTy ?
                                          Constant::getNullValue(RetTy) : 0);
        BB->getInstList().push_back(New);
      }

      BB->dropAllReferences();
      ++NumBlockRemoved;
      MadeChanges = true;
    }
  }

  // Now loop through all of the blocks and delete the dead ones.  We can safely
  // do this now because we know that there are no references to dead blocks
  // (because they have dropped all of their references...  we also remove dead
  // instructions from alive blocks.
  //
  for (Function::iterator BI = Func->begin(); BI != Func->end(); )
    if (!AliveBlocks.count(BI)) {                // Delete dead blocks...
      BI = Func->getBasicBlockList().erase(BI);
    } else {                                     // Scan alive blocks...
      for (BasicBlock::iterator II = BI->begin(); II != --BI->end(); )
        if (!LiveSet.count(II)) {             // Is this instruction alive?
          // Nope... remove the instruction from it's basic block...
          II = BI->getInstList().erase(II);
          ++NumInstRemoved;
          MadeChanges = true;
        } else {
          ++II;
        }

      ++BI;                                           // Increment iterator...
    }

  return MadeChanges;
}
<|endoftext|>