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_ = &register_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
-~----------~----~----~----~------~----~------~--~---

Reply via email to