Skip to content

Commit

Permalink
delete alloca builtin function
Browse files Browse the repository at this point in the history
See #225

introduce os.EnvMap
  • Loading branch information
andrewrk committed Apr 3, 2017
1 parent c400cb4 commit c9ae30d
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 206 deletions.
13 changes: 0 additions & 13 deletions doc/langref.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,19 +295,6 @@ has a terminating null byte.
Built-in functions are prefixed with `@`. Remember that the `comptime` keyword on
a parameter means that the parameter must be known at compile time.

### @alloca(comptime T: type, count: usize) -> []T

Allocates memory in the stack frame of the caller. This temporary space is
automatically freed when the function that called alloca returns to its caller,
just like other stack variables.

When using this function to allocate memory, you should know the upper bound
of `count`. Consider putting a constant array on the stack with the upper bound
instead of using alloca. If you do use alloca it is to save a few bytes off
the memory size given that you didn't actually hit your upper bound.

The allocated memory contents are undefined.

### @typeOf(expression) -> type

This function returns a compile-time constant, which is the type of the
Expand Down
10 changes: 0 additions & 10 deletions src/all_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,6 @@ enum BuiltinFnId {
BuiltinFnIdTruncate,
BuiltinFnIdIntType,
BuiltinFnIdSetDebugSafety,
BuiltinFnIdAlloca,
BuiltinFnIdTypeName,
BuiltinFnIdIsInteger,
BuiltinFnIdIsFloat,
Expand Down Expand Up @@ -1706,7 +1705,6 @@ enum IrInstructionId {
IrInstructionIdTruncate,
IrInstructionIdIntType,
IrInstructionIdBoolNot,
IrInstructionIdAlloca,
IrInstructionIdMemset,
IrInstructionIdMemcpy,
IrInstructionIdSlice,
Expand Down Expand Up @@ -2234,14 +2232,6 @@ struct IrInstructionBoolNot {
IrInstruction *value;
};

struct IrInstructionAlloca {
IrInstruction base;

IrInstruction *type_value;
IrInstruction *count;
LLVMValueRef tmp_ptr;
};

struct IrInstructionMemset {
IrInstruction base;

Expand Down
28 changes: 1 addition & 27 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2190,26 +2190,6 @@ static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrI
}
}

static LLVMValueRef ir_render_alloca(CodeGen *g, IrExecutable *executable, IrInstructionAlloca *instruction) {
TypeTableEntry *slice_type = get_underlying_type(instruction->base.value.type);
TypeTableEntry *ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
LLVMValueRef size_val = ir_llvm_value(g, instruction->count);
LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref, size_val, "");

// TODO in debug mode, initialize all the bytes to 0xaa

// store the freshly allocated pointer in the slice
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, slice_ptr_index, "");
LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr);

// store the size in the len field
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, slice_len_index, "");
LLVMBuildStore(g->builder, size_val, len_field_ptr);

return instruction->tmp_ptr;
}

static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrInstructionMemset *instruction) {
LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);
LLVMValueRef char_val = ir_llvm_value(g, instruction->byte);
Expand Down Expand Up @@ -2548,7 +2528,7 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I
assert(instruction->tmp_ptr);

LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_child_index, "");
assert(child_type == instruction->value->value.type);
// child_type and instruction->value->value.type may differ by constness
gen_assign_raw(g, val_ptr, payload_val, child_type);
LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_null_index, "");
LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr);
Expand Down Expand Up @@ -2796,8 +2776,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_truncate(g, executable, (IrInstructionTruncate *)instruction);
case IrInstructionIdBoolNot:
return ir_render_bool_not(g, executable, (IrInstructionBoolNot *)instruction);
case IrInstructionIdAlloca:
return ir_render_alloca(g, executable, (IrInstructionAlloca *)instruction);
case IrInstructionIdMemset:
return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);
case IrInstructionIdMemcpy:
Expand Down Expand Up @@ -3648,9 +3626,6 @@ static void do_code_gen(CodeGen *g) {
} else if (instruction->id == IrInstructionIdCall) {
IrInstructionCall *call_instruction = (IrInstructionCall *)instruction;
slot = &call_instruction->tmp_ptr;
} else if (instruction->id == IrInstructionIdAlloca) {
IrInstructionAlloca *alloca_instruction = (IrInstructionAlloca *)instruction;
slot = &alloca_instruction->tmp_ptr;
} else if (instruction->id == IrInstructionIdSlice) {
IrInstructionSlice *slice_instruction = (IrInstructionSlice *)instruction;
slot = &slice_instruction->tmp_ptr;
Expand Down Expand Up @@ -4326,7 +4301,6 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
create_builtin_fn(g, BuiltinFnIdIntType, "intType", 2);
create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2);
create_builtin_fn(g, BuiltinFnIdSetGlobalAlign, "setGlobalAlign", 2);
create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
Expand Down
77 changes: 0 additions & 77 deletions src/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) {
return IrInstructionIdBoolNot;
}

