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:
parent
ae4234b488
commit
6fce49609b
@ -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_);
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user