From dbcd0e925af09166501e68b5ae7708a0a06fbfe9 Mon Sep 17 00:00:00 2001 From: "titzer@chromium.org" Date: Fri, 3 May 2013 12:21:16 +0000 Subject: [PATCH] Remove HLoadElements instruction and replace with use of more general HLoadNamedField. This removes the need for both the hydrogen and lithium instructions and allows both kinds of loads to be GVN'd. Review URL: https://codereview.chromium.org/14556020 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14542 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-arm.cc | 6 ------ src/arm/lithium-arm.h | 13 ------------- src/arm/lithium-codegen-arm.cc | 34 ---------------------------------- src/code-stubs-hydrogen.cc | 6 ++---- src/hydrogen-instructions.cc | 9 --------- src/hydrogen-instructions.h | 34 ---------------------------------- src/hydrogen.cc | 28 +++++++++++++++++----------- src/hydrogen.h | 2 ++ src/ia32/lithium-codegen-ia32.cc | 35 ----------------------------------- src/ia32/lithium-ia32.cc | 6 ------ src/ia32/lithium-ia32.h | 13 ------------- src/mips/lithium-codegen-mips.cc | 32 -------------------------------- src/mips/lithium-mips.cc | 6 ------ src/mips/lithium-mips.h | 13 ------------- src/x64/lithium-codegen-x64.cc | 35 ----------------------------------- src/x64/lithium-x64.cc | 6 ------ src/x64/lithium-x64.h | 13 ------------- 17 files changed, 21 insertions(+), 270 deletions(-) diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 0d84ef3..772a2cf 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -2155,12 +2155,6 @@ LInstruction* LChunkBuilder::DoLoadFunctionPrototype( } -LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { - LOperand* input = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new(zone()) LLoadElements(input)); -} - - LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( HLoadExternalArrayPointer* instr) { LOperand* input = UseRegisterAtStart(instr->value()); diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 11675e9..116d576 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -122,7 +122,6 @@ class LCodeGen; V(Label) \ V(LazyBailout) \ V(LoadContextSlot) \ - V(LoadElements) \ V(LoadExternalArrayPointer) \ V(LoadFunctionPrototype) \ V(LoadGlobalCell) \ @@ -1574,18 +1573,6 @@ class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> { }; -class LLoadElements: public LTemplateInstruction<1, 1, 0> { - public: - explicit LLoadElements(LOperand* object) { - inputs_[0] = object; - } - - LOperand* object() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements") -}; - - class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> { public: explicit LLoadExternalArrayPointer(LOperand* object) { diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 24ebbc5..8b3fc94 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -3227,40 +3227,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { } -void LCodeGen::DoLoadElements(LLoadElements* instr) { - Register result = ToRegister(instr->result()); - Register input = ToRegister(instr->object()); - Register scratch = scratch0(); - - __ ldr(result, FieldMemOperand(input, JSObject::kElementsOffset)); - if (FLAG_debug_code) { - Label done, fail; - __ ldr(scratch, FieldMemOperand(result, HeapObject::kMapOffset)); - __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); - __ cmp(scratch, ip); - __ b(eq, &done); - __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); - __ cmp(scratch, ip); - __ b(eq, &done); - // |scratch| still contains |input|'s map. - __ ldr(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); - __ ubfx(scratch, scratch, Map::kElementsKindShift, - Map::kElementsKindBitCount); - __ cmp(scratch, Operand(GetInitialFastElementsKind())); - __ b(lt, &fail); - __ cmp(scratch, Operand(TERMINAL_FAST_ELEMENTS_KIND)); - __ b(le, &done); - __ cmp(scratch, Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); - __ b(lt, &fail); - __ cmp(scratch, Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); - __ b(le, &done); - __ bind(&fail); - __ Abort("Check for fast or external elements failed."); - __ bind(&done); - } -} - - void LCodeGen::DoLoadExternalArrayPointer( LLoadExternalArrayPointer* instr) { Register to_reg = ToRegister(instr->result()); diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 471e2ad..dbe41cb 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -291,8 +291,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { checker.Then(); if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) { - HValue* elements = - AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); + HValue* elements = AddLoadElements(boilerplate); IfBuilder if_fixed_cow(this); if_fixed_cow.IfCompareMap(elements, factory->fixed_cow_array_map()); @@ -484,8 +483,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { if_builder.Else(); - HInstruction* elements = - AddInstruction(new(zone) HLoadElements(js_array, js_array)); + HInstruction* elements = AddLoadElements(js_array); HInstruction* elements_length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 5a4a8d5..fc57aa8 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1601,15 +1601,6 @@ void HCheckMaps::SetSideEffectDominator(GVNFlag side_effect, } -void HLoadElements::PrintDataTo(StringStream* stream) { - value()->PrintNameTo(stream); - if (HasTypeCheck()) { - stream->Add(" "); - typecheck()->PrintNameTo(stream); - } -} - - void HCheckMaps::PrintDataTo(StringStream* stream) { value()->PrintNameTo(stream); stream->Add(" [%p", *map_set()->first()); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 6912ceb..decc627 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -135,7 +135,6 @@ class LChunkBuilder; V(IsUndetectableAndBranch) \ V(LeaveInlined) \ V(LoadContextSlot) \ - V(LoadElements) \ V(LoadExternalArrayPointer) \ V(LoadFunctionPrototype) \ V(LoadGlobalCell) \ @@ -2585,39 +2584,6 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { }; -class HLoadElements: public HTemplateInstruction<2> { - public: - HLoadElements(HValue* value, HValue* typecheck) { - SetOperandAt(0, value); - SetOperandAt(1, typecheck != NULL ? typecheck : value); - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - SetGVNFlag(kDependsOnElementsPointer); - } - - HValue* value() { return OperandAt(0); } - HValue* typecheck() { - ASSERT(HasTypeCheck()); - return OperandAt(1); - } - bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } - - virtual void PrintDataTo(StringStream* stream); - - virtual Representation RequiredInputRepresentation(int index) { - return Representation::Tagged(); - } - - DECLARE_CONCRETE_INSTRUCTION(LoadElements) - - protected: - virtual bool DataEquals(HValue* other) { return true; } - - private: - virtual bool IsDeletable() const { return true; } -}; - - class HLoadExternalArrayPointer: public HUnaryOperation { public: explicit HLoadExternalArrayPointer(HValue* value) diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 2b62e2d..1b02a62 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -1271,8 +1271,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( } bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); bool fast_elements = IsFastObjectElementsKind(elements_kind); - HValue* elements = - AddInstruction(new(zone) HLoadElements(object, mapcheck)); + HValue* elements = AddLoadElements(object, mapcheck); if (is_store && (fast_elements || fast_smi_only_elements) && store_mode != STORE_NO_TRANSITION_HANDLE_COW) { HCheckMaps* check_cow_map = HCheckMaps::New( @@ -1521,6 +1520,18 @@ HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, } +HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, + HValue* typecheck) { + HLoadNamedField* instr = new(zone()) HLoadNamedField(object, true, + Representation::Tagged(), JSObject::kElementsOffset, typecheck); + AddInstruction(instr); + instr->SetGVNFlag(kDependsOnElementsPointer); + instr->ClearGVNFlag(kDependsOnMaps); + instr->ClearGVNFlag(kDependsOnInobjectFields); + return instr; +} + + HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, HValue* old_capacity) { Zone* zone = this->zone(); @@ -1744,8 +1755,7 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, if (length > 0) { // Get hold of the elements array of the boilerplate and setup the // elements pointer in the resulting object. - HValue* boilerplate_elements = - AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); + HValue* boilerplate_elements = AddLoadElements(boilerplate); HValue* object_elements = AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); AddInstruction(new(zone) HStoreNamedField(object, @@ -6876,7 +6886,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { // of the property values and is the value of the entire expression. Push(literal); - HLoadElements* elements = NULL; + HInstruction* elements = NULL; for (int i = 0; i < length; i++) { Expression* subexpr = subexprs->at(i); @@ -6888,10 +6898,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { HValue* value = Pop(); if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); - // Pass in literal as dummy depedency, since the receiver always has - // elements. - elements = new(zone()) HLoadElements(literal, literal); - AddInstruction(elements); + elements = AddLoadElements(literal); HValue* key = AddInstruction( new(zone()) HConstant(Handle(Smi::FromInt(i), isolate()), @@ -8006,8 +8013,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( HInstruction* elements_kind_instr = AddInstruction(new(zone()) HElementsKind(object)); - HInstruction* elements = - AddInstruction(new(zone()) HLoadElements(object, checkspec)); + HInstruction* elements = AddLoadElements(object, checkspec); HLoadExternalArrayPointer* external_elements = NULL; HInstruction* checked_key = NULL; diff --git a/src/hydrogen.h b/src/hydrogen.h index ab721bd..8df7a29 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -1025,6 +1025,8 @@ class HGraphBuilder { HInstruction* BuildStoreMap(HValue* object, HValue* map); HInstruction* BuildStoreMap(HValue* object, Handle map); + HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck = NULL); + class IfBuilder { public: explicit IfBuilder(HGraphBuilder* builder, diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 13f17fd..449ed3e 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -3166,41 +3166,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { } -void LCodeGen::DoLoadElements(LLoadElements* instr) { - Register result = ToRegister(instr->result()); - Register input = ToRegister(instr->object()); - __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); - if (FLAG_debug_code) { - Label done, ok, fail; - __ cmp(FieldOperand(result, HeapObject::kMapOffset), - Immediate(factory()->fixed_array_map())); - __ j(equal, &done, Label::kNear); - __ cmp(FieldOperand(result, HeapObject::kMapOffset), - Immediate(factory()->fixed_cow_array_map())); - __ j(equal, &done, Label::kNear); - Register temp((result.is(eax)) ? ebx : eax); - __ push(temp); - __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); - __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset)); - __ and_(temp, Map::kElementsKindMask); - __ shr(temp, Map::kElementsKindShift); - __ cmp(temp, GetInitialFastElementsKind()); - __ j(less, &fail, Label::kNear); - __ cmp(temp, TERMINAL_FAST_ELEMENTS_KIND); - __ j(less_equal, &ok, Label::kNear); - __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); - __ j(less, &fail, Label::kNear); - __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); - __ j(less_equal, &ok, Label::kNear); - __ bind(&fail); - __ Abort("Check for fast or external elements failed."); - __ bind(&ok); - __ pop(temp); - __ bind(&done); - } -} - - void LCodeGen::DoLoadExternalArrayPointer( LLoadExternalArrayPointer* instr) { Register result = ToRegister(instr->result()); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 371c16c..1edbf41 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -2213,12 +2213,6 @@ LInstruction* LChunkBuilder::DoLoadFunctionPrototype( } -LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { - LOperand* input = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new(zone()) LLoadElements(input)); -} - - LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( HLoadExternalArrayPointer* instr) { LOperand* input = UseRegisterAtStart(instr->value()); diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 490b780..062744a 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -117,7 +117,6 @@ class LCodeGen; V(Label) \ V(LazyBailout) \ V(LoadContextSlot) \ - V(LoadElements) \ V(LoadExternalArrayPointer) \ V(LoadFunctionPrototype) \ V(LoadGlobalCell) \ @@ -1552,18 +1551,6 @@ class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 1> { }; -class LLoadElements: public LTemplateInstruction<1, 1, 0> { - public: - explicit LLoadElements(LOperand* object) { - inputs_[0] = object; - } - - LOperand* object() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements") -}; - - class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> { public: explicit LLoadExternalArrayPointer(LOperand* object) { diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index c502707..b933459 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -2857,38 +2857,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { } -void LCodeGen::DoLoadElements(LLoadElements* instr) { - Register result = ToRegister(instr->result()); - Register input = ToRegister(instr->object()); - Register scratch = scratch0(); - - __ lw(result, FieldMemOperand(input, JSObject::kElementsOffset)); - if (FLAG_debug_code) { - Label done, fail; - __ lw(scratch, FieldMemOperand(result, HeapObject::kMapOffset)); - __ LoadRoot(at, Heap::kFixedArrayMapRootIndex); - __ Branch(USE_DELAY_SLOT, &done, eq, scratch, Operand(at)); - __ LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex); // In the delay slot. - __ Branch(&done, eq, scratch, Operand(at)); - // |scratch| still contains |input|'s map. - __ lbu(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); - __ Ext(scratch, scratch, Map::kElementsKindShift, - Map::kElementsKindBitCount); - __ Branch(&fail, lt, scratch, - Operand(GetInitialFastElementsKind())); - __ Branch(&done, le, scratch, - Operand(TERMINAL_FAST_ELEMENTS_KIND)); - __ Branch(&fail, lt, scratch, - Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); - __ Branch(&done, le, scratch, - Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); - __ bind(&fail); - __ Abort("Check for fast or external elements failed."); - __ bind(&done); - } -} - - void LCodeGen::DoLoadExternalArrayPointer( LLoadExternalArrayPointer* instr) { Register to_reg = ToRegister(instr->result()); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 79817c3..11c620b 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -2029,12 +2029,6 @@ LInstruction* LChunkBuilder::DoLoadFunctionPrototype( } -LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { - LOperand* input = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new(zone()) LLoadElements(input)); -} - - LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( HLoadExternalArrayPointer* instr) { LOperand* input = UseRegisterAtStart(instr->value()); diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index 8b46e6f..bb8c993 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -122,7 +122,6 @@ class LCodeGen; V(Label) \ V(LazyBailout) \ V(LoadContextSlot) \ - V(LoadElements) \ V(LoadExternalArrayPointer) \ V(LoadFunctionPrototype) \ V(LoadGlobalCell) \ @@ -1521,18 +1520,6 @@ class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> { }; -class LLoadElements: public LTemplateInstruction<1, 1, 0> { - public: - explicit LLoadElements(LOperand* object) { - inputs_[0] = object; - } - - LOperand* object() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements") -}; - - class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> { public: explicit LLoadExternalArrayPointer(LOperand* object) { diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 7ced99c..3b87369 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -2854,41 +2854,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { } -void LCodeGen::DoLoadElements(LLoadElements* instr) { - Register result = ToRegister(instr->result()); - Register input = ToRegister(instr->object()); - __ movq(result, FieldOperand(input, JSObject::kElementsOffset)); - if (FLAG_debug_code) { - Label done, ok, fail; - __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), - Heap::kFixedArrayMapRootIndex); - __ j(equal, &done, Label::kNear); - __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), - Heap::kFixedCOWArrayMapRootIndex); - __ j(equal, &done, Label::kNear); - Register temp((result.is(rax)) ? rbx : rax); - __ push(temp); - __ movq(temp, FieldOperand(result, HeapObject::kMapOffset)); - __ movzxbq(temp, FieldOperand(temp, Map::kBitField2Offset)); - __ and_(temp, Immediate(Map::kElementsKindMask)); - __ shr(temp, Immediate(Map::kElementsKindShift)); - __ cmpl(temp, Immediate(GetInitialFastElementsKind())); - __ j(less, &fail, Label::kNear); - __ cmpl(temp, Immediate(TERMINAL_FAST_ELEMENTS_KIND)); - __ j(less_equal, &ok, Label::kNear); - __ cmpl(temp, Immediate(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); - __ j(less, &fail, Label::kNear); - __ cmpl(temp, Immediate(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); - __ j(less_equal, &ok, Label::kNear); - __ bind(&fail); - __ Abort("Check for fast or external elements failed"); - __ bind(&ok); - __ pop(temp); - __ bind(&done); - } -} - - void LCodeGen::DoLoadExternalArrayPointer( LLoadExternalArrayPointer* instr) { Register result = ToRegister(instr->result()); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index d75d1b0..a6f0466 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -2065,12 +2065,6 @@ LInstruction* LChunkBuilder::DoLoadFunctionPrototype( } -LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { - LOperand* input = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new(zone()) LLoadElements(input)); -} - - LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( HLoadExternalArrayPointer* instr) { LOperand* input = UseRegisterAtStart(instr->value()); diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index f288391..ccfb5b1 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -123,7 +123,6 @@ class LCodeGen; V(Label) \ V(LazyBailout) \ V(LoadContextSlot) \ - V(LoadElements) \ V(LoadExternalArrayPointer) \ V(LoadFunctionPrototype) \ V(LoadGlobalCell) \ @@ -1514,18 +1513,6 @@ class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> { }; -class LLoadElements: public LTemplateInstruction<1, 1, 0> { - public: - explicit LLoadElements(LOperand* object) { - inputs_[0] = object; - } - - LOperand* object() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements") -}; - - class LLoadExternalArrayPointer: public LTemplateInstruction<1, 1, 0> { public: explicit LLoadExternalArrayPointer(LOperand* object) { -- 2.7.4