[clang] b5437c8 - [clang][Interp] Emit const references for Float arguments (#79753)

via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 21 05:15:43 PST 2024


Author: Timm Baeder
Date: 2024-02-21T14:15:39+01:00
New Revision: b5437c8ab2af277548ee59b6838e365d35a0d926

URL: https://github.com/llvm/llvm-project/commit/b5437c8ab2af277548ee59b6838e365d35a0d926
DIFF: https://github.com/llvm/llvm-project/commit/b5437c8ab2af277548ee59b6838e365d35a0d926.diff

LOG: [clang][Interp] Emit const references for Float arguments (#79753)

The Float print type is backed by the Floating class, which in turn uses
APFloat, which might heap-allocate memory, so might be expensive to
copy.

Add an 'AsRef' bit to the ArgType tablegen class, which defines whether
we pass the argument around by copy or by reference.

Added: 
    

Modified: 
    clang/lib/AST/Interp/Opcodes.td
    clang/utils/TableGen/ClangOpcodesEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index f1b08944a8812e..5add723842d2b2 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -35,7 +35,7 @@ def FnPtr : Type;
 // Types transferred to the interpreter.
 //===----------------------------------------------------------------------===//
 
-class ArgType { string Name = ?; }
+class ArgType { string Name = ?; bit AsRef = false; }
 def ArgSint8 : ArgType { let Name = "int8_t"; }
 def ArgUint8 : ArgType { let Name = "uint8_t"; }
 def ArgSint16 : ArgType { let Name = "int16_t"; }
@@ -44,9 +44,9 @@ def ArgSint32 : ArgType { let Name = "int32_t"; }
 def ArgUint32 : ArgType { let Name = "uint32_t"; }
 def ArgSint64 : ArgType { let Name = "int64_t"; }
 def ArgUint64 : ArgType { let Name = "uint64_t"; }
-def ArgFloat : ArgType { let Name = "Floating"; }
-def ArgIntAP : ArgType { let Name = "IntegralAP<false>"; }
-def ArgIntAPS : ArgType { let Name = "IntegralAP<true>"; }
+def ArgIntAP : ArgType { let Name = "IntegralAP<false>"; let AsRef = true; }
+def ArgIntAPS : ArgType { let Name = "IntegralAP<true>"; let AsRef = true; }
+def ArgFloat : ArgType { let Name = "Floating"; let AsRef = true; }
 def ArgBool : ArgType { let Name = "bool"; }
 
 def ArgFunction : ArgType { let Name = "const Function *"; }

diff  --git a/clang/utils/TableGen/ClangOpcodesEmitter.cpp b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
index 02d5f9512d9051..1c41301ab3aeeb 100644
--- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
@@ -126,9 +126,15 @@ void ClangOpcodesEmitter::EmitInterp(raw_ostream &OS, StringRef N,
 
               // Emit calls to read arguments.
               for (size_t I = 0, N = Args.size(); I < N; ++I) {
-                OS << "  auto V" << I;
+                const auto *Arg = Args[I];
+                bool AsRef = Arg->getValueAsBit("AsRef");
+
+                if (AsRef)
+                  OS << "  const auto &V" << I;
+                else
+                  OS << "  const auto V" << I;
                 OS << " = ";
-                OS << "ReadArg<" << Args[I]->getValueAsString("Name")
+                OS << "ReadArg<" << Arg->getValueAsString("Name")
                    << ">(S, PC);\n";
               }
 
@@ -192,8 +198,14 @@ void ClangOpcodesEmitter::EmitEmitter(raw_ostream &OS, StringRef N,
 
     // Emit the list of arguments.
     OS << "bool ByteCodeEmitter::emit" << ID << "(";
-    for (size_t I = 0, N = Args.size(); I < N; ++I)
-      OS << Args[I]->getValueAsString("Name") << " A" << I << ", ";
+    for (size_t I = 0, N = Args.size(); I < N; ++I) {
+      const auto *Arg = Args[I];
+      bool AsRef = Arg->getValueAsBit("AsRef");
+      auto Name = Arg->getValueAsString("Name");
+
+      OS << (AsRef ? "const " : " ") << Name << " " << (AsRef ? "&" : "") << "A"
+         << I << ", ";
+    }
     OS << "const SourceInfo &L) {\n";
 
     // Emit a call to write the opcodes.
@@ -218,8 +230,14 @@ void ClangOpcodesEmitter::EmitProto(raw_ostream &OS, StringRef N,
   auto Args = R->getValueAsListOfDefs("Args");
   Enumerate(R, N, [&OS, &Args](ArrayRef<const Record *> TS, const Twine &ID) {
     OS << "bool emit" << ID << "(";
-    for (auto *Arg : Args)
-      OS << Arg->getValueAsString("Name") << ", ";
+    for (size_t I = 0, N = Args.size(); I < N; ++I) {
+      const auto *Arg = Args[I];
+      bool AsRef = Arg->getValueAsBit("AsRef");
+      auto Name = Arg->getValueAsString("Name");
+
+      OS << (AsRef ? "const " : " ") << Name << " " << (AsRef ? "&" : "")
+         << ", ";
+    }
     OS << "const SourceInfo &);\n";
   });
 
@@ -275,8 +293,14 @@ void ClangOpcodesEmitter::EmitGroup(raw_ostream &OS, StringRef N,
   OS << "::" << EmitFuncName << "(";
   for (size_t I = 0, N = Types->size(); I < N; ++I)
     OS << "PrimType T" << I << ", ";
-  for (size_t I = 0, N = Args.size(); I < N; ++I)
-    OS << Args[I]->getValueAsString("Name") << " A" << I << ", ";
+  for (size_t I = 0, N = Args.size(); I < N; ++I) {
+    const auto *Arg = Args[I];
+    bool AsRef = Arg->getValueAsBit("AsRef");
+    auto Name = Arg->getValueAsString("Name");
+
+    OS << (AsRef ? "const " : " ") << Name << " " << (AsRef ? "&" : "") << "A"
+       << I << ", ";
+  }
   OS << "const SourceInfo &I) {\n";
 
   std::function<void(size_t, const Twine &)> Rec;
@@ -343,8 +367,14 @@ void ClangOpcodesEmitter::EmitEval(raw_ostream &OS, StringRef N,
               auto Args = R->getValueAsListOfDefs("Args");
 
               OS << "bool EvalEmitter::emit" << ID << "(";
-              for (size_t I = 0, N = Args.size(); I < N; ++I)
-                OS << Args[I]->getValueAsString("Name") << " A" << I << ", ";
+              for (size_t I = 0, N = Args.size(); I < N; ++I) {
+                const auto *Arg = Args[I];
+                bool AsRef = Arg->getValueAsBit("AsRef");
+                auto Name = Arg->getValueAsString("Name");
+
+                OS << (AsRef ? "const " : " ") << Name << " "
+                   << (AsRef ? "&" : "") << "A" << I << ", ";
+              }
               OS << "const SourceInfo &L) {\n";
               OS << "  if (!isActive()) return true;\n";
               OS << "  CurrentSource = L;\n";


        


More information about the cfe-commits mailing list