aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-11-01 22:57:19 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-11-05 12:11:40 -0500
commit70be308c4315c53d42889d568d5731ba227dcf88 (patch)
tree181b9f099af8dee8637535adfe87550f0355a2f3 /src/ir.cpp
parent76d188551eb3f742c2feb086c8c51c6b0815184d (diff)
downloadzig-70be308c4315c53d42889d568d5731ba227dcf88.tar.gz
zig-70be308c4315c53d42889d568d5731ba227dcf88.zip
implement loading vector elements via runtime index
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp30
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: