================
@@ -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