[llvm] [Attributor] Pack out arguments into a struct (PR #119267)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 26 05:02:04 PST 2024


================
@@ -12989,6 +12991,179 @@ struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
 };
 } // namespace
 
+/// ----------- AAConvertOutArgument ----------
+namespace {
+struct AAConvertOutArgumentFunction final : AAConvertOutArgument {
+  AAConvertOutArgumentFunction(const IRPosition &IRP, Attributor &A)
+      : AAConvertOutArgument(IRP, A) {}
+
+  /// See AbstractAttribute::updateImpl(...).
+  ChangeStatus updateImpl(Attributor &A) override {
+    const Function *F = getAssociatedFunction();
+    if (!F || F->isDeclaration())
+      return indicatePessimisticFixpoint();
+
+    bool hasCandidateArg = false;
+    for (const Argument &Arg : F->args())
+      if (Arg.getType()->isPointerTy() && isEligibleArgument(Arg, A, *this))
+        hasCandidateArg = true;
+
+    return hasCandidateArg ? indicateOptimisticFixpoint()
+                           : indicatePessimisticFixpoint();
+  }
+
+  /// See AbstractAttribute::manifest(...).
+  ChangeStatus manifest(Attributor &A) override {
+    const Function &F = *getAssociatedFunction();
+    DenseMap<Argument*, Type*> PtrToType;
+    SmallVector<Argument *, 4> CandidateArgs;
+    for (unsigned argIdx = 0; argIdx < F.arg_size(); ++argIdx) {
+      Argument *Arg = F.getArg(argIdx);
+      if (isEligibleArgument(*Arg, A, *this)) {
+        CandidateArgs.push_back(Arg);
+        for (auto UseItr = Arg->use_begin(); UseItr != Arg->use_end(); ++UseItr) {
+          auto *Store = dyn_cast<StoreInst>(UseItr->getUser());
+          if (Store)
+            PtrToType[Arg] = Store->getValueOperand()->getType();
+        }
+      }
+    }
+
+    // If there is no valid candidates then return false.
+    if (PtrToType.empty())
+      return ChangeStatus::UNCHANGED;
+
+    // Create the new struct return type.
+    SmallVector<Type *, 4> OutStructElementsTypes;
+    if (auto *OriginalFuncTy = F.getReturnType(); !OriginalFuncTy->isVoidTy())
+      OutStructElementsTypes.push_back(OriginalFuncTy);
----------------
arsenm wrote:

If the function already has a struct return, you could flatten and insert directly into the struct type. It may be a little more effort to emit though.

You also should check whether TargetLowering::CanLowerReturn succeeds, you should avoid over-committing return values if they're going to be forced to the stack. As written out arguments may be in any address space, not just allocas 

https://github.com/llvm/llvm-project/pull/119267


More information about the llvm-commits mailing list