@@ -47,6 +47,7 @@ enum Kind : unsigned {
4747 OperandPos,
4848 OperandGroupPos,
4949 AttributePos,
50+ ConstraintResultPos,
5051 ResultPos,
5152 ResultGroupPos,
5253 TypePos,
@@ -187,6 +188,25 @@ struct AttributeLiteralPosition
187188 using PredicateBase::PredicateBase;
188189};
189190
191+ // ===----------------------------------------------------------------------===//
192+ // ConstraintPosition
193+
194+ struct ConstraintQuestion ;
195+
196+ // / A position describing the result of a native constraint. It saves the
197+ // / corresponding ConstraintQuestion and result index to enable referring
198+ // / back to them
199+ struct ConstraintPosition
200+ : public PredicateBase<ConstraintPosition, Position,
201+ std::pair<ConstraintQuestion *, unsigned >,
202+ Predicates::ConstraintResultPos> {
203+ using PredicateBase::PredicateBase;
204+
205+ ConstraintQuestion *getQuestion () const { return key.first ; }
206+
207+ unsigned getIndex () const { return key.second ; }
208+ };
209+
190210// ===----------------------------------------------------------------------===//
191211// ForEachPosition
192212
@@ -447,11 +467,13 @@ struct AttributeQuestion
447467 : public PredicateBase<AttributeQuestion, Qualifier, void ,
448468 Predicates::AttributeQuestion> {};
449469
450- // / Apply a parameterized constraint to multiple position values.
470+ // / Apply a parameterized constraint to multiple position values and possibly
471+ // / produce results.
451472struct ConstraintQuestion
452- : public PredicateBase<ConstraintQuestion, Qualifier,
453- std::tuple<StringRef, ArrayRef<Position *>>,
454- Predicates::ConstraintQuestion> {
473+ : public PredicateBase<
474+ ConstraintQuestion, Qualifier,
475+ std::tuple<StringRef, ArrayRef<Position *>, ArrayRef<Type>>,
476+ Predicates::ConstraintQuestion> {
455477 using Base::Base;
456478
457479 // / Return the name of the constraint.
@@ -460,11 +482,15 @@ struct ConstraintQuestion
460482 // / Return the arguments of the constraint.
461483 ArrayRef<Position *> getArgs () const { return std::get<1 >(key); }
462484
485+ // / Return the result types of the constraint.
486+ ArrayRef<Type> getResultTypes () const { return std::get<2 >(key); }
487+
463488 // / Construct an instance with the given storage allocator.
464489 static ConstraintQuestion *construct (StorageUniquer::StorageAllocator &alloc,
465490 KeyTy key) {
466491 return Base::construct (alloc, KeyTy{alloc.copyInto (std::get<0 >(key)),
467- alloc.copyInto (std::get<1 >(key))});
492+ alloc.copyInto (std::get<1 >(key)),
493+ alloc.copyInto (std::get<2 >(key))});
468494 }
469495};
470496
@@ -517,6 +543,7 @@ class PredicateUniquer : public StorageUniquer {
517543 // Register the types of Positions with the uniquer.
518544 registerParametricStorageType<AttributePosition>();
519545 registerParametricStorageType<AttributeLiteralPosition>();
546+ registerParametricStorageType<ConstraintPosition>();
520547 registerParametricStorageType<ForEachPosition>();
521548 registerParametricStorageType<OperandPosition>();
522549 registerParametricStorageType<OperandGroupPosition>();
@@ -579,6 +606,12 @@ class PredicateBuilder {
579606 return OperationPosition::get (uniquer, p);
580607 }
581608
609+ // Returns a position for a new value created by a constraint.
610+ ConstraintPosition *getConstraintPosition (ConstraintQuestion *q,
611+ unsigned index) {
612+ return ConstraintPosition::get (uniquer, std::make_pair (q, index));
613+ }
614+
582615 // / Returns an attribute position for an attribute of the given operation.
583616 Position *getAttribute (OperationPosition *p, StringRef name) {
584617 return AttributePosition::get (uniquer, p, StringAttr::get (ctx, name));
@@ -664,8 +697,10 @@ class PredicateBuilder {
664697 }
665698
666699 // / Create a predicate that applies a generic constraint.
667- Predicate getConstraint (StringRef name, ArrayRef<Position *> pos) {
668- return {ConstraintQuestion::get (uniquer, std::make_tuple (name, pos)),
700+ Predicate getConstraint (StringRef name, ArrayRef<Position *> args,
701+ ArrayRef<Type> resultTypes) {
702+ return {ConstraintQuestion::get (uniquer,
703+ std::make_tuple (name, args, resultTypes)),
669704 TrueAnswer::get (uniquer)};
670705 }
671706
0 commit comments