remove the scope parameter of setFloatMode

also document that scopes inherit this value. See #367
See #1283
master
Andrew Kelley 2018-09-13 15:46:34 -04:00
parent 9ac9633b10
commit 7c3636aaa3
No known key found for this signature in database
GPG Key ID: 4E7CD66038A4D47C
6 changed files with 47 additions and 63 deletions

View File

@ -734,7 +734,7 @@ export fn foo_strict(x: f64) f64 {
}
export fn foo_optimized(x: f64) f64 {
@setFloatMode(this, builtin.FloatMode.Optimized);
@setFloatMode(builtin.FloatMode.Optimized);
return x + big - big;
}
{#code_end#}
@ -6030,17 +6030,20 @@ test "foo" {
{#see_also|comptime#}
{#header_close#}
{#header_open|@setFloatMode#}
<pre><code class="zig">@setFloatMode(scope, mode: @import("builtin").FloatMode)</code></pre>
<pre><code class="zig">@setFloatMode(mode: @import("builtin").FloatMode)</code></pre>
<p>
Sets the floating point mode for a given scope. Possible values are:
Sets the floating point mode of the current scope. Possible values are:
</p>
{#code_begin|syntax#}
pub const FloatMode = enum {
Optimized,
Strict,
Optimized,
};
{#code_end#}
<ul>
<li>
<code>Strict</code> (default) - Floating point operations follow strict IEEE compliance.
</li>
<li>
<code>Optimized</code> - Floating point operations may do all of the following:
<ul>
@ -6053,10 +6056,11 @@ pub const FloatMode = enum {
</ul>
This is equivalent to <code>-ffast-math</code> in GCC.
</li>
<li>
<code>Strict</code> (default) - Floating point operations follow strict IEEE compliance.
</li>
</ul>
<p>
The floating point mode is inherited by child scopes, and can be overridden in any scope.
You can set the floating point mode in a struct or module scope by using a comptime block.
</p>
{#see_also|Floating Point Operations#}
{#header_close#}
{#header_open|@setGlobalLinkage#}

View File

@ -3287,8 +3287,8 @@ static const size_t stack_trace_ptr_count = 30;
enum FloatMode {
FloatModeOptimized,
FloatModeStrict,
FloatModeOptimized,
};
enum FnWalkId {

View File

@ -6729,7 +6729,7 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1);
create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1);
create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1);
create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);
create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2);
@ -7115,11 +7115,11 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
{
buf_appendf(contents,
"pub const FloatMode = enum {\n"
" Optimized,\n"
" Strict,\n"
" Optimized,\n"
"};\n\n");
assert(FloatModeOptimized == 0);
assert(FloatModeStrict == 1);
assert(FloatModeStrict == 0);
assert(FloatModeOptimized == 1);
}
{
buf_appendf(contents,
@ -7127,8 +7127,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" Big,\n"
" Little,\n"
"};\n\n");
assert(FloatModeOptimized == 0);
assert(FloatModeStrict == 1);
//assert(EndianBig == 0);
//assert(EndianLittle == 1);
}
{
const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";

View File

@ -1577,13 +1577,11 @@ static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope,
}
static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *scope_value, IrInstruction *mode_value)
IrInstruction *mode_value)
{
IrInstructionSetFloatMode *instruction = ir_build_instruction<IrInstructionSetFloatMode>(irb, scope, source_node);
instruction->scope_value = scope_value;
instruction->mode_value = mode_value;
ir_ref_instruction(scope_value, irb->current_basic_block);
ir_ref_instruction(mode_value, irb->current_basic_block);
return &instruction->base;
@ -3959,12 +3957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
if (arg0_value == irb->codegen->invalid_instruction)
return arg0_value;
AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
if (arg1_value == irb->codegen->invalid_instruction)
return arg1_value;
IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value, arg1_value);
IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value);
return ir_lval_wrap(irb, scope, set_float_mode, lval);
}
case BuiltinFnIdSizeof:
@ -15379,6 +15372,7 @@ static ZigType *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSet
ir_build_const_from(ira, &instruction->base);
return ira->codegen->builtin_types.entry_void;
}
static ZigType *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira,
IrInstructionSetRuntimeSafety *set_runtime_safety_instruction)
{
@ -15439,14 +15433,6 @@ static ZigType *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira,
static ZigType *ir_analyze_instruction_set_float_mode(IrAnalyze *ira,
IrInstructionSetFloatMode *instruction)
{
IrInstruction *target_instruction = instruction->scope_value->other;
ZigType *target_type = target_instruction->value.type;
if (type_is_invalid(target_type))
return ira->codegen->builtin_types.entry_invalid;
ConstExprValue *target_val = ir_resolve_const(ira, target_instruction, UndefBad);
if (!target_val)
return ira->codegen->builtin_types.entry_invalid;
if (ira->new_irb.exec->is_inline) {
// ignore setFloatMode when running functions at compile time
ir_build_const_from(ira, &instruction->base);
@ -15455,40 +15441,34 @@ static ZigType *ir_analyze_instruction_set_float_mode(IrAnalyze *ira,
bool *fast_math_on_ptr;
AstNode **fast_math_set_node_ptr;
if (target_type->id == ZigTypeIdBlock) {
ScopeBlock *block_scope = (ScopeBlock *)target_val->data.x_block;
fast_math_on_ptr = &block_scope->fast_math_on;
fast_math_set_node_ptr = &block_scope->fast_math_set_node;
} else if (target_type->id == ZigTypeIdFn) {
assert(target_val->data.x_ptr.special == ConstPtrSpecialFunction);
ZigFn *target_fn = target_val->data.x_ptr.data.fn.fn_entry;
assert(target_fn->def_scope);
fast_math_on_ptr = &target_fn->def_scope->fast_math_on;
fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node;
} else if (target_type->id == ZigTypeIdMetaType) {
ScopeDecls *decls_scope;
ZigType *type_arg = target_val->data.x_type;
if (type_arg->id == ZigTypeIdStruct) {
decls_scope = type_arg->data.structure.decls_scope;
} else if (type_arg->id == ZigTypeIdEnum) {
decls_scope = type_arg->data.enumeration.decls_scope;
} else if (type_arg->id == ZigTypeIdUnion) {
decls_scope = type_arg->data.unionation.decls_scope;
Scope *scope = instruction->base.scope;
while (scope != nullptr) {
if (scope->id == ScopeIdBlock) {
ScopeBlock *block_scope = (ScopeBlock *)scope;
fast_math_on_ptr = &block_scope->fast_math_on;
fast_math_set_node_ptr = &block_scope->fast_math_set_node;
break;
} else if (scope->id == ScopeIdFnDef) {
ScopeFnDef *def_scope = (ScopeFnDef *)scope;
ZigFn *target_fn = def_scope->fn_entry;
assert(target_fn->def_scope != nullptr);
fast_math_on_ptr = &target_fn->def_scope->fast_math_on;
fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node;
break;
} else if (scope->id == ScopeIdDecls) {
ScopeDecls *decls_scope = (ScopeDecls *)scope;
fast_math_on_ptr = &decls_scope->fast_math_on;
fast_math_set_node_ptr = &decls_scope->fast_math_set_node;
break;
} else {
ir_add_error_node(ira, target_instruction->source_node,
buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));
return ira->codegen->builtin_types.entry_invalid;
scope = scope->parent;
continue;
}
fast_math_on_ptr = &decls_scope->fast_math_on;
fast_math_set_node_ptr = &decls_scope->fast_math_set_node;
} else {
ir_add_error_node(ira, target_instruction->source_node,
buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&target_type->name)));
return ira->codegen->builtin_types.entry_invalid;
}
assert(scope != nullptr);
IrInstruction *float_mode_value = instruction->mode_value->other;
FloatMode float_mode_scalar;
if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar))
return ira->codegen->builtin_types.entry_invalid;

View File

@ -275,7 +275,7 @@ test "eval @setFloatMode at compile-time" {
}
fn fnWithFloatMode() f32 {
@setFloatMode(this, builtin.FloatMode.Strict);
@setFloatMode(builtin.FloatMode.Strict);
return 1234.0;
}

View File

@ -3996,8 +3996,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"@setFloatMode twice for same scope",
\\export fn foo() void {
\\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
\\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
\\ @setFloatMode(@import("builtin").FloatMode.Optimized);
\\ @setFloatMode(@import("builtin").FloatMode.Optimized);
\\}
,
".tmp_source.zig:3:5: error: float mode set twice for same scope",