llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

Quite a few opcode implementations don't ever report a diagnostic, so they 
don't need the `OpPC` at all. Add a tablegen bit to disable passing `OpPC` 
altogether.

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


5 Files Affected:

- (modified) clang/lib/AST/ByteCode/EvalEmitter.cpp (+2-2) 
- (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-4) 
- (modified) clang/lib/AST/ByteCode/Interp.h (+27-28) 
- (modified) clang/lib/AST/ByteCode/Opcodes.td (+22-24) 
- (modified) clang/utils/TableGen/ClangOpcodesEmitter.cpp (+14-4) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp 
b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index dbec700c80d44..34c85c7c66bdd 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -209,8 +209,8 @@ bool EvalEmitter::speculate(const CallExpr *E, const 
LabelTy &EndLabel) {
   if (!isActive())
     return true;
 
-  PushIgnoreDiags(S, OpPC);
-  auto _ = llvm::scope_exit([&]() { PopIgnoreDiags(S, OpPC); });
+  PushIgnoreDiags(S);
+  auto _ = llvm::scope_exit([&]() { PopIgnoreDiags(S); });
 
   size_t StackSizeBefore = S.Stk.size();
   const Expr *Arg = E->getArg(0);
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index dc93cc4fd698c..6d9b8bc78668f 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -2891,7 +2891,7 @@ static void finishGlobalRecurse(InterpState &S, const 
Pointer &Ptr) {
   }
 }
 
