Home | History | Annotate | Download | only in compiler
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/compiler/control-builders.h"
      6 
      7 #include "src/objects-inl.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 namespace compiler {
     12 
     13 
     14 void IfBuilder::If(Node* condition, BranchHint hint) {
     15   builder_->NewBranch(condition, hint);
     16   else_environment_ = environment()->CopyForConditional();
     17 }
     18 
     19 
     20 void IfBuilder::Then() { builder_->NewIfTrue(); }
     21 
     22 
     23 void IfBuilder::Else() {
     24   builder_->NewMerge();
     25   then_environment_ = environment();
     26   set_environment(else_environment_);
     27   builder_->NewIfFalse();
     28 }
     29 
     30 
     31 void IfBuilder::End() {
     32   then_environment_->Merge(environment());
     33   set_environment(then_environment_);
     34 }
     35 
     36 
     37 void LoopBuilder::BeginLoop(BitVector* assigned, bool is_osr) {
     38   loop_environment_ = environment()->CopyForLoop(assigned, is_osr);
     39   continue_environment_ = environment()->CopyAsUnreachable();
     40   break_environment_ = environment()->CopyAsUnreachable();
     41   assigned_ = assigned;
     42 }
     43 
     44 
     45 void LoopBuilder::Continue() {
     46   continue_environment_->Merge(environment());
     47   environment()->MarkAsUnreachable();
     48 }
     49 
     50 
     51 void LoopBuilder::Break() {
     52   break_environment_->Merge(environment());
     53   environment()->MarkAsUnreachable();
     54 }
     55 
     56 
     57 void LoopBuilder::EndBody() {
     58   continue_environment_->Merge(environment());
     59   set_environment(continue_environment_);
     60 }
     61 
     62 
     63 void LoopBuilder::EndLoop() {
     64   loop_environment_->Merge(environment());
     65   set_environment(break_environment_);
     66   ExitLoop();
     67 }
     68 
     69 
     70 void LoopBuilder::BreakUnless(Node* condition) {
     71   IfBuilder control_if(builder_);
     72   control_if.If(condition);
     73   control_if.Then();
     74   control_if.Else();
     75   Break();
     76   control_if.End();
     77 }
     78 
     79 
     80 void LoopBuilder::BreakWhen(Node* condition) {
     81   IfBuilder control_if(builder_);
     82   control_if.If(condition);
     83   control_if.Then();
     84   Break();
     85   control_if.Else();
     86   control_if.End();
     87 }
     88 
     89 void LoopBuilder::ExitLoop(Node** extra_value_to_rename) {
     90   if (extra_value_to_rename) {
     91     environment()->Push(*extra_value_to_rename);
     92   }
     93   environment()->PrepareForLoopExit(loop_environment_->GetControlDependency(),
     94                                     assigned_);
     95   if (extra_value_to_rename) {
     96     *extra_value_to_rename = environment()->Pop();
     97   }
     98 }
     99 
    100 void SwitchBuilder::BeginSwitch() {
    101   body_environment_ = environment()->CopyAsUnreachable();
    102   label_environment_ = environment()->CopyAsUnreachable();
    103   break_environment_ = environment()->CopyAsUnreachable();
    104 }
    105 
    106 
    107 void SwitchBuilder::BeginLabel(int index, Node* condition) {
    108   builder_->NewBranch(condition);
    109   label_environment_ = environment()->CopyForConditional();
    110   builder_->NewIfTrue();
    111   body_environments_[index] = environment();
    112 }
    113 
    114 
    115 void SwitchBuilder::EndLabel() {
    116   set_environment(label_environment_);
    117   builder_->NewIfFalse();
    118 }
    119 
    120 
    121 void SwitchBuilder::DefaultAt(int index) {
    122   label_environment_ = environment()->CopyAsUnreachable();
    123   body_environments_[index] = environment();
    124 }
    125 
    126 
    127 void SwitchBuilder::BeginCase(int index) {
    128   set_environment(body_environments_[index]);
    129   environment()->Merge(body_environment_);
    130 }
    131 
    132 
    133 void SwitchBuilder::Break() {
    134   break_environment_->Merge(environment());
    135   environment()->MarkAsUnreachable();
    136 }
    137 
    138 
    139 void SwitchBuilder::EndCase() { body_environment_ = environment(); }
    140 
    141 
    142 void SwitchBuilder::EndSwitch() {
    143   break_environment_->Merge(label_environment_);
    144   break_environment_->Merge(environment());
    145   set_environment(break_environment_);
    146 }
    147 
    148 
    149 void BlockBuilder::BeginBlock() {
    150   break_environment_ = environment()->CopyAsUnreachable();
    151 }
    152 
    153 
    154 void BlockBuilder::Break() {
    155   break_environment_->Merge(environment());
    156   environment()->MarkAsUnreachable();
    157 }
    158 
    159 
    160 void BlockBuilder::BreakWhen(Node* condition, BranchHint hint) {
    161   IfBuilder control_if(builder_);
    162   control_if.If(condition, hint);
    163   control_if.Then();
    164   Break();
    165   control_if.Else();
    166   control_if.End();
    167 }
    168 
    169 
    170 void BlockBuilder::BreakUnless(Node* condition, BranchHint hint) {
    171   IfBuilder control_if(builder_);
    172   control_if.If(condition, hint);
    173   control_if.Then();
    174   control_if.Else();
    175   Break();
    176   control_if.End();
    177 }
    178 
    179 
    180 void BlockBuilder::EndBlock() {
    181   break_environment_->Merge(environment());
    182   set_environment(break_environment_);
    183 }
    184 
    185 }  // namespace compiler
    186 }  // namespace internal
    187 }  // namespace v8
    188