Author: [email protected]
Date: Thu Jan 22 01:30:43 2009
New Revision: 1121
Modified:
branches/experimental/toiger/src/codegen-ia32.cc
branches/experimental/toiger/src/codegen.cc
branches/experimental/toiger/src/jump-target-ia32.cc
branches/experimental/toiger/src/jump-target.h
Log:
Experimental: statically distinguish between named basic block entries
that are definitely reached by only forward CFG edges and those that
may be reached by a backward edge. Assert that we do not try to jump
backward to forward-only blocks. Otherwise, the two types of blocks
are not handled differently yet.
There are only a handful of backward edges:
* one for each of the loop types (while, for, and do...while),
* the for...in statement,
* a loop in GenerateFastCharCodeAt,
* the fall-through from a default case in a switch when it is not the
last case,
* (possibly) the return sequence
* the exit labels from deferred code
The last two are not true backward edges (there is no loop).
Review URL: http://codereview.chromium.org/18362
Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc Thu Jan 22 01:30:43
2009
@@ -138,7 +138,7 @@
allocator_ = ®ister_allocator;
ASSERT(frame_ == NULL);
frame_ = new VirtualFrame(this);
- function_return_.set_code_generator(this);
+ function_return_.Initialize(this, JumpTarget::BIDIRECTIONAL);
function_return_is_shadowed_ = false;
set_in_spilled_code(false);
@@ -1357,7 +1357,7 @@
Comment cmnt(masm_, "[ Block");
CodeForStatement(node);
node->set_break_stack_height(break_stack_height_);
- node->break_target()->set_code_generator(this);
+ node->break_target()->Initialize(this);
VisitStatements(node->statements());
if (node->break_target()->is_linked()) {
node->break_target()->Bind();
@@ -1739,7 +1739,7 @@
Comment cmnt(masm_, "[ SwitchStatement");
CodeForStatement(node);
node->set_break_stack_height(break_stack_height_);
- node->break_target()->set_code_generator(this);
+ node->break_target()->Initialize(this);
Load(node->tag());
@@ -1750,7 +1750,7 @@
JumpTarget next_test(this);
JumpTarget fall_through(this);
JumpTarget default_entry(this);
- JumpTarget default_exit(this);
+ JumpTarget default_exit(this, JumpTarget::BIDIRECTIONAL);
ZoneList<CaseClause*>* cases = node->cases();
int length = cases->length();
CaseClause* default_clause = NULL;
@@ -1838,8 +1838,7 @@
Comment cmnt(masm_, "[ LoopStatement");
CodeForStatement(node);
node->set_break_stack_height(break_stack_height_);
- node->break_target()->set_code_generator(this);
- node->continue_target()->set_code_generator(this);
+ node->break_target()->Initialize(this);
// Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
// known result for the test expression, with no side effects.
@@ -1860,18 +1859,21 @@
switch (node->type()) {
case LoopStatement::DO_LOOP: {
- JumpTarget body(this);
+ JumpTarget body(this, JumpTarget::BIDIRECTIONAL);
IncrementLoopNesting();
// Label the top of the loop for the backward CFG edge. If the test
// is always true we can use the continue target, and if the test is
// always false there is no need.
if (info == ALWAYS_TRUE) {
+ node->continue_target()->Initialize(this,
JumpTarget::BIDIRECTIONAL);
node->continue_target()->Bind();
} else if (info == ALWAYS_FALSE) {
+ node->continue_target()->Initialize(this);
// There is no need, we will never jump back.
} else {
ASSERT(info == DONT_KNOW);
+ node->continue_target()->Initialize(this);
body.Bind();
}
@@ -1914,6 +1916,7 @@
// Label the top of the loop with the continue target for the
backward
// CFG edge.
+ node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
node->continue_target()->Bind();
// If the test is always true and has no side effects there is no
need
@@ -1941,7 +1944,7 @@
}
case LoopStatement::FOR_LOOP: {
- JumpTarget loop(this);
+ JumpTarget loop(this, JumpTarget::BIDIRECTIONAL);
if (node->init() != NULL) {
Visit(node->init());
}
@@ -1954,8 +1957,10 @@
// Label the top of the loop for the backward CFG edge. If there is
// no update expression we can use the continue target.
if (node->next() == NULL) {
+ node->continue_target()->Initialize(this,
JumpTarget::BIDIRECTIONAL);
node->continue_target()->Bind();
} else {
+ node->continue_target()->Initialize(this);
loop.Bind();
}
@@ -2022,13 +2027,13 @@
const int kForInStackSize = 5 * kPointerSize;
break_stack_height_ += kForInStackSize;
node->set_break_stack_height(break_stack_height_);
- node->break_target()->set_code_generator(this);
- node->continue_target()->set_code_generator(this);
+ node->break_target()->Initialize(this);
+ node->continue_target()->Initialize(this);
JumpTarget primitive(this);
JumpTarget jsobject(this);
JumpTarget fixed_array(this);
- JumpTarget entry(this);
+ JumpTarget entry(this, JumpTarget::BIDIRECTIONAL);
JumpTarget end_del_check(this);
JumpTarget cleanup(this);
JumpTarget exit(this);
@@ -3364,7 +3369,7 @@
JumpTarget end(this);
JumpTarget not_a_flat_string(this);
JumpTarget not_a_cons_string_either(this);
- JumpTarget try_again_with_new_string(this);
+ JumpTarget try_again_with_new_string(this, JumpTarget::BIDIRECTIONAL);
JumpTarget ascii_string(this);
JumpTarget got_char_code(this);
Modified: branches/experimental/toiger/src/codegen.cc
==============================================================================
--- branches/experimental/toiger/src/codegen.cc (original)
+++ branches/experimental/toiger/src/codegen.cc Thu Jan 22 01:30:43 2009
@@ -41,7 +41,7 @@
: masm_(generator->masm()),
generator_(generator),
enter_(generator),
- exit_(generator),
+ exit_(generator, JumpTarget::BIDIRECTIONAL),
statement_position_(masm_->current_statement_position()),
position_(masm_->current_position()) {
generator->AddDeferred(this);
@@ -385,7 +385,7 @@
// JumpTarget per switch case.
SmartPointer<JumpTarget> case_labels(NewArray<JumpTarget>(length));
for (int i = 0; i < length; i++) {
- case_labels[i].set_code_generator(this);
+ case_labels[i].Initialize(this);
}
JumpTarget* fail_label = default_index >= 0 ?
&(case_labels[default_index])
Modified: branches/experimental/toiger/src/jump-target-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/jump-target-ia32.cc (original)
+++ branches/experimental/toiger/src/jump-target-ia32.cc Thu Jan 22
01:30:43 2009
@@ -37,8 +37,9 @@
#define __ masm_->
-JumpTarget::JumpTarget(CodeGenerator* cgen)
+JumpTarget::JumpTarget(CodeGenerator* cgen, Directionality direction)
: cgen_(cgen),
+ direction_(direction),
reaching_frames_(0),
merge_labels_(0),
expected_frame_(NULL) {
@@ -50,17 +51,19 @@
JumpTarget::JumpTarget()
: cgen_(NULL),
masm_(NULL),
+ direction_(FORWARD_ONLY),
reaching_frames_(0),
merge_labels_(0),
expected_frame_(NULL) {
}
-void JumpTarget::set_code_generator(CodeGenerator* cgen) {
+void JumpTarget::Initialize(CodeGenerator* cgen, Directionality direction)
{
ASSERT(cgen != NULL);
ASSERT(cgen_ == NULL);
cgen_ = cgen;
masm_ = cgen->masm();
+ direction_ = direction;
}
@@ -74,6 +77,7 @@
if (is_bound()) {
// Backward jump. There is an expected frame to merge to.
+ ASSERT(direction_ == BIDIRECTIONAL);
cgen_->frame()->MergeTo(expected_frame_);
cgen_->DeleteFrame();
__ jmp(&entry_label_);
@@ -120,6 +124,7 @@
// TODO(): we should try to avoid negating the condition in the case
// where there is no merge code to emit. Otherwise, we emit a
// branch around an unconditional jump.
+ ASSERT(direction_ == BIDIRECTIONAL);
Label original_fall_through;
__ j(NegateCondition(cc), &original_fall_through, NegateHint(hint));
// Swap the current frame for a copy of it, saving non-frame
@@ -305,7 +310,7 @@
ASSERT(destination != NULL);
destination->cgen_ = cgen_;
destination->masm_ = masm_;
-
+ destination->direction_ = direction_;
destination->reaching_frames_.Clear();
destination->merge_labels_.Clear();
ASSERT(reaching_frames_.length() == merge_labels_.length());
@@ -354,17 +359,19 @@
void ShadowTarget::StopShadowing() {
ASSERT(is_shadowing_);
+ // This target does not have a valid code generator yet.
+ cgen_ = other_target_->code_generator();
+ ASSERT(cgen_ != NULL);
+ masm_ = cgen_->masm();
+
// The states of this target, which was shadowed, and the original
// target, which was shadowing, are swapped.
JumpTarget temp;
-
other_target_->CopyTo(&temp);
CopyTo(other_target_);
temp.CopyTo(this);
temp.Reset(); // So the destructor does not deallocate virtual frames.
- // The shadowing target does not have a valid code generator yet.
- other_target_->set_code_generator(cgen_);
#ifdef DEBUG
is_shadowing_ = false;
#endif
Modified: branches/experimental/toiger/src/jump-target.h
==============================================================================
--- branches/experimental/toiger/src/jump-target.h (original)
+++ branches/experimental/toiger/src/jump-target.h Thu Jan 22 01:30:43 2009
@@ -52,9 +52,13 @@
class JumpTarget : public ZoneObject { // Shadows are dynamically
allocated.
public:
+ // Forward-only jump targets can only be reached by forward CFG edges.
+ enum Directionality { FORWARD_ONLY, BIDIRECTIONAL };
+
// Construct a jump target with a given code generator used to generate
// code and to provide access to a current frame.
- explicit JumpTarget(CodeGenerator* cgen);
+ explicit JumpTarget(CodeGenerator* cgen,
+ Directionality direction = FORWARD_ONLY);
// Construct a jump target without a code generator. A code generator
// must be supplied before using the jump target as a label. This is
@@ -63,10 +67,12 @@
virtual ~JumpTarget() { Unuse(); }
- // Supply a code generator. This function expects to be given a non-null
- // code generator, and to be called only when the code generator is not
- // yet set.
- void set_code_generator(CodeGenerator* cgen);
+ // Supply a code generator and directionality to an already
+ // constructed jump target. This function expects to be given a
+ // non-null code generator, and to be called only when the code
+ // generator is not yet set.
+ void Initialize(CodeGenerator* cgen,
+ Directionality direction = FORWARD_ONLY);
// Accessors.
CodeGenerator* code_generator() const { return cgen_; }
@@ -145,6 +151,9 @@
MacroAssembler* masm_;
private:
+ // Directionality flag set at initialization time.
+ Directionality direction_;
+
// A list of frames reaching this block via forward jumps.
List<VirtualFrame*> reaching_frames_;
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---