[Mesa-dev] [PATCH] radv/ac: enable loop unrolling.
Dave Airlie
airlied at gmail.com
Fri Feb 24 03:28:47 UTC 2017
On 24 February 2017 at 13:27, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This enables LLVM loop unrolling.
Meant to also say it's based on a radeonsi patch Marek wrote.
Dave.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> src/amd/common/ac_llvm_helper.cpp | 22 ++++++++++++++++++++++
> src/amd/common/ac_llvm_util.h | 1 +
> src/amd/common/ac_nir_to_llvm.c | 24 ++++++++++++++++++++++--
> 3 files changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/src/amd/common/ac_llvm_helper.cpp b/src/amd/common/ac_llvm_helper.cpp
> index 594339e..85b0cbf 100644
> --- a/src/amd/common/ac_llvm_helper.cpp
> +++ b/src/amd/common/ac_llvm_helper.cpp
> @@ -36,7 +36,9 @@
> #include <llvm/Target/TargetOptions.h>
> #include <llvm/ExecutionEngine/ExecutionEngine.h>
> #include <llvm/IR/Attributes.h>
> +#include <llvm/IR/LLVMContext.h>
>
> +using namespace llvm;
> void ac_add_attr_dereferenceable(LLVMValueRef val, uint64_t bytes)
> {
> llvm::Argument *A = llvm::unwrap<llvm::Argument>(val);
> @@ -53,3 +55,23 @@ bool ac_is_sgpr_param(LLVMValueRef arg)
> return AS.hasAttribute(ArgNo + 1, llvm::Attribute::ByVal) ||
> AS.hasAttribute(ArgNo + 1, llvm::Attribute::InReg);
> }
> +
> +// MetadataAsValue uses a canonical format which strips the actual MDNode for
> +// MDNode with just a single constant value, storing just a ConstantAsMetadata
> +// This undoes this canonicalization, reconstructing the MDNode.
> +static MDNode *extractMDNode(MetadataAsValue *MAV) {
> + Metadata *MD = MAV->getMetadata();
> + assert((isa<MDNode>(MD) || isa<ConstantAsMetadata>(MD)) &&
> + "Expected a metadata node or a canonicalized constant");
> +
> + if (MDNode *N = dyn_cast<MDNode>(MD))
> + return N;
> + assert(0);
> + return MDNode::get(MAV->getContext(), MD);
> +}
> +
> +void ac_metadata_point_op0_to_itself(LLVMValueRef v)
> +{
> + MDNode *node = extractMDNode(unwrap<MetadataAsValue>(v));
> + node->replaceOperandWith(0, node);
> +}
> diff --git a/src/amd/common/ac_llvm_util.h b/src/amd/common/ac_llvm_util.h
> index 1f37a12..0d6c53c 100644
> --- a/src/amd/common/ac_llvm_util.h
> +++ b/src/amd/common/ac_llvm_util.h
> @@ -48,6 +48,7 @@ LLVMTargetMachineRef ac_create_target_machine(enum radeon_family family, bool su
>
> void ac_add_attr_dereferenceable(LLVMValueRef val, uint64_t bytes);
> bool ac_is_sgpr_param(LLVMValueRef param);
> +void ac_metadata_point_op0_to_itself(LLVMValueRef v);
>
> void
> ac_add_function_attr(LLVMValueRef function,
> diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
> index 9778581..0e20aa1 100644
> --- a/src/amd/common/ac_nir_to_llvm.c
> +++ b/src/amd/common/ac_nir_to_llvm.c
> @@ -3950,6 +3950,21 @@ static void visit_if(struct nir_to_llvm_context *ctx, nir_if *if_stmt)
> LLVMPositionBuilderAtEnd(ctx->builder, merge_block);
> }
>
> +static void set_unroll_metadata(struct nir_to_llvm_context *ctx,
> + LLVMValueRef br)
> +{
> + unsigned kind = LLVMGetMDKindIDInContext(ctx->context, "llvm.loop", 9);
> + LLVMValueRef md_unroll;
> + LLVMValueRef full_arg = LLVMMDStringInContext(ctx->context, "llvm.loop.unroll.full", 21);
> + LLVMValueRef full = LLVMMDNodeInContext(ctx->context, &full_arg, 1);
> +
> + LLVMValueRef md_args[] = {NULL, full};
> + md_unroll = LLVMMDNodeInContext(ctx->context, md_args, 2);
> + ac_metadata_point_op0_to_itself(md_unroll);
> +
> + LLVMSetMetadata(br, kind, md_unroll);
> +}
> +
> static void visit_loop(struct nir_to_llvm_context *ctx, nir_loop *loop)
> {
> LLVMBasicBlockRef continue_parent = ctx->continue_block;
> @@ -3964,8 +3979,10 @@ static void visit_loop(struct nir_to_llvm_context *ctx, nir_loop *loop)
> LLVMPositionBuilderAtEnd(ctx->builder, ctx->continue_block);
> visit_cf_list(ctx, &loop->body);
>
> - if (LLVMGetInsertBlock(ctx->builder))
> - LLVMBuildBr(ctx->builder, ctx->continue_block);
> + if (LLVMGetInsertBlock(ctx->builder)) {
> + LLVMValueRef loop = LLVMBuildBr(ctx->builder, ctx->continue_block);
> + set_unroll_metadata(ctx, loop);
> + }
> LLVMPositionBuilderAtEnd(ctx->builder, ctx->break_block);
>
> ctx->continue_block = continue_parent;
> @@ -4827,10 +4844,13 @@ static void ac_llvm_finalize_module(struct nir_to_llvm_context * ctx)
>
> /* Add some optimization passes */
> LLVMAddScalarReplAggregatesPass(passmgr);
> + LLVMAddLoopRotatePass(passmgr);
> LLVMAddLICMPass(passmgr);
> LLVMAddAggressiveDCEPass(passmgr);
> LLVMAddCFGSimplificationPass(passmgr);
> LLVMAddInstructionCombiningPass(passmgr);
> + LLVMAddIndVarSimplifyPass(passmgr);
> + LLVMAddLoopUnrollPass(passmgr);
>
> /* Run the pass */
> LLVMInitializeFunctionPassManager(passmgr);
> --
> 2.9.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list