@@ -617,6 +617,143 @@ def DynamicCastInfoAttr
617
617
}];
618
618
}
619
619
620
+ //===----------------------------------------------------------------------===//
621
+ // AddressSpaceAttr
622
+ //===----------------------------------------------------------------------===//
623
+
624
+ // TODO: other CIR AS cases
625
+ def AS_Target : I32EnumAttrCase<"target", 21>;
626
+
627
+ def AddressSpaceAttr : CIR_Attr<"AddressSpace", "addrspace"> {
628
+
629
+ let summary = "Address space attribute for pointer types";
630
+ let description = [{
631
+ The address space attribute models `clang::LangAS` rather than the LLVM
632
+ address space, which means it's not yet converted by the address space map
633
+ to carry target-specific semantics.
634
+
635
+ The representation is one-to-one except for `LangAS::Default`, which
636
+ corresponds to a null attribute instead.
637
+ }];
638
+
639
+ let parameters = (ins "int32_t":$value);
640
+
641
+ let assemblyFormat = [{
642
+ `<` $value `>`
643
+ }];
644
+
645
+ let builders = [
646
+ AttrBuilder<(ins "clang::LangAS":$langAS), [{
647
+ assert(langAS != clang::LangAS::Default &&
648
+ "Default address space is encoded as null attribute");
649
+ return $_get($_ctxt, getValueFromLangAS(langAS).value());
650
+ }]>
651
+ ];
652
+
653
+ let cppNamespace = "::mlir::cir";
654
+
655
+ // The following codes implement these conversions:
656
+ // clang::LangAS -> int32_t <-> text-form CIR
657
+
658
+ // CIR_PointerType manipulates the parse- and stringify- methods to provide
659
+ // simplified assembly format `custom<PointerAddrSpace>`.
660
+
661
+ list<I32EnumAttrCase> langASCases = [
662
+ // TODO: includes all non-target CIR AS cases here
663
+ ];
664
+
665
+ I32EnumAttrCase targetASCase = AS_Target;
666
+
667
+ let extraClassDeclaration = [{
668
+ static constexpr char kTargetKeyword[] = "}]#targetASCase.symbol#[{";
669
+ static constexpr int32_t kFirstTargetASValue = }]#targetASCase.value#[{;
670
+
671
+ bool isLang() const;
672
+ bool isTarget() const;
673
+ unsigned getTargetValue() const;
674
+
675
+ static std::optional<int32_t> parseValueFromString(llvm::StringRef s);
676
+ static std::optional<int32_t> getValueFromLangAS(clang::LangAS v);
677
+ static std::optional<llvm::StringRef> stringifyValue(int32_t v);
678
+ }];
679
+
680
+ let extraClassDefinition = [{
681
+ bool $cppClass::isLang() const {
682
+ return !isTarget();
683
+ }
684
+
685
+ bool $cppClass::isTarget() const {
686
+ return getValue() >= kFirstTargetASValue;
687
+ }
688
+
689
+ unsigned $cppClass::getTargetValue() const {
690
+ assert(isTarget() && "Not a target address space");
691
+ return getValue() - kFirstTargetASValue;
692
+ }
693
+
694
+ std::optional<int32_t>
695
+ $cppClass::parseValueFromString(llvm::StringRef str) {
696
+ return llvm::StringSwitch<::std::optional<int32_t>>(str)
697
+ }]
698
+ #
699
+ !interleave(
700
+ !foreach(case, langASCases,
701
+ ".Case(\""#case.symbol# "\", "#case.value # ")\n"
702
+ ),
703
+ "\n"
704
+ )
705
+ #
706
+ [{
707
+ // Target address spaces are not parsed here
708
+ .Default(std::nullopt);
709
+ }
710
+
711
+ std::optional<llvm::StringRef>
712
+ $cppClass::stringifyValue(int32_t value) {
713
+ switch (value) {
714
+ }]
715
+ #
716
+ !interleave(
717
+ !foreach(case, langASCases,
718
+ "case "#case.value
719
+ # ": return \""#case.symbol # "\";" ),
720
+ "\n"
721
+ )
722
+ #
723
+ [{
724
+ default:
725
+ // Target address spaces are not processed here
726
+ return std::nullopt;
727
+ }
728
+ }
729
+
730
+ std::optional<int32_t>
731
+ $cppClass::getValueFromLangAS(clang::LangAS langAS) {
732
+ assert((langAS == clang::LangAS::Default ||
733
+ clang::isTargetAddressSpace(langAS)) &&
734
+ "Language-specific address spaces are not supported");
735
+ switch (langAS) {
736
+ }]
737
+ #
738
+ !interleave(
739
+ !foreach(case, langASCases,
740
+ "case clang::LangAS::"#case.symbol
741
+ # [{: llvm_unreachable("Not Yet Supported");}] ),
742
+ "\n"
743
+ )
744
+ #
745
+ [{
746
+ case clang::LangAS::Default:
747
+ // Default address space should be encoded as a null attribute.
748
+ return std::nullopt;
749
+ default:
750
+ // Target address space offset arithmetics
751
+ return clang::toTargetAddressSpace(langAS) + kFirstTargetASValue;
752
+ }
753
+ }
754
+ }];
755
+ }
756
+
620
757
//===----------------------------------------------------------------------===//
621
758
// AST Wrappers
622
759
//===----------------------------------------------------------------------===//
0 commit comments