mask-vec-mathfunc 优化设计

1:识别的gimple 

(1) VEC_COND_EXPR

(2) MASK_STORE

2: 找向量数学函数的方法

(1)VEC_COND_EXPR中有三个参数

vect_cstore_3623.1792_3442 = VEC_COND_EXPR <_3443, vect_cst__3446, vect__3624.1791_3445>;

参数1:mask的值,需要保证该mask在向量数学函数之前定义,不然插入的mask无法识别。如果在其之后定义,需要评估能不能移动到其之前。

参数2:mask 为 true 选择的元素,该操作数如果是SSA_NAME需要递归的找其定义的地方是否有向量数学函数,如果有,将参数1 插入向量数学函数中。

参数3:mask为false选择的元素,该操作数如果是SSA_NAME需要递归的找其定义的地方是否有向量数学函数,如果有,将参数1 取反插入向量数学函数中。

(2)MASK_STORE 有四个参数

 MASK_STORE (vectp.232_1628, 64B, mask__847.221_1607, vect__839.231_1621);

参数3:mask的值,同上,定义需要在向量数学函数之前。否则考虑能否移动

参数4:运算的结果。在其定义中查找是否有vect-mathfunc。

      

#include "config.h"
  2  #include "system.h"
  3  #include "coretypes.h"
  4  #include "backend.h"
  5  #include "tree.h"
  6  #include "gimple.h"
  7  #include "predict.h"
  8  #include "tree-pass.h"
  9  #include "ssa.h"
 10  #include "cgraph.h"
 11  #include "fold-const.h"
 12  #include "stor-layout.h"
 13  #include "gimple-iterator.h"
 14  #include "gimple-walk.h"
 15  #include "tree-ssa-loop-manip.h"
 16  #include "tree-ssa-loop-niter.h"
 17  #include "tree-cfg.h"
 18  #include "cfgloop.h"
 19  #include "tree-vectorizer.h"
 20  #include "tree-ssa-propagate.h"
 21  #include "dbgcnt.h"
 22  #include "tree-scalar-evolution.h"
 23  #include "stringpool.h"
 24  #include "attribs.h"
 25  #include "gimple-pretty-print.h"
 26  #include "opt-problem.h"
 27  #include "internal-fn.h"
 28  #include "tree-ssa-sccvn.h"
 29  #include "gimple-expr.h"
 30  #include <cstdio>
 31
 32  namespace
 33  {
 34  const pass_data pass_data_test = {
 35    GIMPLE_PASS,           /* type */
 36    "mask_vecmath_func",                /* name */
 37    OPTGROUP_NONE,         /* optinfo_flags */
 38    TV_TREE_VECT_MASK_VECMATH_FUNC,          /* tv_id */
 39    (PROP_cfg | PROP_ssa), /* properties_required */
 40    0,                     /* properties_provided */
 41    0,                     /* properties_destroyed */
 42    0,                     /* todo_flags_start */
 43    0,                     /* todo_flags_finish */
 44  };
 46  class pass_mask_vecmath_func : public gimple_opt_pass
 47  {
 48  public:
 49    pass_mask_vecmath_func (gcc::context *ctxt) : gimple_opt_pass (pass_data_test, ctxt) {}
 50    virtual bool
 51    gate (function *fun)
 52    {
 53     // printf ("gate function noipa.\n");
 54      return flag_tree_mask_vecmath_func;
 55    }
 56
 57    virtual unsigned int execute (function *);
 58  };
 59
 60
 61 static gimple *find_relate_operand(tree operand, gimple *stmt)
 62 {
 63   if (!stmt)
 64         return NULL;
 65
 66   if (TREE_CODE (operand) == SSA_NAME && is_gimple_call(stmt)) {  // operand is ssa && stmt is gimple call
 67      tree fndecl = gimple_call_fndecl(stmt);  // 获取函数声明
 68        if (fndecl && DECL_P(fndecl)) {  // 确保fndecl有效并且是一个声明
 69           const char *func_name = IDENTIFIER_POINTER(DECL_NAME(fndecl));  // 获取函数名称
 70          // if (strcmp(func_name, "vmldLn2") == 0) {
 71           if (strcmp(func_name, "__svml_log4_mask_e9") == 0) {
 72             return stmt;
 73           }
 74        }
 75   }
 76   if (TREE_CODE (operand) == SSA_NAME && is_gimple_assign(stmt)) {   // only find gimple assign
 77
 78      for (unsigned i = 1; i < gimple_num_ops(stmt); ++i) {  // get gimple assign right hand side operand
 79         tree op = gimple_op(stmt, i);
 80         if(TREE_CODE (op) == SSA_NAME) {
 81
 82            gimple *stmt_2 = SSA_NAME_DEF_STMT (op);
 83            gimple *result = find_relate_operand(op,stmt_2);
 84            if(result) return result;
 85         }
 86     }
 87   }
 88   return NULL;
 89 }
 90
 91 static void add_mask_to_call(gimple *stmt, tree new_arg) {
 92     if (!is_gimple_call(stmt)) {
 93         // 如果不是函数调用语句,则不做任何操作
 94         return;
 95     }
 96
 97     // 获取原始函数调用的目标和参数列表
 98     tree call_fn = gimple_call_fndecl(stmt);
 99
100    // 获取或创建新的标识符节点来表示新的函数名称
101   // tree new_func_id = get_identifier("vmldLn2Mask");
102    tree new_func_id = get_identifier("__svml_log4_mask_e9");
103    tree fntype = TREE_TYPE(call_fn);
104
105    tree new_fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, new_func_id, fntype);
106
107    TREE_PUBLIC (new_fndecl) = 1;
108    DECL_EXTERNAL (new_fndecl) = 1;
109    DECL_IS_NOVOPS (new_fndecl) = 1;
110    TREE_READONLY (new_fndecl) = 1;
111
112
113    // 将新的标识符节点分配给函数声明的汇编名
114   // DECL_ASSEMBLER_NAME(call_fn) = new_func_id;
115
116     int num_args = gimple_call_num_args(stmt);
117     vec<tree> vargs = vNULL;
118     vargs.create (num_args+1);
119
120     // 创建一个新的参数列表,包含原始的参数和新的参数
121     for (int i = 0; i < num_args; i++) {
122         tree arg = gimple_call_arg(stmt, i);
123         vargs.safe_push(arg);
124     }
125     vargs.safe_push(new_arg);
126
127     tree lhs = gimple_call_lhs(stmt);
128
129     // 创建新的函数调用语句,包含新的参数
130     gimple *new_call = gimple_build_call_vec(new_fndecl,vargs);
131     gimple_call_set_lhs (new_call, lhs);
132
133     // 替换原始的函数调用语句
134     gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
135
136  //   printf ("-------------finish add mask to vecmath func call------------.\n");
137
138     gsi_replace(&gsi, new_call,true);
139     stmt = new_call;
140
141     // 释放参数列表的内存
142     vargs.release ();
143 }
144
145  unsigned
146  pass_mask_vecmath_func::execute (function *fun)
147  {
148    unsigned ret = 0;
149
150  //  printf ("-----------begin mask vecmath func------------.\n");
151  //  printf ("current function name:%s\n", function_name (fun));
152    basic_block bb;
153    enum tree_code code;
154
155     // 遍历所有基本块
156     FOR_EACH_BB_FN(bb, fun) {
157         gimple_stmt_iterator gsi;
158
159         // 遍历基本块中的所有 GIMPLE 语句
160         for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
161             gimple *stmt = gsi_stmt(gsi);
162             if (is_gimple_assign(stmt)) {
163
164                gassign *stmt_assign = dyn_cast <gassign *> (gsi_stmt (gsi));
165                code = gimple_assign_rhs_code (stmt_assign);
166
167              // 检查语句是否为 VEC_COND_EXPR
168                if (code == VEC_COND_EXPR) {
169
170                 //  printf ("-----------find out vec cond expr------------.\n");
171                   tree true_vector_operand = gimple_assign_rhs2(stmt_assign); // add wrong vec operand
172                   tree  mask_operand = gimple_assign_rhs1(stmt_assign);
173                   if(TREE_CODE (true_vector_operand) == SSA_NAME) {
174
175                      gimple *stmt_def = SSA_NAME_DEF_STMT (true_vector_operand);
176                      gimple *stmt_vecmath = find_relate_operand(true_vector_operand,stmt_def);
177                      if(stmt_vecmath) {
178                  //  printf ("-----------find out vecmath stmt------------.\n");
179                      add_mask_to_call(stmt_vecmath,mask_operand);
180
181                      }
182                   }
183               }
184             }
185         }
186     }
187    return ret;
188  }
189  }
190
191  gimple_opt_pass *
192  make_pass_mask_vecmath_func (gcc::context *ctxt)
193  {
194    return new pass_mask_vecmath_func (ctxt);
195  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值