Allow IfBuilder's to join existing (captured) continuations.

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/23452049

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16857 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
bmeurer@chromium.org 2013-09-20 10:47:09 +00:00
parent ae4234b488
commit 6fce49609b
2 changed files with 74 additions and 1 deletions

View File

@ -806,6 +806,28 @@ void HGraphBuilder::IfBuilder::CaptureContinuation(
}
void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) {
ASSERT(!finished_);
ASSERT(!captured_);
HBasicBlock* true_block = last_true_block_ == NULL
? first_true_block_
: last_true_block_;
HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL)
? builder_->current_block()
: first_false_block_;
if (true_block != NULL && !true_block->IsFinished()) {
ASSERT(continuation->IsTrueReachable());
true_block->GotoNoSimulate(continuation->true_branch());
}
if (false_block != NULL && !false_block->IsFinished()) {
ASSERT(continuation->IsFalseReachable());
false_block->GotoNoSimulate(continuation->false_branch());
}
captured_ = true;
End();
}
void HGraphBuilder::IfBuilder::Then() {
ASSERT(!captured_);
ASSERT(!finished_);

View File

@ -941,7 +941,12 @@ class FunctionState V8_FINAL {
class HIfContinuation V8_FINAL {
public:
HIfContinuation() { continuation_captured_ = false; }
HIfContinuation() : continuation_captured_(false) {}
HIfContinuation(HBasicBlock* true_branch,
HBasicBlock* false_branch,
int position = RelocInfo::kNoPosition)
: continuation_captured_(true), true_branch_(true_branch),
false_branch_(false_branch), position_(position) {}
~HIfContinuation() { ASSERT(!continuation_captured_); }
void Capture(HBasicBlock* true_branch,
@ -970,6 +975,10 @@ class HIfContinuation V8_FINAL {
return IsTrueReachable() || IsFalseReachable();
}
HBasicBlock* true_branch() const { return true_branch_; }
HBasicBlock* false_branch() const { return false_branch_; }
private:
bool continuation_captured_;
HBasicBlock* true_branch_;
HBasicBlock* false_branch_;
@ -1380,8 +1389,50 @@ class HGraphBuilder {
void Or();
void And();
// Captures the current state of this IfBuilder in the specified
// continuation and ends this IfBuilder.
void CaptureContinuation(HIfContinuation* continuation);
// Joins the specified continuation from this IfBuilder and ends this
// IfBuilder. This appends a Goto instruction from the true branch of
// this IfBuilder to the true branch of the continuation unless the
// true branch of this IfBuilder is already finished. And vice versa
// for the false branch.
//
// The basic idea is as follows: You have several nested IfBuilder's
// that you want to join based on two possible outcomes (i.e. success
// and failure, or whatever). You can do this easily using this method
// now, for example:
//
// HIfContinuation cont(graph()->CreateBasicBlock(),
// graph()->CreateBasicBlock());
// ...
// IfBuilder if_whatever(this);
// if_whatever.If<Condition>(arg);
// if_whatever.Then();
// ...
// if_whatever.Else();
// ...
// if_whatever.JoinContinuation(&cont);
// ...
// IfBuilder if_something(this);
// if_something.If<Condition>(arg1, arg2);
// if_something.Then();
// ...
// if_something.Else();
// ...
// if_something.JoinContinuation(&cont);
// ...
// IfBuilder if_finally(this, &cont);
// if_finally.Then();
// // continues after then code of if_whatever or if_something.
// ...
// if_finally.Else();
// // continues after else code of if_whatever or if_something.
// ...
// if_finally.End();
void JoinContinuation(HIfContinuation* continuation);
void Then();
void Else();
void End();