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

2024-02-21 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/79753
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-02-20 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman approved this pull request.

LGTM!

https://github.com/llvm/llvm-project/pull/79753
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-02-19 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/79753
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-02-13 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/79753
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-02-05 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/79753

>From 0e108e92b3165f95a934895e14f6c330f6c5e3fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 28 Jan 2024 16:13:08 +0100
Subject: [PATCH] [clang][Interp] Emit const references for Float arguments

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.
---
 clang/lib/AST/Interp/Opcodes.td  |  8 ++--
 clang/utils/TableGen/ClangOpcodesEmitter.cpp | 50 
 2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index e720b95498f17..b33741c0e5a68 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"; }
-def ArgIntAPS : ArgType { let Name = "IntegralAP"; }
+def ArgIntAP : ArgType { let Name = "IntegralAP"; let AsRef = true; }
+def ArgIntAPS : ArgType { let Name = "IntegralAP"; 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 02d5f9512d905..1c41301ab3aee 100644
--- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
@@ -126,9 +126,15 @@ void ClangOpcodesEmitter::EmitInterp(raw_ostream , 
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 " << 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 , 
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 ) {\n";
 
 // Emit a call to write the opcodes.
@@ -218,8 +230,14 @@ void ClangOpcodesEmitter::EmitProto(raw_ostream , 
StringRef N,
   auto Args = R->getValueAsListOfDefs("Args");
   Enumerate(R, N, [, ](ArrayRef TS, const Twine ) {
 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 , 
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 << 

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

2024-01-28 Thread Timm Baeder via cfe-commits

tbaederr wrote:

For reference, the generated code with this patch looks like this:

```c++
#if defined(GET_EVAL_PROTO) || defined(GET_LINK_PROTO)
bool emitConstFloat(const Floating &, const SourceInfo &);
#endif
#ifdef GET_LINK_IMPL
bool ByteCodeEmitter::emitConstFloat(const Floating , const SourceInfo ) {
  return emitOp(OP_ConstFloat, A0, L);
}
#endif
#ifdef GET_EVAL_IMPL
bool EvalEmitter::emitConstFloat(const Floating , const SourceInfo ) {
  if (!isActive()) return true;
  CurrentSource = L;
  return Const(S, OpPC, A0);
}
#endif
```

Where all those `const Floating &` arguments were just `Floating` before.


https://github.com/llvm/llvm-project/pull/79753
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-01-28 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/79753.diff


2 Files Affected:

- (modified) clang/lib/AST/Interp/Opcodes.td (+2-2) 
- (modified) clang/utils/TableGen/ClangOpcodesEmitter.cpp (+40-10) 


``diff
diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 24747b6b98c163..6283e388d7a526 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,7 +44,7 @@ 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 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 , 
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 " << 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 , 
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 ) {\n";
 
 // Emit a call to write the opcodes.
@@ -218,8 +230,14 @@ void ClangOpcodesEmitter::EmitProto(raw_ostream , 
StringRef N,
   auto Args = R->getValueAsListOfDefs("Args");
   Enumerate(R, N, [, ](ArrayRef TS, const Twine ) {
 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 , 
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 ) {\n";
 
   std::function Rec;
@@ -343,8 +367,14 @@ void ClangOpcodesEmitter::EmitEval(raw_ostream , 
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 

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

2024-01-28 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/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.

>From f45b08cd965b2bc281c1fcb50ace203c5e8879dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 28 Jan 2024 16:13:08 +0100
Subject: [PATCH] [clang][Interp] Emit const references for Float arguments

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.
---
 clang/lib/AST/Interp/Opcodes.td  |  4 +-
 clang/utils/TableGen/ClangOpcodesEmitter.cpp | 50 
 2 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 24747b6b98c163e..6283e388d7a5260 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,7 +44,7 @@ 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 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 02d5f9512d90514..1c41301ab3aeeba 100644
--- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
@@ -126,9 +126,15 @@ void ClangOpcodesEmitter::EmitInterp(raw_ostream , 
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 " << 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 , 
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 ) {\n";
 
 // Emit a call to write the opcodes.
@@ -218,8 +230,14 @@ void ClangOpcodesEmitter::EmitProto(raw_ostream , 
StringRef N,
   auto Args = R->getValueAsListOfDefs("Args");
   Enumerate(R, N, [, ](ArrayRef TS, const Twine ) {
 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 , 
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"
+