diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-11-01 22:57:19 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-11-05 12:11:40 -0500 |
| commit | 70be308c4315c53d42889d568d5731ba227dcf88 (patch) | |
| tree | 181b9f099af8dee8637535adfe87550f0355a2f3 /src/ir.cpp | |
| parent | 76d188551eb3f742c2feb086c8c51c6b0815184d (diff) | |
| download | zig-70be308c4315c53d42889d568d5731ba227dcf88.tar.gz zig-70be308c4315c53d42889d568d5731ba227dcf88.zip | |
implement loading vector elements via runtime index
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index f0f6c0ea7e..8592d033bc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1083,6 +1083,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillEnd *) { return IrInstructionIdSpillEnd; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorExtractElem *) { + return IrInstructionIdVectorExtractElem; +} + template<typename T> static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { const char *name = nullptr; @@ -3419,6 +3423,21 @@ static IrInstruction *ir_build_spill_end(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } +static IrInstruction *ir_build_vector_extract_elem(IrAnalyze *ira, IrInstruction *source_instruction, + IrInstruction *vector, IrInstruction *index) +{ + IrInstructionVectorExtractElem *instruction = ir_build_instruction<IrInstructionVectorExtractElem>( + &ira->new_irb, source_instruction->scope, source_instruction->source_node); + instruction->base.value.type = vector->value.type->data.vector.elem_type; + instruction->vector = vector; + instruction->index = index; + + ir_ref_instruction(vector, ira->new_irb.current_basic_block); + ir_ref_instruction(index, ira->new_irb.current_basic_block); + + return &instruction->base; +} + static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { results[ReturnKindUnconditional] = 0; results[ReturnKindError] = 0; @@ -12965,8 +12984,15 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc // the type information does not contain enough information to actually // perform a dereference. if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { + if (ptr->id == IrInstructionIdElemPtr) { + IrInstructionElemPtr *elem_ptr = (IrInstructionElemPtr *)ptr; + IrInstruction *vector_loaded = ir_get_deref(ira, elem_ptr->array_ptr, + elem_ptr->array_ptr, nullptr); + IrInstruction *elem_index = elem_ptr->elem_index; + return ir_build_vector_extract_elem(ira, source_instruction, vector_loaded, elem_index); + } ir_add_error(ira, ptr, - buf_sprintf("unable to determine element index in order to dereference vector pointer")); + buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr_type->name))); return ira->codegen->invalid_instruction; } @@ -26036,6 +26062,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction case IrInstructionIdFrameSizeGen: case IrInstructionIdAwaitGen: case IrInstructionIdSplatGen: + case IrInstructionIdVectorExtractElem: zig_unreachable(); case IrInstructionIdReturn: @@ -26571,6 +26598,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdAllocaSrc: case IrInstructionIdAllocaGen: case IrInstructionIdSpillEnd: + case IrInstructionIdVectorExtractElem: return false; case IrInstructionIdAsm: |
