|  | @@ -49,6 +49,8 @@ struct lbModule {
 | 
	
		
			
				|  |  |  	LLVMContextRef ctx;
 | 
	
		
			
				|  |  |  	CheckerInfo *info;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	gbMutex mutex;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	Map<LLVMTypeRef> types; // Key: Type *
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	Map<lbValue> values; // Key: Entity *
 | 
	
	
		
			
				|  | @@ -77,6 +79,9 @@ struct lbBlock {
 | 
	
		
			
				|  |  |  	LLVMBasicBlockRef block;
 | 
	
		
			
				|  |  |  	Scope *scope;
 | 
	
		
			
				|  |  |  	isize scope_index;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	Array<lbBlock *> preds;
 | 
	
		
			
				|  |  | +	Array<lbBlock *> succs;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  struct lbBranchBlocks {
 | 
	
	
		
			
				|  | @@ -106,6 +111,28 @@ enum lbDeferExitKind {
 | 
	
		
			
				|  |  |  	lbDeferExit_Branch,
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +enum lbDeferKind {
 | 
	
		
			
				|  |  | +	lbDefer_Node,
 | 
	
		
			
				|  |  | +	lbDefer_Instr,
 | 
	
		
			
				|  |  | +	lbDefer_Proc,
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +struct lbDefer {
 | 
	
		
			
				|  |  | +	lbDeferKind kind;
 | 
	
		
			
				|  |  | +	isize       scope_index;
 | 
	
		
			
				|  |  | +	isize       context_stack_count;
 | 
	
		
			
				|  |  | +	lbBlock *   block;
 | 
	
		
			
				|  |  | +	union {
 | 
	
		
			
				|  |  | +		Ast *stmt;
 | 
	
		
			
				|  |  | +		// NOTE(bill): 'instr' will be copied every time to create a new one
 | 
	
		
			
				|  |  | +		lbValue instr;
 | 
	
		
			
				|  |  | +		struct {
 | 
	
		
			
				|  |  | +			lbValue deferred;
 | 
	
		
			
				|  |  | +			Array<lbValue> result_as_args;
 | 
	
		
			
				|  |  | +		} proc;
 | 
	
		
			
				|  |  | +	};
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  struct lbTargetList {
 | 
	
		
			
				|  |  |  	lbTargetList *prev;
 | 
	
		
			
				|  |  |  	bool          is_block;
 | 
	
	
		
			
				|  | @@ -138,6 +165,7 @@ struct lbProcedure {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	lbAddr           return_ptr;
 | 
	
		
			
				|  |  |  	Array<lbValue>   params;
 | 
	
		
			
				|  |  | +	Array<lbDefer>   defer_stmts;
 | 
	
		
			
				|  |  |  	Array<lbBlock *> blocks;
 | 
	
		
			
				|  |  |  	Array<lbBranchBlocks> branch_blocks;
 | 
	
		
			
				|  |  |  	Scope *          curr_scope;
 | 
	
	
		
			
				|  | @@ -176,7 +204,10 @@ LLVMTypeRef  lb_type(lbModule *m, Type *type);
 | 
	
		
			
				|  |  |  lbBlock *lb_create_block(lbProcedure *p, char const *name);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  lbValue lb_const_nil(lbModule *m, Type *type);
 | 
	
		
			
				|  |  | +lbValue lb_const_undef(lbModule *m, Type *type);
 | 
	
		
			
				|  |  |  lbValue lb_const_value(lbModule *m, Type *type, ExactValue value);
 | 
	
		
			
				|  |  | +lbValue lb_const_bool(lbModule *m, Type *type, bool value);
 | 
	
		
			
				|  |  | +lbValue lb_const_int(lbModule *m, Type *type, u64 value);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  lbAddr lb_addr(lbValue addr);
 | 
	
	
		
			
				|  | @@ -200,7 +231,7 @@ lbValue lb_emit_array_epi(lbProcedure *p, lbValue value, i32 index);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t);
 | 
	
		
			
				|  |  |  lbValue lb_build_call_expr(lbProcedure *p, Ast *expr);
 | 
	
	
		
			
				|  | @@ -212,6 +243,12 @@ lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e=nullptr, bool zero_ini
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right);
 | 
	
		
			
				|  |  | +lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining = ProcInlining_none, bool use_return_ptr_hint = false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +lbValue lb_typeid(lbModule *m, Type *type, Type *typeid_type=t_typeid);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  enum lbCallingConventionKind {
 | 
	
		
			
				|  |  |      lbCallingConvention_C = 0,
 |