@@ -335,16 +335,15 @@ LogicalResult ProfileInfoDepot::populatationDispatch(Operation *op) {
335335// ===----------------------------------------------------------------------===//
336336
337337template <typename T>
338- FailureOr<SmallVector<T>>
339- TosaProfileCompliance::getOperatorDefinition (Operation *op,
340- CheckCondition &condition) {
338+ FailureOr<OpComplianceInfo<T>>
339+ TosaProfileCompliance::getOperatorDefinition (Operation *op) {
341340 const std::string opName = op->getName ().getStringRef ().str ();
342341 const auto complianceMap = getProfileComplianceMap<T>();
343342 const auto it = complianceMap.find (opName);
344343 if (it == complianceMap.end ())
345344 return {};
346345
347- return findMatchedProfile <T>(op, it->second , condition );
346+ return findMatchedEntry <T>(op, it->second );
348347}
349348
350349template <typename T>
@@ -356,22 +355,21 @@ LogicalResult TosaProfileCompliance::checkProfileOrExtension(
356355 if (specRequiredModeSet.size () == 0 )
357356 return success ();
358357
359- CheckCondition condition = CheckCondition::invalid;
360- const auto maybeOpRequiredMode = getOperatorDefinition<T>(op, condition);
361- if (failed (maybeOpRequiredMode)) {
358+ const auto maybeOpDefinition = getOperatorDefinition<T>(op);
359+ if (failed (maybeOpDefinition)) {
362360 // Operators such as control-flow and shape ops do not have an operand type
363361 // restriction. When the profile compliance information of operation is not
364362 // found, confirm if the target have enabled the profile required from the
365363 // specification.
366- int mode_count = 0 ;
364+ int modeCount = 0 ;
367365 for (const auto &cands : specRequiredModeSet) {
368366 if (targetEnv.allowsAnyOf (cands))
369367 return success ();
370- mode_count += cands.size ();
368+ modeCount += cands.size ();
371369 }
372370
373371 op->emitOpError () << " illegal: requires"
374- << (mode_count > 1 ? " any of " : " " ) << " ["
372+ << (modeCount > 1 ? " any of " : " " ) << " ["
375373 << llvm::join (stringifyProfile<T>(specRequiredModeSet),
376374 " , " )
377375 << " ] but not enabled in target\n " ;
@@ -381,7 +379,10 @@ LogicalResult TosaProfileCompliance::checkProfileOrExtension(
381379
382380 // Find the required profiles or extensions according to the operand type
383381 // combination.
384- const auto opRequiredMode = maybeOpRequiredMode.value ();
382+ const auto opDefinition = maybeOpDefinition.value ();
383+ const SmallVector<T> opRequiredMode = opDefinition.mode ;
384+ const CheckCondition condition = opDefinition.condition ;
385+
385386 if (opRequiredMode.size () == 0 ) {
386387 // No matched restriction found.
387388 return success ();
@@ -437,6 +438,21 @@ LogicalResult TosaProfileCompliance::checkProfileOrExtension(
437438 }
438439 }
439440
441+ // Ensure the matched op compliance version does not exceed the target
442+ // specification version.
443+ const VersionedTypeInfo versionedTypeInfo =
444+ opDefinition.operandTypeInfoSet [0 ];
445+ const TosaSpecificationVersion complianceVersion{versionedTypeInfo.second };
446+ const TosaSpecificationVersion targetVersion{targetEnv.getSpecVersion ()};
447+ if (!targetVersion.isBackwardsCompatibleWith (complianceVersion)) {
448+ op->emitOpError () << " illegal: the target specification version ("
449+ << stringifyVersion (targetVersion)
450+ << " ) is not backwards compatible with the op compliance "
451+ " specification version ("
452+ << stringifyVersion (complianceVersion) << " )\n " ;
453+ return failure ();
454+ }
455+
440456 return success ();
441457}
442458
@@ -461,14 +477,14 @@ TosaProfileCompliance::checkExtension(Operation *op,
461477}
462478
463479LogicalResult TosaProfileCompliance::checkInvalid (Operation *op) {
464- CheckCondition condition = CheckCondition::invalid;
465- const auto maybeProfDef = getOperatorDefinition<Profile>(op, condition);
466- const auto maybeExtDef = getOperatorDefinition<Extension>(op, condition);
480+ const auto maybeProfDef = getOperatorDefinition<Profile>(op);
481+ const auto maybeExtDef = getOperatorDefinition<Extension>(op);
467482 if (failed (maybeProfDef) && failed (maybeExtDef))
468483 return success ();
469484
470- const bool hasEntry = (succeeded (maybeProfDef) && !maybeProfDef->empty ()) ||
471- (succeeded (maybeExtDef) && !maybeExtDef->empty ());
485+ const bool hasEntry =
486+ (succeeded (maybeProfDef) && !maybeProfDef->mode .empty ()) ||
487+ (succeeded (maybeExtDef) && !maybeExtDef->mode .empty ());
472488 if (!hasEntry) {
473489 std::string message;
474490 llvm::raw_string_ostream os (message);
@@ -488,7 +504,9 @@ LogicalResult TosaProfileCompliance::checkInvalid(Operation *op) {
488504 SmallVector<TypeInfo> bestTypeInfo;
489505 const auto searchBestMatch = [&](auto map) {
490506 for (const auto &complianceInfos : map[opName]) {
491- for (const auto &typeInfos : complianceInfos.operandTypeInfoSet ) {
507+ for (const auto &versionedTypeInfos :
508+ complianceInfos.operandTypeInfoSet ) {
509+ const SmallVector<TypeInfo> typeInfos = versionedTypeInfos.first ;
492510 const int matches = llvm::count_if (
493511 llvm::zip_equal (current, typeInfos), [&](const auto zipType) {
494512 return isSameTypeInfo (std::get<0 >(zipType),
@@ -520,9 +538,8 @@ LogicalResult TosaProfileCompliance::checkInvalid(Operation *op) {
520538// Find the profiles or extensions requirement according to the signature of
521539// type of the operand list.
522540template <typename T>
523- SmallVector<T> TosaProfileCompliance::findMatchedProfile (
524- Operation *op, SmallVector<OpComplianceInfo<T>> compInfo,
525- CheckCondition &condition) {
541+ OpComplianceInfo<T> TosaProfileCompliance::findMatchedEntry (
542+ Operation *op, SmallVector<OpComplianceInfo<T>> compInfo) {
526543 assert (compInfo.size () != 0 &&
527544 " profile-based compliance information is empty" );
528545
@@ -533,27 +550,30 @@ SmallVector<T> TosaProfileCompliance::findMatchedProfile(
533550 return {};
534551
535552 for (size_t i = 0 ; i < compInfo.size (); i++) {
536- SmallVector<SmallVector<TypeInfo>> sets = compInfo[i].operandTypeInfoSet ;
537- for (SmallVector<TypeInfo> expected : sets) {
553+ SmallVector<VersionedTypeInfo> sets = compInfo[i].operandTypeInfoSet ;
554+ for (const auto &set : sets) {
555+ SmallVector<TypeInfo> expected = set.first ;
538556 assert (present.size () == expected.size () &&
539557 " the entries for profile-based compliance do not match between "
540558 " the generated metadata and the type definition retrieved from "
541559 " the operation" );
542560
543- bool is_found = true ;
561+ bool isFound = true ;
544562 // Compare the type signature between the given operation and the
545563 // compliance metadata.
546564 for (size_t j = 0 ; j < expected.size (); j++) {
547565 if (!isSameTypeInfo (present[j], expected[j])) {
548566 // Verify the next mode set from the list.
549- is_found = false ;
567+ isFound = false ;
550568 break ;
551569 }
552570 }
553571
554- if (is_found == true ) {
555- condition = compInfo[i].condition ;
556- return compInfo[i].mode ;
572+ if (isFound == true ) {
573+ SmallVector<VersionedTypeInfo> typeInfoSet{set};
574+ OpComplianceInfo<T> info{compInfo[i].mode , typeInfoSet,
575+ compInfo[i].condition };
576+ return info;
557577 }
558578 }
559579 }
0 commit comments