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 {...@@ -2064,7 +2064,6 @@ struct IrInstructionMemset {
2064 IrInstruction *dest_ptr;2064 IrInstruction *dest_ptr;
2065 IrInstruction *byte;2065 IrInstruction *byte;
2066 IrInstruction *count;2066 IrInstruction *count;
2067 bool is_volatile;
2068};2067};
20692068
2070struct IrInstructionMemcpy {2069struct IrInstructionMemcpy {
...@@ -2073,7 +2072,6 @@ struct IrInstructionMemcpy {...@@ -2073,7 +2072,6 @@ struct IrInstructionMemcpy {
2073 IrInstruction *dest_ptr;2072 IrInstruction *dest_ptr;
2074 IrInstruction *src_ptr;2073 IrInstruction *src_ptr;
2075 IrInstruction *count;2074 IrInstruction *count;
2076 bool is_volatile;
2077};2075};
20782076
2079struct IrInstructionSlice {2077struct IrInstructionSlice {
src/analyze.cpp+8-5
...@@ -2036,7 +2036,8 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -2036,7 +2036,8 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
2036 // pointer const2036 // pointer const
2037 if (expected_type->id == TypeTableEntryIdPointer &&2037 if (expected_type->id == TypeTableEntryIdPointer &&
2038 actual_type->id == TypeTableEntryIdPointer &&2038 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))
2040 {2041 {
2041 return types_match_const_cast_only(expected_type->data.pointer.child_type,2042 return types_match_const_cast_only(expected_type->data.pointer.child_type,
2042 actual_type->data.pointer.child_type);2043 actual_type->data.pointer.child_type);
...@@ -2047,12 +2048,14 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -2047,12 +2048,14 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
2047 actual_type->id == TypeTableEntryIdStruct &&2048 actual_type->id == TypeTableEntryIdStruct &&
2048 expected_type->data.structure.is_slice &&2049 expected_type->data.structure.is_slice &&
2049 actual_type->data.structure.is_slice &&2050 actual_type->data.structure.is_slice &&
2050 (!actual_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 ||
2051 expected_type->data.structure.fields[0].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))
2052 {2055 {
2053 return types_match_const_cast_only(2056 return types_match_const_cast_only(
2054 expected_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,
2055 actual_type->data.structure.fields[0].type_entry->data.pointer.child_type);2058 actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type);
2056 }2059 }
20572060
2058 // maybe2061 // maybe
src/codegen.cpp+11-2
...@@ -1804,7 +1804,10 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns...@@ -1804,7 +1804,10 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
18041804
1805 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");1805 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 ?
1808 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());1811 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());
18091812
1810 LLVMValueRef params[] = {1813 LLVMValueRef params[] = {
...@@ -1829,7 +1832,13 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns...@@ -1829,7 +1832,13 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
1829 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");1832 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
1830 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, "");1833 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) ?
1833 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());1842 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());
18341843
1835 LLVMValueRef params[] = {1844 LLVMValueRef params[] = {
src/ir.cpp+15-4
...@@ -11193,9 +11193,13 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi...@@ -11193,9 +11193,13 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi
11193 if (count_value->value.type->id == TypeTableEntryIdInvalid)11193 if (count_value->value.type->id == TypeTableEntryIdInvalid)
11194 return ira->codegen->builtin_types.entry_invalid;11194 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
11196 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;11200 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
11197 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;11201 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
11200 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr);11204 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr);
11201 if (casted_dest_ptr->value.type->id == TypeTableEntryIdInvalid)11205 if (casted_dest_ptr->value.type->id == TypeTableEntryIdInvalid)
...@@ -11262,10 +11266,17 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi...@@ -11262,10 +11266,17 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
11262 if (count_value->value.type->id == TypeTableEntryIdInvalid)11266 if (count_value->value.type->id == TypeTableEntryIdInvalid)
11263 return ira->codegen->builtin_types.entry_invalid;11267 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
11265 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;11276 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
11266 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;11277 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
11267 TypeTableEntry *u8_ptr_mut = get_pointer_to_type(ira->codegen, u8, false);11278 TypeTableEntry *u8_ptr_mut = get_pointer_to_type_volatile(ira->codegen, u8, false, dest_is_volatile);
11268 TypeTableEntry *u8_ptr_const = get_pointer_to_type(ira->codegen, u8, true);11279 TypeTableEntry *u8_ptr_const = get_pointer_to_type_volatile(ira->codegen, u8, true, src_is_volatile);
1126911280
11270 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut);11281 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut);
11271 if (casted_dest_ptr->value.type->id == TypeTableEntryIdInvalid)11282 if (casted_dest_ptr->value.type->id == TypeTableEntryIdInvalid)
...@@ -11888,7 +11899,7 @@ static TypeTableEntry *ir_analyze_instruction_can_implicit_cast(IrAnalyze *ira,...@@ -11888,7 +11899,7 @@ static TypeTableEntry *ir_analyze_instruction_can_implicit_cast(IrAnalyze *ira,
11888 if (result == ImplicitCastMatchResultReportedError) {11899 if (result == ImplicitCastMatchResultReportedError) {
11889 zig_panic("TODO refactor implicit cast tester to return bool without reporting errors");11900 zig_panic("TODO refactor implicit cast tester to return bool without reporting errors");
11890 }11901 }
11891 11902
11892 // TODO in order to known depends_on_compile_var we have to known if the type of the target11903 // TODO in order to known depends_on_compile_var we have to known if the type of the target
11893 // depends on a compile var11904 // depends on a compile var
11894 bool depends_on_compile_var = true;11905 bool depends_on_compile_var = true;