static constexpr IrInstructionId ir_instruction_id(IrInstructionAlloca *) {
return IrInstructionIdAlloca;
}

static constexpr IrInstructionId ir_instruction_id(IrInstructionMemset *) {
return IrInstructionIdMemset;
}
Expand Down Expand Up @@ -1668,27 +1664,6 @@ static IrInstruction *ir_build_bool_not_from(IrBuilder *irb, IrInstruction *old_
return new_instruction;
}

static IrInstruction *ir_build_alloca(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *type_value, IrInstruction *count)
{
IrInstructionAlloca *instruction = ir_build_instruction<IrInstructionAlloca>(irb, scope, source_node);
instruction->type_value = type_value;
instruction->count = count;

ir_ref_instruction(type_value, irb->current_basic_block);
ir_ref_instruction(count, irb->current_basic_block);

return &instruction->base;
}

static IrInstruction *ir_build_alloca_from(IrBuilder *irb, IrInstruction *old_instruction,
IrInstruction *type_value, IrInstruction *count)
{
IrInstruction *new_instruction = ir_build_alloca(irb, old_instruction->scope, old_instruction->source_node, type_value, count);
ir_link_new_instruction(new_instruction, old_instruction);
return new_instruction;
}

static IrInstruction *ir_build_memset(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *dest_ptr, IrInstruction *byte, IrInstruction *count)
{
Expand Down Expand Up @@ -2567,14 +2542,6 @@ static IrInstruction *ir_instruction_boolnot_get_dep(IrInstructionBoolNot *instr
}
}

static IrInstruction *ir_instruction_alloca_get_dep(IrInstructionAlloca *instruction, size_t index) {
switch (index) {
case 0: return instruction->type_value;
case 1: return instruction->count;
default: return nullptr;
}
}

static IrInstruction *ir_instruction_memset_get_dep(IrInstructionMemset *instruction, size_t index) {
switch (index) {
case 0: return instruction->dest_ptr;
Expand Down Expand Up @@ -2938,8 +2905,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
return ir_instruction_inttype_get_dep((IrInstructionIntType *) instruction, index);
case IrInstructionIdBoolNot:
return ir_instruction_boolnot_get_dep((IrInstructionBoolNot *) instruction, index);
case IrInstructionIdAlloca:
return ir_instruction_alloca_get_dep((IrInstructionAlloca *) instruction, index);
case IrInstructionIdMemset:
return ir_instruction_memset_get_dep((IrInstructionMemset *) instruction, index);
case IrInstructionIdMemcpy:
Expand Down Expand Up @@ -4100,20 +4065,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo

return ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
}
case BuiltinFnIdAlloca:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
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;

return ir_build_alloca(irb, scope, node, arg0_value, arg1_value);
}
case BuiltinFnIdMemcpy:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
Expand Down Expand Up @@ -11461,31 +11412,6 @@ static TypeTableEntry *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstruc
return bool_type;
}

static TypeTableEntry *ir_analyze_instruction_alloca(IrAnalyze *ira, IrInstructionAlloca *instruction) {
IrInstruction *type_value = instruction->type_value->other;
if (type_is_invalid(type_value->value.type))
return ira->codegen->builtin_types.entry_invalid;

IrInstruction *count_value = instruction->count->other;
if (type_is_invalid(count_value->value.type))
return ira->codegen->builtin_types.entry_invalid;

TypeTableEntry *child_type = ir_resolve_type(ira, type_value);

if (type_requires_comptime(child_type)) {
ir_add_error(ira, type_value,
buf_sprintf("invalid alloca type '%s'", buf_ptr(&child_type->name)));
// TODO if this is a typedecl, add error note showing the declaration of the type decl
return ira->codegen->builtin_types.entry_invalid;
} else {
TypeTableEntry *slice_type = get_slice_type(ira->codegen, child_type, false);
IrInstruction *new_instruction = ir_build_alloca_from(&ira->new_irb, &instruction->base, type_value, count_value);
ir_add_alloca(ira, new_instruction, slice_type);
return slice_type;
}
zig_unreachable();
}

