================
@@ -1476,6 +1476,127 @@ static bool shouldExtendLifetime(const ASTContext 
&Context,
   return true;
 }
 
+/// Adds metadata for restrict-qualified pointers at any nesting level.
+///
+/// This function processes pointer types recursively to generate metadata
+/// for restrict-qualified pointers. The metadata encodes which pointer levels
+/// are restrict qualified and assigns unique identifiers to each restrict
+/// qualification level.
+///
+/// For example, consider the type `int * restrict * restrict` in foo():
+///   - First level: pointer to restrict pointer (gets unique code 1)
+///   - Second level: restrict pointer to int (gets another unique code 1)
+///
+/// The metadata structure is attached to the alloca instruction and consists
+/// of:
+///   1. Full variable name (function name + scope encoding)
+///   2. List of restrict codes for each pointer level:
+///      - Non-zero: unique identifier for restrict-qualified pointer
+///      - Zero: non-restrict qualified pointer at that level
+///
+/// For example, consider function `foo` with variable declarations:
+///   void foo() {
+///     int * restrict p1;       // Single-level restrict pointer
+///     int * restrict *p2;      // restrict at first level, non-restrict at
+///     second int * restrict * restrict p3;  // restrict at both levels
+///   }
+///
+/// Generated metadata would be:
+///   p1: !{!"foo_1", !{1}}          // One restrict level, code 1
+///   p2: !{!"foo_1", !{2, 0}}       // First level restrict (1), second
+///   non-restrict (0) p3: !{!"foo_1", !{3, 1}}       // First level restrict
+///   (1), second restrict (2)
+///
+/// The unique codes allow distinguishing different restrict pointers at the
+/// same nesting level within the same function and scope.
+///
+void CodeGenFunction::AddPointerMetodataForRestrict(RawAddress AllocaAddr,
+                                                    QualType Ty,
+                                                    llvm::StringRef FullName) {
+  auto *AllocaInst = cast<llvm::AllocaInst>(AllocaAddr.getPointer());
+
+  unsigned RestictNesting = 0;
+
+  llvm::SmallVector<llvm::Metadata *, 8> RestrictMDs;
+  llvm::LLVMContext &Ctx = AllocaInst->getContext();
+
+  while (const PointerType *PT = Ty->getAs<PointerType>()) {
+    if (Ty.isRestrictQualified()) {
+      if (RestictNesting >= RestrictCodes.size())
+        RestrictCodes.push_back(1);
+      unsigned Code = RestrictCodes[RestictNesting];
+      llvm::Constant *C =
+          llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), Code);
+      RestrictMDs.push_back(llvm::ConstantAsMetadata::get(C));
+      RestrictCodes[RestictNesting]++;
+    } else {
+      if (PT->getPointeeType()->getAs<RecordType>())
+        AddMetodataForRestrict(AllocaAddr, PT->getPointeeType(), FullName);
+      llvm::Constant *C =
+          llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), 0);
+      RestrictMDs.push_back(llvm::ConstantAsMetadata::get(C));
+    }
+    RestictNesting++;
+    Ty = PT->getPointeeType();
+  }
+  llvm::MDNode *RestrictList = llvm::MDNode::get(Ctx, RestrictMDs);
+  llvm::MDString *NameMD = llvm::MDString::get(Ctx, FullName.str());
+  llvm::MDNode *Node = llvm::MDNode::get(Ctx, {NameMD, RestrictList});
+  AllocaInst->setMetadata(llvm::LLVMContext::MD_scope, Node);
+}
+
+bool CodeGenFunction::IsRestrictExperimentalSupportEnabled() const {
+  return (getLangOpts().IsCLanguageOnly() &&
+          (CGM.getCodeGenOpts().RestrictExperimental));
+}
+
+/// Constructs metadata for variables in the current lexical scope.
+///
+/// This function builds a unique name for each variable by combining the
----------------
erichkeane wrote:

Why is the unique name required?  SHouldn't just attaching to each alloca be 
sufficient? 

https://github.com/llvm/llvm-project/pull/173394
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to