authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-04 22:12:06-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-04 22:12:06-05:00
logb840184bb09b9d5e4272f848dcaa7c4973dfdcd5
treefb0be751a985d6b52c173da49692171e61e935e2
parent419e75eb2313b4910921185211201317cbbb400c

memcpy and memset builtins support volatile pointers

See #238

4 files changed, 34 insertions(+), 13 deletions(-)

src/all_types.hpp-2
......@@ -2064,7 +2064,6 @@ struct IrInstructionMemset {
20642064 IrInstruction *dest_ptr;
20652065 IrInstruction *byte;
20662066 IrInstruction *count;
2067 bool is_volatile;
20682067};
20692068
20702069struct IrInstructionMemcpy {
......@@ -2073,7 +2072,6 @@ struct IrInstructionMemcpy {
20732072 IrInstruction *dest_ptr;
20742073 IrInstruction *src_ptr;
20752074 IrInstruction *count;
2076 bool is_volatile;
20772075};
20782076
20792077struct IrInstructionSlice {
src/analyze.cpp+8-5
......@@ -2036,7 +2036,8 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
20362036 // pointer const
20372037 if (expected_type->id == TypeTableEntryIdPointer &&
20382038 actual_type->id == TypeTableEntryIdPointer &&
2039 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const))
2039 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const) &&
2040 (!actual_type->data.pointer.is_volatile || expected_type->data.pointer.is_volatile))
20402041 {
20412042 return types_match_const_cast_only(expected_type->data.pointer.child_type,
20422043 actual_type->data.pointer.child_type);
......@@ -2047,12 +2048,14 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
20472048 actual_type->id == TypeTableEntryIdStruct &&
20482049 expected_type->data.structure.is_slice &&
20492050 actual_type->data.structure.is_slice &&
2050 (!actual_type->data.structure.fields[0].type_entry->data.pointer.is_const ||
2051 expected_type->data.structure.fields[0].type_entry->data.pointer.is_const))
2051 (!actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
2052 expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const) &&
2053 (!actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_volatile ||
2054 expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_volatile))
20522055 {
20532056 return types_match_const_cast_only(
2054 expected_type->data.structure.fields[0].type_entry->data.pointer.child_type,
2055 actual_type->data.structure.fields[0].type_entry->data.pointer.child_type);
2057 expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
2058 actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type);
20562059 }
20572060
20582061 // maybe
src/codegen.cpp+11-2
......@@ -1804,7 +1804,10 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
18041804
18051805 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
18061806
1807 LLVMValueRef is_volatile = instruction->is_volatile ?
1807 TypeTableEntry *ptr_type = get_underlying_type(instruction->dest_ptr->value.type);
1808 assert(ptr_type->id == TypeTableEntryIdPointer);
1809
1810 LLVMValueRef is_volatile = ptr_type->data.pointer.is_volatile ?
18081811 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());
18091812
18101813 LLVMValueRef params[] = {
......@@ -1829,7 +1832,13 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
18291832 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
18301833 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, "");
18311834
1832 LLVMValueRef is_volatile = instruction->is_volatile ?
1835 TypeTableEntry *dest_ptr_type = get_underlying_type(instruction->dest_ptr->value.type);
1836 TypeTableEntry *src_ptr_type = get_underlying_type(instruction->src_ptr->value.type);
1837
1838 assert(dest_ptr_type->id == TypeTableEntryIdPointer);
1839 assert(src_ptr_type->id == TypeTableEntryIdPointer);
1840
1841 LLVMValueRef is_volatile = (dest_ptr_type->data.pointer.is_volatile || src_ptr_type->data.pointer.is_volatile) ?
18331842 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());
18341843
18351844 LLVMValueRef params[] = {
src/ir.cpp+15-4
......@@ -11193,9 +11193,13 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi
1119311193 if (count_value->value.type->id == TypeTableEntryIdInvalid)
1119411194 return ira->codegen->builtin_types.entry_invalid;
1119511195
11196 TypeTableEntry *dest_uncasted_type = get_underlying_type(dest_ptr->value.type);
11197 bool dest_is_volatile = (dest_uncasted_type->id == TypeTableEntryIdPointer) &&
11198 dest_uncasted_type->data.pointer.is_volatile;
11199
1119611200 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
1119711201 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
11198 TypeTableEntry *u8_ptr = get_pointer_to_type(ira->codegen, u8, false);
11202 TypeTableEntry *u8_ptr = get_pointer_to_type_volatile(ira->codegen, u8, false, dest_is_volatile);
1119911203
1120011204 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr);
1120111205 if (casted_dest_ptr->value.type->id == TypeTableEntryIdInvalid)
......@@ -11262,10 +11266,17 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
1126211266 if (count_value->value.type->id == TypeTableEntryIdInvalid)
1126311267 return ira->codegen->builtin_types.entry_invalid;
1126411268
11269 TypeTableEntry *dest_uncasted_type = get_underlying_type(dest_ptr->value.type);
11270 TypeTableEntry *src_uncasted_type = get_underlying_type(src_ptr->value.type);
11271 bool dest_is_volatile = (dest_uncasted_type->id == TypeTableEntryIdPointer) &&
11272 dest_uncasted_type->data.pointer.is_volatile;
11273 bool src_is_volatile = (src_uncasted_type->id == TypeTableEntryIdPointer) &&
11274 src_uncasted_type->data.pointer.is_volatile;
11275
1126511276 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
1126611277 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
11267 TypeTableEntry *u8_ptr_mut = get_pointer_to_type(ira->codegen, u8, false);
11268 TypeTableEntry *u8_ptr_const = get_pointer_to_type(ira->codegen, u8, true);
11278 TypeTableEntry *u8_ptr_mut = get_pointer_to_type_volatile(ira->codegen, u8, false, dest_is_volatile);
11279 TypeTableEntry *u8_ptr_const = get_pointer_to_type_volatile(ira->codegen, u8, true, src_is_volatile);
1126911280
1127011281 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut);
1127111282 if (casted_dest_ptr->value.type->id == TypeTableEntryIdInvalid)
......@@ -11888,7 +11899,7 @@ static TypeTableEntry *ir_analyze_instruction_can_implicit_cast(IrAnalyze *ira,
1188811899 if (result == ImplicitCastMatchResultReportedError) {
1188911900 zig_panic("TODO refactor implicit cast tester to return bool without reporting errors");
1189011901 }
11891
11902
1189211903 // TODO in order to known depends_on_compile_var we have to known if the type of the target
1189311904 // depends on a compile var
1189411905 bool depends_on_compile_var = true;