-bool FinishInitGlobal(InterpState &S, CodePtr OpPC) {
+bool FinishInitGlobal(InterpState &S) {
   const Pointer &Ptr = S.Stk.pop<Pointer>();
 
   finishGlobalRecurse(S, Ptr);
@@ -3175,10 +3175,10 @@ PRESERVE_NONE static bool BCP(InterpState &S, CodePtr 
OpPC, int32_t Offset,
   assert(DepthBefore >= 1);
 #endif
 
-  auto SpeculativeInterp = [&S, OpPC]() -> bool {
+  auto SpeculativeInterp = [&S]() -> bool {
     // Ignore diagnostics during speculative execution.
-    PushIgnoreDiags(S, OpPC);
-    auto _ = llvm::scope_exit([&]() { PopIgnoreDiags(S, OpPC); });
+    PushIgnoreDiags(S);
+    auto _ = llvm::scope_exit([&]() { PopIgnoreDiags(S); });
 
 #if USE_TAILCALLS
     auto Op = S.PC.read<Opcode>();
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 61c2b0a5e5960..26cada1685186 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1537,20 +1537,19 @@ bool GE(InterpState &S, CodePtr OpPC) {
 
//===----------------------------------------------------------------------===//
 
 template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Dup(InterpState &S, CodePtr OpPC) {
+bool Dup(InterpState &S) {
   S.Stk.push<T>(S.Stk.peek<T>());
   return true;
 }
 
 template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Pop(InterpState &S, CodePtr OpPC) {
+bool Pop(InterpState &S) {
   S.Stk.discard<T>();
   return true;
 }
 
 /// [Value1, Value2] -> [Value2, Value1]
-template <PrimType TopName, PrimType BottomName>
-bool Flip(InterpState &S, CodePtr OpPC) {
+template <PrimType TopName, PrimType BottomName> bool Flip(InterpState &S) {
   using TopT = typename PrimConv<TopName>::T;
   using BottomT = typename PrimConv<BottomName>::T;
 
@@ -1568,7 +1567,7 @@ bool Flip(InterpState &S, CodePtr OpPC) {
 
//===----------------------------------------------------------------------===//
 
 template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Const(InterpState &S, CodePtr OpPC, const T &Arg) {
+bool Const(InterpState &S, const T &Arg) {
   if constexpr (needsAlloc<T>()) {
     T Result = S.allocAP<T>(Arg.bitWidth());
     Result.copy(Arg.toAPSInt());
@@ -1596,7 +1595,7 @@ bool Const(InterpState &S, CodePtr OpPC, const T &Arg) {
   return true;
 }
 
-inline bool ConstFloat(InterpState &S, CodePtr OpPC, const Floating &F) {
+inline bool ConstFloat(InterpState &S, const Floating &F) {
   Floating Result = S.allocFloat(F.getSemantics());
   Result.copy(F.getAPFloat());
   S.Stk.push<Floating>(Result);
@@ -2120,21 +2119,21 @@ inline bool GetPtrThisBase(InterpState &S, CodePtr 
OpPC, uint32_t Off) {
   return true;
 }
 
-inline bool FinishInitPop(InterpState &S, CodePtr OpPC) {
+inline bool FinishInitPop(InterpState &S) {
   const Pointer &Ptr = S.Stk.pop<Pointer>();
   if (Ptr.canBeInitialized())
     Ptr.initialize();
   return true;
 }
 
-inline bool FinishInit(InterpState &S, CodePtr OpPC) {
+inline bool FinishInit(InterpState &S) {
   const Pointer &Ptr = S.Stk.peek<Pointer>();
   if (Ptr.canBeInitialized())
     Ptr.initialize();
   return true;
 }
 
-inline bool FinishInitActivate(InterpState &S, CodePtr OpPC) {
+inline bool FinishInitActivate(InterpState &S) {
   const Pointer &Ptr = S.Stk.peek<Pointer>();
   if (Ptr.canBeInitialized()) {
     Ptr.initialize();
@@ -2143,7 +2142,7 @@ inline bool FinishInitActivate(InterpState &S, CodePtr 
OpPC) {
   return true;
 }
 
-inline bool FinishInitActivatePop(InterpState &S, CodePtr OpPC) {
+inline bool FinishInitActivatePop(InterpState &S) {
   const Pointer &Ptr = S.Stk.pop<Pointer>();
   if (Ptr.canBeInitialized()) {
     Ptr.initialize();
@@ -2152,7 +2151,7 @@ inline bool FinishInitActivatePop(InterpState &S, CodePtr 
OpPC) {
   return true;
 }
 
-bool FinishInitGlobal(InterpState &S, CodePtr OpPC);
+bool FinishInitGlobal(InterpState &S);
 
 inline bool Dump(InterpState &S, CodePtr OpPC) {
   S.Stk.dump();
@@ -2261,14 +2260,14 @@ bool StorePop(InterpState &S, CodePtr OpPC) {
   return true;
 }
 
-static inline bool Activate(InterpState &S, CodePtr OpPC) {
+static inline bool Activate(InterpState &S) {
   const Pointer &Ptr = S.Stk.peek<Pointer>();
   if (Ptr.canBeInitialized())
     Ptr.activate();
   return true;
 }
 
-static inline bool ActivateThisField(InterpState &S, CodePtr OpPC, uint32_t I) 
{
+static inline bool ActivateThisField(InterpState &S, uint32_t I) {
   if (S.checkingPotentialConstantExpression())
     return false;
   if (!S.Current->hasThisPointer())
@@ -3139,12 +3138,12 @@ static inline bool PtrPtrCast(InterpState &S, CodePtr 
OpPC, bool SrcIsVoidPtr) {
 
//===----------------------------------------------------------------------===//
 
 template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Zero(InterpState &S, CodePtr OpPC) {
+bool Zero(InterpState &S) {
   S.Stk.push<T>(T::zero());
   return true;
 }
 
-static inline bool ZeroIntAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
+static inline bool ZeroIntAP(InterpState &S, uint32_t BitWidth) {
   auto Result = S.allocAP<IntegralAP<false>>(BitWidth);
   if (!Result.singleWord())
     std::memset(Result.Memory, 0, Result.numWords() * sizeof(uint64_t));
@@ -3152,7 +3151,7 @@ static inline bool ZeroIntAP(InterpState &S, CodePtr 
OpPC, uint32_t BitWidth) {
   return true;
 }
 
-static inline bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) 
{
+static inline bool ZeroIntAPS(InterpState &S, uint32_t BitWidth) {
   auto Result = S.allocAP<IntegralAP<true>>(BitWidth);
   if (!Result.singleWord())
     std::memset(Result.Memory, 0, Result.numWords() * sizeof(uint64_t));
@@ -3161,7 +3160,7 @@ static inline bool ZeroIntAPS(InterpState &S, CodePtr 
OpPC, uint32_t BitWidth) {
 }
 
 template <PrimType Name, class T = typename PrimConv<Name>::T>
-inline bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, const Type *Ty) 
{
+inline bool Null(InterpState &S, uint64_t Value, const Type *Ty) {
   // FIXME(perf): This is a somewhat often-used function and the value of a
   // null pointer is almost always 0.
   S.Stk.push<T>(Value, Ty);
@@ -3433,13 +3432,13 @@ PRESERVE_NONE inline bool NoRet(InterpState &S, CodePtr 
OpPC) {
 // NarrowPtr, ExpandPtr
 
//===----------------------------------------------------------------------===//
 
-inline bool NarrowPtr(InterpState &S, CodePtr OpPC) {
+inline bool NarrowPtr(InterpState &S) {
   const Pointer &Ptr = S.Stk.pop<Pointer>();
   S.Stk.push<Pointer>(Ptr.narrow());
   return true;
 }
 
-inline bool ExpandPtr(InterpState &S, CodePtr OpPC) {
+inline bool ExpandPtr(InterpState &S) {
   const Pointer &Ptr = S.Stk.pop<Pointer>();
   if (Ptr.isBlockPointer())
     S.Stk.push<Pointer>(Ptr.expand());
@@ -3654,7 +3653,7 @@ inline bool Unsupported(InterpState &S, CodePtr OpPC) {
   return false;
 }
 
-inline bool PushIgnoreDiags(InterpState &S, CodePtr OpPC) {
+inline bool PushIgnoreDiags(InterpState &S) {
   ++S.DiagIgnoreDepth;
   if (S.DiagIgnoreDepth != 1)
     return true;
@@ -3666,7 +3665,7 @@ inline bool PushIgnoreDiags(InterpState &S, CodePtr OpPC) 
{
   return true;
 }
 
-inline bool PopIgnoreDiags(InterpState &S, CodePtr OpPC) {
+inline bool PopIgnoreDiags(InterpState &S) {
   assert(S.DiagIgnoreDepth != 0);
   --S.DiagIgnoreDepth;
   if (S.DiagIgnoreDepth == 0) {
@@ -3677,20 +3676,20 @@ inline bool PopIgnoreDiags(InterpState &S, CodePtr 
OpPC) {
   return true;
 }
 
-inline bool StartSpeculation(InterpState &S, CodePtr OpPC) {
+inline bool StartSpeculation(InterpState &S) {
 #ifndef NDEBUG
   ++S.SpeculationDepth;
 #endif
   return true;
 }
 
-inline bool StartInit(InterpState &S, CodePtr OpPC) {
+inline bool StartInit(InterpState &S) {
   const Pointer &Ptr = S.Stk.peek<Pointer>();
   S.InitializingPtrs.push_back(Ptr.view());
   return true;
 }
 
-inline bool EndInit(InterpState &S, CodePtr OpPC) {
+inline bool EndInit(InterpState &S) {
   S.InitializingPtrs.pop_back();
   return true;
 }
@@ -3706,22 +3705,22 @@ PRESERVE_NONE inline bool EndSpeculation(InterpState 
&S) {
   return true;
 }
 
-inline bool PushCC(InterpState &S, CodePtr OpPC, bool Value) {
+inline bool PushCC(InterpState &S, bool Value) {
   S.ConstantContextOverride = Value;
   return true;
 }
-inline bool PopCC(InterpState &S, CodePtr OpPC) {
+inline bool PopCC(InterpState &S) {
   S.ConstantContextOverride = std::nullopt;
   return true;
 }
 
-inline bool PushMSVCCE(InterpState &S, CodePtr OpPC) {
+inline bool PushMSVCCE(InterpState &S) {
   // This is a per-frame property.
   ++S.Current->MSVCConstexprAllowed;
   return true;
 }
 
-inline bool PopMSVCCE(InterpState &S, CodePtr OpPC) {
+inline bool PopMSVCCE(InterpState &S) {
   assert(S.Current->MSVCConstexprAllowed >= 1);
   // This is a per-frame property.
   --S.Current->MSVCConstexprAllowed;
diff --git a/clang/lib/AST/ByteCode/Opcodes.td 
b/clang/lib/AST/ByteCode/Opcodes.td
index 8123ca7497335..cf99c1f056527 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -145,10 +145,12 @@ class Opcode {
   bit HasCustomEval = 0;
   bit HasGroup = 0;
   bit CanFail = 1;
+  bit NeedsOpPC = 1;
 }
 
 class SuccessOpcode : Opcode {
   let CanFail = 0;
+  let NeedsOpPC = 0;
 }
 
 class AluOpcode : Opcode {
@@ -272,11 +274,10 @@ def EnableLocal : Opcode {
 // Constants
 
//===----------------------------------------------------------------------===//
 
-class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
+class ConstOpcode<Type Ty, ArgType ArgTy> : SuccessOpcode {
   let Types = [SingletonTypeClass<Ty>];
   let Args = [ArgTy];
   let Name = "Const";
-  let CanFail = 0;
 }
 
 // [] -> [Integer]
@@ -293,35 +294,29 @@ def ConstIntAPS : ConstOpcode<IntAPS, ArgIntAPS>;
 def ConstBool : ConstOpcode<Bool, ArgBool>;
 def ConstFixedPoint : ConstOpcode<FixedPoint, ArgFixedPoint>;
 
-def ConstFloat : Opcode {
+def ConstFloat : SuccessOpcode {
   let Args = [ArgFloat];
-  let CanFail = 0;
 }
 
 // [] -> [Integer]
-def Zero : Opcode {
+def Zero : SuccessOpcode {
   let Types = [FixedSizeIntegralTypeClass];
   let HasGroup = 1;
-  let CanFail = 0;
-
 }
 
-def ZeroIntAP : Opcode {
+def ZeroIntAP : SuccessOpcode {
   let Args = [ArgUint32];
-  let CanFail = 0;
 }
 
-def ZeroIntAPS : Opcode {
+def ZeroIntAPS : SuccessOpcode {
   let Args = [ArgUint32];
-  let CanFail = 0;
 }
 
 // [] -> [Pointer]
-def Null : Opcode {
+def Null : SuccessOpcode {
   let Types = [PtrTypeClass];
   let Args = [ArgUint64, ArgTypePtr];
   let HasGroup = 1;
-  let CanFail = 0;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -551,8 +546,13 @@ def StoreBitFieldPop : StoreBitFieldOpcode {}
 def StoreBitFieldActivate : StoreBitFieldOpcode {}
 def StoreBitFieldActivatePop : StoreBitFieldOpcode {}
 
-def Activate : SuccessOpcode;
-def ActivateThisField : Opcode { let Args = [ArgUint32]; }
+def Activate : SuccessOpcode {
+  let NeedsOpPC = 0;
+}
+def ActivateThisField : Opcode {
+  let Args = [ArgUint32];
+  let NeedsOpPC = 0;
+}
 
 // [Pointer, Value] -> []
 def Init : StoreOpcode {}
@@ -846,23 +846,20 @@ def GE : ComparisonOpcode;
 
//===----------------------------------------------------------------------===//
 
 // [Value] -> []
-def Pop : Opcode {
+def Pop : SuccessOpcode {
   let Types = [AllTypeClass];
   let HasGroup = 1;
-  let CanFail = 0;
 }
 
 // [Value] -> [Value, Value]
-def Dup : Opcode {
+def Dup : SuccessOpcode {
   let Types = [AllTypeClass];
   let HasGroup = 1;
-  let CanFail = 0;
 }
 
-def Flip : Opcode {
+def Flip : SuccessOpcode {
   let Types = [AllTypeClass, AllTypeClass];
   let HasGroup = 1;
-  let CanFail = 0;
 }
 
 // [] -> []
@@ -878,7 +875,9 @@ def DynamicCast : Opcode {
 }
 
 def InvalidStore : Opcode { let Args = [ArgTypePtr]; }
-def CheckPseudoDtor : SuccessOpcode;
+def CheckPseudoDtor : SuccessOpcode {
+  let NeedsOpPC = 1;
+}
 
 def InvalidDeclRef : Opcode {
   let Args = [ArgDeclRef, ArgBool];
@@ -970,9 +969,8 @@ def CheckDestruction : Opcode;
 
 def CtorCheck : Opcode;
 
-def PushCC : Opcode {
+def PushCC : SuccessOpcode {
   let Args = [ArgBool];
-  let CanFail = 0;
 }
 def PopCC : SuccessOpcode;
 def PushMSVCCE : SuccessOpcode;
diff --git a/clang/utils/TableGen/ClangOpcodesEmitter.cpp 
b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
index 13a99900bc9ec..4a3c901d2de7f 100644
--- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
@@ -126,6 +126,7 @@ void 
ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
     bool CanReturn = R->getValueAsBit("CanReturn");
     const auto &Args = R->getValueAsListOfDefs("Args");
     bool CanFail = R->getValueAsBit("CanFail");
+    bool PassOpPC = R->getValueAsBit("NeedsOpPC");
 
     if (Args.empty()) {
       if (CanReturn) {
@@ -142,7 +143,11 @@ void 
ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
 
       OS << N;
       PrintTypes(OS, TS);
-      OS << "(S, S.PC)";
+      OS << "(S";
+      if (PassOpPC)
+        OS << ", S.PC)";
+      else
+        OS << ")";
 
       if (CanFail)
         OS << ") return false";
@@ -160,7 +165,8 @@ void 
ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
 
     OS << "  {\n";
 
-    OS << "    CodePtr OpPC = S.PC;\n";
+    if (PassOpPC)
+      OS << "    CodePtr OpPC = S.PC;\n";
 
     // Emit calls to read arguments.
     for (size_t I = 0, N = Args.size(); I < N; ++I) {
@@ -182,7 +188,8 @@ void 
ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
     OS << N;
     PrintTypes(OS, TS);
     OS << "(S";
-    OS << ", OpPC";
+    if (PassOpPC)
+      OS << ", OpPC";
     for (size_t I = 0, N = Args.size(); I < N; ++I)
       OS << ", V" << I;
 
@@ -431,10 +438,13 @@ void ClangOpcodesEmitter::EmitEval(raw_ostream &OS, 
StringRef N,
               if (N == "EndSpeculation") {
                 OS << "return EndSpeculation(S);\n";
               } else {
+                bool PassOpPC = R->getValueAsBit("NeedsOpPC");
 
                 OS << "  return " << N;
                 PrintTypes(OS, TS);
-                OS << "(S, OpPC";
+                OS << "(S";
+                if (PassOpPC)
+                  OS << ", OpPC";
                 for (size_t I = 0, N = Args.size(); I < N; ++I)
                   OS << ", A" << I;
                 OS << ");\n";

``````````

</details>


https://github.com/llvm/llvm-project/pull/207479
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to