static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemset *instruction) {
IrInstruction *dest_ptr = instruction->dest_ptr->other;
if (type_is_invalid(dest_ptr->value.type))
Expand Down Expand Up @@ -12550,8 +12476,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction);
case IrInstructionIdBoolNot:
return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction);
case IrInstructionIdAlloca:
return ir_analyze_instruction_alloca(ira, (IrInstructionAlloca *)instruction);
case IrInstructionIdMemset:
return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction);
case IrInstructionIdMemcpy:
Expand Down Expand Up @@ -12749,7 +12673,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdTruncate:
case IrInstructionIdIntType:
case IrInstructionIdBoolNot:
case IrInstructionIdAlloca:
case IrInstructionIdSlice:
case IrInstructionIdMemberCount:
case IrInstructionIdAlignOf:
Expand Down
11 changes: 0 additions & 11 deletions src/ir_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,14 +601,6 @@ static void ir_print_truncate(IrPrint *irp, IrInstructionTruncate *instruction)
fprintf(irp->f, ")");
}

static void ir_print_alloca(IrPrint *irp, IrInstructionAlloca *instruction) {
fprintf(irp->f, "@alloca(");
ir_print_other_instruction(irp, instruction->type_value);
fprintf(irp->f, ", ");
ir_print_other_instruction(irp, instruction->count);
fprintf(irp->f, ")");
}

static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) {
fprintf(irp->f, "@intType(");
ir_print_other_instruction(irp, instruction->is_signed);
Expand Down Expand Up @@ -1049,9 +1041,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdTruncate:
ir_print_truncate(irp, (IrInstructionTruncate *)instruction);
break;
case IrInstructionIdAlloca:
ir_print_alloca(irp, (IrInstructionAlloca *)instruction);
break;
case IrInstructionIdIntType:
ir_print_int_type(irp, (IrInstructionIntType *)instruction);
break;
Expand Down
4 changes: 3 additions & 1 deletion std/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub const Builder = struct {
}

pub fn make(self: &Builder, cli_args: []const []const u8) -> %void {
var env_map = %return os.getEnvMap(self.allocator);

var verbose = false;
for (cli_args) |arg| {
if (mem.eql(u8, arg, "--verbose")) {
Expand Down Expand Up @@ -93,7 +95,7 @@ pub const Builder = struct {
}

printInvocation(self.zig_exe, zig_args);
var child = %return os.ChildProcess.spawn(self.zig_exe, zig_args.toSliceConst(), os.environ,
var child = %return os.ChildProcess.spawn(self.zig_exe, zig_args.toSliceConst(), env_map,
StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, self.allocator);
const term = %return child.wait();
switch (term) {
Expand Down
19 changes: 12 additions & 7 deletions std/hash_map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
};

pub const Iterator = struct {
hm: &Self,
hm: &const Self,
// how many items have we returned
count: usize,
// iterator through the entry array
Expand Down Expand Up @@ -99,17 +99,21 @@ pub fn HashMap(comptime K: type, comptime V: type,
}

pub fn get(hm: &Self, key: K) -> ?&Entry {
if (hm.entries.len == 0) {
return null;
}
return hm.internalGet(key);
}

pub fn remove(hm: &Self, key: K) {
pub fn remove(hm: &Self, key: K) -> ?&Entry {
hm.incrementModificationCount();
const start_index = hm.keyToIndex(key);
{var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index; roll_over += 1) {
const index = (start_index + roll_over) % hm.entries.len;
var entry = &hm.entries[index];

assert(entry.used); // key not found
if (!entry.used)
return null;

if (!eql(entry.key, key)) continue;

Expand All @@ -119,18 +123,18 @@ pub fn HashMap(comptime K: type, comptime V: type,
if (!next_entry.used or next_entry.distance_from_start_index == 0) {
entry.used = false;
hm.size -= 1;
return;
return entry;
}
*entry = *next_entry;
entry.distance_from_start_index -= 1;
entry = next_entry;
}
unreachable // shifting everything in the table
}}
unreachable // key not found
return null;
}

pub fn entryIterator(hm: &Self) -> Iterator {
pub fn entryIterator(hm: &const Self) -> Iterator {
return Iterator {
.hm = hm,
.count = 0,
Expand Down Expand Up @@ -231,7 +235,8 @@ test "basicHashMapTest" {
%%map.put(5, 55);

assert((??map.get(2)).value == 22);
map.remove(2);
_ = map.remove(2);
assert(map.remove(2) == null);
assert(if (const entry ?= map.get(2)) false else true);
}

Expand Down

0 comments on commit c9ae30d

Please sign in to comment.