Hi, On Thu, 23 Nov 2017, Richard Sandiford wrote:
> > I don't want variable-size vector special-casing everywhere. I want > > it to be somehow naturally integrating with existing stuff. > > It's going to be a special case whatever happens though. It wouldn't have to be this way. It's like saying that loops with a constant upper bound should be represented in a different way than loops with an invariant upper bound. That would seem like a bad idea. > If it's a VEC_PERM_EXPR then it'll be a new form of VEC_PERM_EXPR. No, it'd be a VEC_PERM_EXPR where the magic mask is generated by a new EXPR type, instead of being a mere constant. > The advantage of the internal functions and optabs is that they map to a > concept that already exists. The code that generates the permutation > already knows that it's generating an interleave lo/hi, and like you > say, it used to do that directly via special tree codes. I agree that > having a VEC_PERM_EXPR makes more sense for the constant-length case, > but the concept is still there. > > And although using VEC_PERM_EXPR in gimple makes sense, I think not > having the optabs is a step backwards, because it means that every > target with interleave lo/hi has to duplicate the detection logic. The middle end can provide helper routines to make detection easy. The RTL expander could also match VEC_PERM_EXPR to specific optabs, if we really really want to add optab over optab for each specific kind of permutation in the future. In a way the difference boils down to have PERM(x,y, TYPE) (with TYPE being, say, HI_LO, EXTR_EVEN/ODD, REVERSE, and what not) vs. PERM_HI_LO(x,y) PERM_EVEN(x,y) PERM_ODD(x,y) PERM_REVERSE(x,y) ... The former way seems saner for an intermediate representation. In this specific case TYPE would be detected by magicness of the constant, and if extended to SVE by magicness of the definition of the variably-sized invariant. > > I'm not suggesting to expose it as an operation. I'm suggesting that > > if the target can vec_perm_const_ok () with an "interleave/extract" > > permutation then we should be able to represent that with > > VEC_PERM_EXPR and thus also represent the permutation vector. > > But vec_perm_const_ok () takes a fixed-length mask, so it can't be > used here. It would need to be a new hook (and thus a new special > case for variable-length vectors). Why do you reject extending vec_perm_const_ok to _do_ take an invarant mask? > > But is there more? Possibly a generic permute but for it you'd have > > to explicitely construct a permutation vector using some primitives > > like that "series" instruction? So for that case it's reasonable to > > have GIMPLE like > > > > perm_vector_1 = VEC_SERIES_EXRP <...> > > ... > > v_2 = VEC_PERM_EXPR <.., .., perm_vector_1>; > > > > that is, it's not required to pretend the VEC_PERM_EXRP is a single > > instruction or the permutation vector is "constant"? > > ...by taking this approach, we're saying that we need to ensure that > there is always a way of representing every directly-supported variable- > length permutation mask as a constant, so that it doesn't get split from > VEC_PERM_EXPR. I'm having trouble understanding this. Why would splitting away the defintion of perm_vector_1 from VEC_PERM_EXPR be a problem? It's still the same VEC_SERIES_EXRP, and hence still recognizable as a special permutation (if it is one). The optimizer won't touch VEC_SERIES_EXRP, or if they do (e.g. combine two of them), and they feed a VEC_PERM_EXPR they will make sure the combined result still is supported by the target. In a way, on targets which support only specific forms of permutation for the vector type in question, this invariant mask won't be explicitely generated in code, it's an abstract tag in the IR to specific the type of the transformation. Hence moving the def for that tag around is no problem. > I don't see why that's better than having internal > functions. The real difference isn't internal functions vs. expression nodes, but rather multiple node types vs. a single node type. Ciao, Michael.