Hi Richard and Segher I don't know if I exactly understood your discussion. If I misunderstood, please let me know.
I am trying to test these two cases. Case 1. keep the TYPE attribute unchanged, add new attributes It works well as below. (define_attr "shift_imm_value" "shift_imm_none,shift_imm_0,shift_imm_1to4,shift_imm_ge5" (const_string "shift_imm_none")) (define_insn "*add_<shift>_<mode>" [(set (match_operand:GPI 0 "register_operand" "=r") (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r") (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) (match_operand:GPI 3 "register_operand" "r")))] "" "add\\t%<w>0, %<w>3, %<w>1, <shift> %2" [(set_attr "type" "alu_shift_imm") (set (attr "shift_imm_value") (cond [(eq (symbol_ref "XINT(operands[2],0)") (const_int 0)) (const_string "shift_imm_0") (and (ge (symbol_ref "XINT(operands[2],0)") (const_int 1)) (le (symbol_ref "XINT(operands[2],0)") (const_int 4))) (const_string "shift_imm_1to4")] (const_string "shift_imm_ge5")))] ) (define_insn_reservation "a64fx_alu_shift1to4" 2 (and (eq_attr "tune" "a64fx") (eq_attr "type" "alu_shift_imm") (eq_attr "shift_imm_value" "shift_imm_1to4")) "(a64fx_exa,a64fx_exa)|(a64fx_exb,a64fx_exb)") Case2. expand the TYPE attribute I replaced the alu_shift_imm to alu_shift_imm, alu_shift_imm1to4, and I got the error message " bad number of entries in SET_ATTR_ALTERNATIVE, was 2 expected 1" (define_attr "type" ... alu_shift_imm,\ alu_shift_imm1to4,\ ... (define_insn "*add_<shift>_<mode>" [(set (match_operand:GPI 0 "register_operand" "=r") (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r") (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) (match_operand:GPI 3 "register_operand" "r")))] "" "add\\t%<w>0, %<w>3, %<w>1, <shift> %2" [(set_attr "type" "alu_shift_imm,alu_shift_imm1to4")] ) It means that one "type" value should be matched by one operand constraint pattern. So this will raise two problems. 1. One instruction should be classified to multiple patterns - define multiple operand constraints, such as "(match_operand:QI 2 "aarch64_shift_imm_<mode>" "0, 1to4, ...")" - or, use "cond" at set_attr just like Case1. 2. Whatever you do with the first problem, the type attribute cannot be set with "alu_shift_imm" and "alu_shift_imm1to4" at the same time by one operand constraint pattern. - If we cannot resolve it, the existing CPUs' descriptions need to be changed. This is not what I expected. - If we want to add new attribute to resolve this problem, why not use the Case1 directly? > It is very much not what I am saying. I *am* saying that if people trying to > improve one CPU's modelling have to edit over 20 models for CPUs that they do > not care about, mistakes happen. That's what I'm worried about. Regards Qian > -----Original Message----- > From: Segher Boessenkool <seg...@kernel.crashing.org> > Sent: Friday, September 11, 2020 9:59 PM > To: Qian, Jianhua/钱 建华 <qia...@cn.fujitsu.com>; gcc@gcc.gnu.org; > richard.sandif...@arm.com > Subject: Re: A problem with one instruction multiple latencies and pipelines > > Hi! > > On Fri, Sep 11, 2020 at 08:44:54AM +0100, Richard Sandiford wrote: > > Segher Boessenkool <seg...@kernel.crashing.org> writes: > > > Consider cores that do not care about the "subtype" at all: when > > > using just "type", all cores have to test for "foo,foo_subtype", > > > while with a separate attribute they can just test for "foo". > > > > Right. But that was exactly the case I was considering with the sed > > comment above :-) > > > > I don't see adding a new attribute value to a set_attr as extra > > complication. It's just adding a value to a set. To me extra > > complication is adding (ior …)s, (and …)s, etc. > > Combinatorial explosion is real. > > (ior)s etc. are easier to read, and importantly it is much more obvious if > any case > is missed with them. > > Here is the very first diff in d839f53b7dfd, where I started this for > rs6000: > > (define_insn_reservation "ppc403-load" 2 > - (and (eq_attr "type" > "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ > - load_l,store_c,sync") > + (and (eq_attr "type" "load,load_l,store_c,sync") > (eq_attr "cpu" "ppc403,ppc405")) > "iu_40x") > > We started off with 77 insn types. Now we have 63 (it was 57 before, we added > some more). > > > > Yeas, exactly. And for rs6000 we *did* have many more types before, > > > and very frequently one was missed (in a scheduling description usually). > > > Especially common was when some new type attribute was added, not > > > all existing cpu descriptions were updated correctly. Maybe this is > > > the strongest argument "for" actually :-) > > > > The update shouldn't be done by hand. > > No, it very much had to, because the existing code missed many cases and was > inconsistent in others. > > > What I'm really wary of with taking the line above is that it feeds > > into the attitude that existing scheduling descriptions should become > > fossilised at the point they're added: noone working on a different > > core should change the declarations in the file later in case they > > miss something. I don't think that's what you're saying, but it could > > feed into that general attitude. > > It is very much not what I am saying. I *am* saying that if people trying to > improve one CPU's modelling have to edit over 20 models for CPUs that they do > not care about, mistakes happen. Such churn is conceptually wrong as well, > of course (the new types are just the same as the old types on most older > CPUs!) > > > > Yes. > > > > > > One example of what we do: > > > > > > ;; Is this instruction using operands[2] as shift amount, and can > > > that be a ;; register? > > > ;; This is used for shift insns. > > > (define_attr "maybe_var_shift" "no,yes" (const_string "no")) > > > > > > ;; Is this instruction using a shift amount from a register? > > > ;; This is used for shift insns. > > > (define_attr "var_shift" "no,yes" > > > (if_then_else (and (eq_attr "type" "shift") > > > (eq_attr "maybe_var_shift" "yes")) > > > (if_then_else (match_operand 2 "gpc_reg_operand") > > > (const_string "yes") > > > (const_string "no")) > > > (const_string "no"))) > > > > > > define_insns only use maybe_var_shift. Only the power6 and e*500* > > > cpu descriptions ever look at var_shift. (Directly. There is some > > > other scheduling code that looks at it too -- and all but the power6 > > > ones seem to be incorrect! That is all a direct translation of > > > "type-only" code there was before...) > > > > Right. This is similar to the: > > > > (define_attr "shift_imm_type" "none,alu_shift_op2") > > > > thing I suggested upthread. I think it's better for the define_insn > > attribute to specify the operand number directly, since there might > > well be cases where the shift isn't operand 2. > > Not in this case; all such insns always have it as op 2 in the machine > instruction, and RTL almost always uses the same order. > > > Anyway, I think we're in violent agreement on how this works, we're > > just taking different conclusions from it. > > Yeah :-) And not even so different: I think you agree it is a trade-off, you > just > see it tilt more to one side, while I see it go to the other side often. > > We still have over fifty instruction types. We (hopefully :-) ) use the > "extra > attribute" method only where that helps more than it hurts. It is just > another > tool in the toolbox. > > > Segher >