Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 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/load-elimination.h"
      6 
      7 #include "src/compiler/node-properties.h"
      8 #include "src/compiler/simplified-operator.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 namespace compiler {
     13 
     14 LoadElimination::~LoadElimination() {}
     15 
     16 
     17 Reduction LoadElimination::Reduce(Node* node) {
     18   switch (node->opcode()) {
     19     case IrOpcode::kLoadField:
     20       return ReduceLoadField(node);
     21     default:
     22       break;
     23   }
     24   return NoChange();
     25 }
     26 
     27 
     28 Reduction LoadElimination::ReduceLoadField(Node* node) {
     29   DCHECK_EQ(IrOpcode::kLoadField, node->opcode());
     30   FieldAccess const access = FieldAccessOf(node->op());
     31   Node* object = NodeProperties::GetValueInput(node, 0);
     32   for (Node* effect = NodeProperties::GetEffectInput(node);;
     33        effect = NodeProperties::GetEffectInput(effect)) {
     34     switch (effect->opcode()) {
     35       case IrOpcode::kLoadField: {
     36         if (object == NodeProperties::GetValueInput(effect, 0) &&
     37             access == FieldAccessOf(effect->op())) {
     38           Node* const value = effect;
     39           ReplaceWithValue(node, value);
     40           return Replace(value);
     41         }
     42         break;
     43       }
     44       case IrOpcode::kStoreField: {
     45         if (access == FieldAccessOf(effect->op())) {
     46           if (object == NodeProperties::GetValueInput(effect, 0)) {
     47             Node* const value = NodeProperties::GetValueInput(effect, 1);
     48             ReplaceWithValue(node, value);
     49             return Replace(value);
     50           }
     51           // TODO(turbofan): Alias analysis to the rescue?
     52           return NoChange();
     53         }
     54         break;
     55       }
     56       case IrOpcode::kBeginRegion:
     57       case IrOpcode::kStoreBuffer:
     58       case IrOpcode::kStoreElement: {
     59         // These can never interfere with field loads.
     60         break;
     61       }
     62       case IrOpcode::kFinishRegion: {
     63         // "Look through" FinishRegion nodes to make LoadElimination capable
     64         // of looking into atomic regions.
     65         if (object == effect) object = NodeProperties::GetValueInput(effect, 0);
     66         break;
     67       }
     68       case IrOpcode::kAllocate: {
     69         // Allocations don't interfere with field loads. In case we see the
     70         // actual allocation for the {object} we can abort.
     71         if (object == effect) return NoChange();
     72         break;
     73       }
     74       default: {
     75         if (!effect->op()->HasProperty(Operator::kNoWrite) ||
     76             effect->op()->EffectInputCount() != 1) {
     77           return NoChange();
     78         }
     79         break;
     80       }
     81     }
     82   }
     83   UNREACHABLE();
     84   return NoChange();
     85 }
     86 
     87 }  // namespace compiler
     88 }  // namespace internal
     89 }  // namespace v8
     90