[llvm-branch-commits] [clang] [llvm] clang: Store Triple in multiset (PR #189264)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Mar 29 10:25:36 PDT 2026


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/189264

>From 3fe1fd18b4c657896b82c1f5ade10f086229aa71 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sun, 29 Mar 2026 11:34:53 +0200
Subject: [PATCH] clang: Store Triple in multiset

Previously this was storing StringRefs, which just happen
to be constant allocated strings. Change this into an owning
reference in the form that will actually be used. This will allow
changing the triples to something computed without maintaining
a table of every possible permutation.
---
 clang/include/clang/Driver/ToolChain.h  |  4 +++
 clang/lib/Driver/Driver.cpp             | 36 ++++++++++++++-----------
 llvm/include/llvm/TargetParser/Triple.h |  7 +++++
 3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 5e111c43b717d..7f6d779565434 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -863,6 +863,10 @@ class ToolChain {
     }
     return TT;
   }
+
+  static llvm::Triple getOpenMPTriple(const llvm::Triple &OrigTT) {
+    return getOpenMPTriple(OrigTT.str());
+  }
 };
 
 /// Set a ToolChain's effective triple. Reset it when the registration object
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index d58cc3b2d72c2..aff34603b8b86 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -943,10 +943,12 @@ getSystemOffloadArchs(Compilation &C, Action::OffloadKind Kind) {
   return GPUArchs;
 }
 
+using TripleSet = std::multiset<llvm::Triple>;
+
 // Attempts to infer the correct offloading toolchain triple by looking at the
 // requested offloading kind and architectures.
-static std::multiset<llvm::StringRef>
-inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind) {
+static TripleSet inferOffloadToolchains(Compilation &C,
+                                        Action::OffloadKind Kind) {
   std::set<std::string> Archs;
   for (Arg *A : C.getInputArgs()) {
     for (StringRef Arch : A->getValues()) {
@@ -966,7 +968,7 @@ inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind) {
     }
   }
 
-  std::multiset<llvm::StringRef> Triples;
+  TripleSet Triples;
   for (llvm::StringRef Arch : Archs) {
     OffloadArch ID = StringToOffloadArch(Arch);
     if (ID == OffloadArch::Unknown)
@@ -1013,20 +1015,22 @@ inferOffloadToolchains(Compilation &C, Action::OffloadKind Kind) {
     A->claim();
     C.getArgs().append(A);
     C.getArgs().AddSynthesizedArg(A);
-    Triples.insert(TripleStr);
+    Triples.insert(Triple);
   }
 
   // Infer the default target triple if no specific architectures are given.
   if (Archs.empty() && Kind == Action::OFK_HIP)
-    Triples.insert("amdgcn-amd-amdhsa");
+    Triples.insert(llvm::Triple("amdgcn-amd-amdhsa"));
   else if (Archs.empty() && Kind == Action::OFK_Cuda)
-    Triples.insert(C.getDefaultToolChain().getTriple().isArch64Bit()
-                       ? "nvptx64-nvidia-cuda"
-                       : "nvptx-nvidia-cuda");
+    Triples.insert(
+        llvm::Triple(C.getDefaultToolChain().getTriple().isArch64Bit()
+                         ? "nvptx64-nvidia-cuda"
+                         : "nvptx-nvidia-cuda"));
   else if (Archs.empty() && Kind == Action::OFK_SYCL)
-    Triples.insert(C.getDefaultToolChain().getTriple().isArch64Bit()
-                       ? "spirv64-unknown-unknown"
-                       : "spirv32-unknown-unknown");
+    Triples.insert(
+        llvm::Triple(C.getDefaultToolChain().getTriple().isArch64Bit()
+                         ? "spirv64-unknown-unknown"
+                         : "spirv32-unknown-unknown"));
 
   // We need to dispatch these to the appropriate toolchain now.
   C.getArgs().eraseArg(options::OPT_offload_arch_EQ);
@@ -1088,12 +1092,12 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
   // Get the list of requested offloading toolchains. If they were not
   // explicitly specified we will infer them based on the offloading language
   // and requested architectures.
-  std::multiset<llvm::StringRef> Triples;
+  TripleSet Triples;
   if (C.getInputArgs().hasArg(options::OPT_offload_targets_EQ)) {
     std::vector<std::string> ArgValues =
         C.getInputArgs().getAllArgValues(options::OPT_offload_targets_EQ);
     for (llvm::StringRef Target : ArgValues)
-      Triples.insert(C.getInputArgs().MakeArgString(Target));
+      Triples.insert(llvm::Triple(C.getInputArgs().MakeArgString(Target)));
 
     if (ArgValues.empty())
       Diag(clang::diag::warn_drv_empty_joined_argument)
@@ -1107,7 +1111,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
 
   // Build an offloading toolchain for every requested target and kind.
   llvm::StringMap<StringRef> FoundNormalizedTriples;
-  for (StringRef Target : Triples) {
+  for (const llvm::Triple &Target : Triples) {
     // OpenMP offloading requires a compatible libomp.
     if (Kinds.contains(Action::OFK_OpenMP)) {
       OpenMPRuntimeKind RuntimeKind = getOpenMPRuntime(C.getInputArgs());
@@ -1138,10 +1142,10 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
 
       std::string NormalizedName = TT.normalize();
       auto [TripleIt, Inserted] =
-          FoundNormalizedTriples.try_emplace(NormalizedName, Target);
+          FoundNormalizedTriples.try_emplace(NormalizedName, Target.str());
       if (!Inserted) {
         Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
-            << Target << TripleIt->second;
+            << Target.str() << TripleIt->second;
         continue;
       }
 
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 8d238a527b7f1..d891b53a62e9d 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -387,6 +387,13 @@ class Triple {
     return !(*this == Other);
   }
 
+  bool operator<(const Triple &Other) const {
+    return std::tie(Arch, SubArch, Vendor, OS, Environment, ObjectFormat,
+                    Data) < std::tie(Other.Arch, Other.SubArch, Other.Vendor,
+                                     Other.OS, Other.Environment,
+                                     Other.ObjectFormat, Other.Data);
+  }
+
   /// @}
   /// @name Normalization
   /// @{



More information about the llvm-branch-commits mailing list