Skip to content

Commit

Permalink
Optimize access of array member in a structure.
Browse files Browse the repository at this point in the history
  • Loading branch information
shwqf committed Dec 17, 2022
1 parent 21d2e63 commit 49aa7fc
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/codegen/llvm.zig
Expand Up @@ -5750,8 +5750,8 @@ pub const FuncGen = struct {
const elem_ty = array_ty.childType();
if (isByRef(array_ty)) {
const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");
if (isByRef(elem_ty)) {
const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");
if (canElideLoad(self, body_tail))
return elem_ptr;

Expand All @@ -5772,11 +5772,13 @@ pub const FuncGen = struct {
.struct_field_ptr_index_3 => {
const load_ptr_inst = try self.resolveInst(load_ptr);
const gep = self.builder.buildInBoundsGEP(array_llvm_ty, load_ptr_inst, &indices, indices.len, "");
array_llvm_val.removeUnusedLoadArray();
return self.builder.buildLoad(elem_llvm_ty, gep, "");
},
else => {}
}
}
const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");
return self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/codegen/llvm/bindings.zig
Expand Up @@ -256,6 +256,9 @@ pub const Value = opaque {

pub const addByValAttr = ZigLLVMAddByValAttr;
extern fn ZigLLVMAddByValAttr(Fn: *Value, ArgNo: c_uint, type: *Type) void;

pub const removeUnusedLoadArray = ZigLLVMRemoveUnusedLoadArray;
extern fn ZigLLVMRemoveUnusedLoadArray(Val: *Value) void;
};

pub const Type = opaque {
Expand Down
14 changes: 14 additions & 0 deletions src/zig_llvm.cpp
Expand Up @@ -186,6 +186,20 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {
return unwrap(TD)->getProgramAddressSpace();
}

void ZigLLVMRemoveUnusedLoadArray(LLVMValueRef Val) {
auto *Ptr = unwrap(Val);
if (auto *AI = dyn_cast<AllocaInst>(Ptr)) {
if (AI->hasOneUse()) {
if (auto *CI = dyn_cast<CallInst>(AI->user_back())) {
if (CI->getIntrinsicID() == Intrinsic::memcpy) {
CI->eraseFromParent();
AI->eraseFromParent();
}
}
}
}
}

namespace {
// LLVM's time profiler can provide a hierarchy view of the time spent
// in each component. It generates JSON report in Chrome's "Trace Event"
Expand Down
2 changes: 2 additions & 0 deletions src/zig_llvm.h
Expand Up @@ -599,4 +599,6 @@ ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type,
ZIG_EXTERN_C unsigned ZigLLVMDataLayoutGetStackAlignment(LLVMTargetDataRef TD);
ZIG_EXTERN_C unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD);

ZIG_EXTERN_C void ZigLLVMRemoveUnusedLoadArray(LLVMValueRef Val);

#endif

0 comments on commit 49aa7fc

Please sign in to comment.