[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