summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Benton <[email protected]>2012-04-19 13:13:17 +0100
committerJosé Fonseca <[email protected]>2012-05-02 10:12:48 +0100
commit85d09d1c61d3e5ab2c2ae6fc74a30ea6a572f25e (patch)
tree669d2e64f0fe620f7c764ddbca6c446692d03d29
parent630fa2688634365c03edf2a189cf9225899fbcc5 (diff)
gallivm: added aligned pointer get/set
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.h7
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_misc.cpp15
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_struct.c34
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_struct.h25
4 files changed, 81 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h
index f68bf75a851..5fc0f996c64 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h
@@ -81,5 +81,12 @@ extern LLVMValueRef
lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal,
const char *Name);
+void
+lp_set_load_alignment(LLVMValueRef Inst,
+ unsigned Align);
+
+void
+lp_set_store_alignment(LLVMValueRef Inst,
+ unsigned Align);
#endif /* !LP_BLD_INIT_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index 68f8808f3ef..6c4586c4212 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -165,3 +165,18 @@ lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal,
return llvm::wrap(llvm::unwrap(B)->CreateLoad(llvm::unwrap(PointerVal), true, Name));
}
+extern "C"
+void
+lp_set_load_alignment(LLVMValueRef Inst,
+ unsigned Align)
+{
+ llvm::unwrap<llvm::LoadInst>(Inst)->setAlignment(Align);
+}
+
+extern "C"
+void
+lp_set_store_alignment(LLVMValueRef Inst,
+ unsigned Align)
+{
+ llvm::unwrap<llvm::StoreInst>(Inst)->setAlignment(Align);
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_struct.c b/src/gallium/auxiliary/gallivm/lp_bld_struct.c
index 0dc2f24d10a..cc248d15e97 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_struct.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.c
@@ -146,6 +146,25 @@ lp_build_pointer_get(LLVMBuilderRef builder,
}
+LLVMValueRef
+lp_build_pointer_get_unaligned(LLVMBuilderRef builder,
+ LLVMValueRef ptr,
+ LLVMValueRef index,
+ unsigned alignment)
+{
+ LLVMValueRef element_ptr;
+ LLVMValueRef res;
+ assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
+ element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, "");
+ res = LLVMBuildLoad(builder, element_ptr, "");
+ lp_set_load_alignment(res, alignment);
+#ifdef DEBUG
+ lp_build_name(res, "%s[%s]", LLVMGetValueName(ptr), LLVMGetValueName(index));
+#endif
+ return res;
+}
+
+
void
lp_build_pointer_set(LLVMBuilderRef builder,
LLVMValueRef ptr,
@@ -156,3 +175,18 @@ lp_build_pointer_set(LLVMBuilderRef builder,
element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, "");
LLVMBuildStore(builder, value, element_ptr);
}
+
+
+void
+lp_build_pointer_set_unaligned(LLVMBuilderRef builder,
+ LLVMValueRef ptr,
+ LLVMValueRef index,
+ LLVMValueRef value,
+ unsigned alignment)
+{
+ LLVMValueRef element_ptr;
+ LLVMValueRef instr;
+ element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, "");
+ instr = LLVMBuildStore(builder, value, element_ptr);
+ lp_set_store_alignment(instr, alignment);
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_struct.h b/src/gallium/auxiliary/gallivm/lp_bld_struct.h
index 11605c685f0..6b7b4f2a6bf 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_struct.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.h
@@ -105,6 +105,18 @@ lp_build_pointer_get(LLVMBuilderRef builder,
LLVMValueRef index);
/**
+ * Get the value of an array element, with explicit alignment.
+ *
+ * If the element size is different from the alignment this will
+ * cause llvm to emit an unaligned load
+ */
+LLVMValueRef
+lp_build_pointer_get_unaligned(LLVMBuilderRef builder,
+ LLVMValueRef ptr,
+ LLVMValueRef index,
+ unsigned alignment);
+
+/**
* Set the value of an array element.
*/
void
@@ -113,4 +125,17 @@ lp_build_pointer_set(LLVMBuilderRef builder,
LLVMValueRef index,
LLVMValueRef value);
+/**
+ * Set the value of an array element, with explicit alignment.
+ *
+ * If the element size is different from the alignment this will
+ * cause llvm to emit an unaligned store
+ */
+void
+lp_build_pointer_set_unaligned(LLVMBuilderRef builder,
+ LLVMValueRef ptr,
+ LLVMValueRef index,
+ LLVMValueRef value,
+ unsigned alignment);
+
#endif /* !LP_BLD_STRUCT_H */