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 ~LoadElimination()14LoadElimination::~LoadElimination() {} 15 16 Reduce(Node * node)17Reduction 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 ReduceLoadField(Node * node)28Reduction 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