/** * Do a load from &base_ptr[index], but also add a flag that it's loading * a constant from a dynamically uniform index. */ LLVMValueRef ac_build_indexed_load_const(struct ac_llvm_context *ctx, LLVMValueRef base_ptr, LLVMValueRef index) { LLVMValueRef result = ac_build_indexed_load(ctx, base_ptr, index, true); LLVMSetMetadata(result, ctx->invariant_load_md_kind, ctx->empty_md); return result; }
static void set_descriptor(compile_t* c, reach_type_t* t, LLVMValueRef value) { if(t->underlying == TK_STRUCT) return; LLVMValueRef desc_ptr = LLVMBuildStructGEP(c->builder, value, 0, ""); LLVMValueRef store = LLVMBuildStore(c->builder, t->desc, desc_ptr); const char id[] = "tbaa"; LLVMSetMetadata(store, LLVMGetMDKindID(id, sizeof(id) - 1), c->tbaa_descptr); }
LLVMValueRef ac_build_fdiv(struct ac_llvm_context *ctx, LLVMValueRef num, LLVMValueRef den) { LLVMValueRef ret = LLVMBuildFDiv(ctx->builder, num, den, ""); if (!LLVMIsConstant(ret)) LLVMSetMetadata(ret, ctx->fpmath_md_kind, ctx->fpmath_md_2p5_ulp); return ret; }
/** * Set range metadata on an instruction. This can only be used on load and * call instructions. If you know an instruction can only produce the values * 0, 1, 2, you would do set_range_metadata(value, 0, 3); * \p lo is the minimum value inclusive. * \p hi is the maximum value exclusive. */ static void set_range_metadata(struct ac_llvm_context *ctx, LLVMValueRef value, unsigned lo, unsigned hi) { LLVMValueRef range_md, md_args[2]; LLVMTypeRef type = LLVMTypeOf(value); LLVMContextRef context = LLVMGetTypeContext(type); md_args[0] = LLVMConstInt(type, lo, false); md_args[1] = LLVMConstInt(type, hi, false); range_md = LLVMMDNodeInContext(context, md_args, 2); LLVMSetMetadata(value, ctx->range_md_kind, range_md); }
/** * Build an LLVM bytecode indexed load using LLVMBuildGEP + LLVMBuildLoad. * It's equivalent to doing a load from &base_ptr[index]. * * \param base_ptr Where the array starts. * \param index The element index into the array. * \param uniform Whether the base_ptr and index can be assumed to be * dynamically uniform */ LLVMValueRef ac_build_indexed_load(struct ac_llvm_context *ctx, LLVMValueRef base_ptr, LLVMValueRef index, bool uniform) { LLVMValueRef pointer; pointer = ac_build_gep0(ctx, base_ptr, index); if (uniform) LLVMSetMetadata(pointer, ctx->uniform_md_kind, ctx->empty_md); return LLVMBuildLoad(ctx->builder, pointer, ""); }
static LLVMValueRef assign_field(compile_t* c, LLVMValueRef l_value, LLVMValueRef r_value, ast_t* p_type, ast_t* r_type) { LLVMValueRef result = LLVMBuildLoad(c->builder, l_value, ""); // Cast the rvalue appropriately. LLVMTypeRef cast_type = LLVMGetElementType(LLVMTypeOf(l_value)); LLVMValueRef cast_value = gen_assign_cast(c, cast_type, r_value, r_type); if(cast_value == NULL) return NULL; // Store to the field. LLVMValueRef store = LLVMBuildStore(c->builder, cast_value, l_value); LLVMValueRef metadata = tbaa_metadata_for_type(c, p_type); const char id[] = "tbaa"; LLVMSetMetadata(result, LLVMGetMDKindID(id, sizeof(id) - 1), metadata); LLVMSetMetadata(store, LLVMGetMDKindID(id, sizeof(id) - 1), metadata); return result; }
int llvm_set_metadata(void) { LLVMBuilderRef b = LLVMCreateBuilder(); LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) }; // This used to trigger an assertion LLVMSetMetadata( LLVMBuildRetVoid(b), LLVMGetMDKindID("kind", 4), LLVMMDNode(values, 1)); LLVMDisposeBuilder(b); return 0; }
/** * Build an LLVM bytecode indexed load using LLVMBuildGEP + LLVMBuildLoad * * @param offset The offset parameter specifies the number of * elements to offset, not the number of bytes or dwords. An element is the * the type pointed to by the base_ptr parameter (e.g. int is the element of * an int* pointer) * * When LLVM lowers the load instruction, it will convert the element offset * into a dword offset automatically. * */ static LLVMValueRef build_indexed_load( struct si_shader_context * si_shader_ctx, LLVMValueRef base_ptr, LLVMValueRef offset) { struct lp_build_context * base = &si_shader_ctx->radeon_bld.soa.bld_base.base; LLVMValueRef computed_ptr = LLVMBuildGEP( base->gallivm->builder, base_ptr, &offset, 1, ""); LLVMValueRef result = LLVMBuildLoad(base->gallivm->builder, computed_ptr, ""); LLVMSetMetadata(result, 1, si_shader_ctx->const_md); return result; }
static void emit_fdiv(const struct lp_build_tgsi_action *action, struct lp_build_tgsi_context *bld_base, struct lp_build_emit_data *emit_data) { struct si_shader_context *ctx = si_shader_context(bld_base); emit_data->output[emit_data->chan] = LLVMBuildFDiv(bld_base->base.gallivm->builder, emit_data->args[0], emit_data->args[1], ""); /* Use v_rcp_f32 instead of precise division. */ if (HAVE_LLVM >= 0x0309 && !LLVMIsConstant(emit_data->output[emit_data->chan])) LLVMSetMetadata(emit_data->output[emit_data->chan], ctx->fpmath_md_kind, ctx->fpmath_md_2p5_ulp); }
LLVMValueRef gen_fieldload(compile_t* c, ast_t* ast) { AST_GET_CHILDREN(ast, left, right); ast_t* l_type = ast_type(left); LLVMValueRef field = gen_fieldptr(c, ast); if(field == NULL) return NULL; assert((ast_id(l_type) == TK_NOMINAL) || (ast_id(l_type) == TK_TUPLETYPE)); // Don't load if we're reading from a tuple. if(ast_id(l_type) != TK_TUPLETYPE) { field = LLVMBuildLoad(c->builder, field, ""); LLVMValueRef metadata = tbaa_metadata_for_type(c, l_type); const char id[] = "tbaa"; LLVMSetMetadata(field, LLVMGetMDKindID(id, sizeof(id) - 1), metadata); } return field; }