tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, tahonermann, shafik, erichkeane.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This adds a `InterpStack::discard()` version that takes a `PrimType` argument.

I'm not sure what to do if we actually want to //use// a value from the stack...


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D139700

Files:
  clang/lib/AST/Interp/Interp.h
  clang/lib/AST/Interp/InterpBuiltin.cpp
  clang/lib/AST/Interp/InterpStack.h
  clang/lib/AST/Interp/InterpState.h
  clang/test/AST/Interp/builtins.cpp

Index: clang/test/AST/Interp/builtins.cpp
===================================================================
--- clang/test/AST/Interp/builtins.cpp
+++ clang/test/AST/Interp/builtins.cpp
@@ -22,3 +22,11 @@
 bool is_this_constant() {
   return __builtin_is_constant_evaluated(); // CHECK: ret i1 false
 }
+
+long my_expected() {
+  return __builtin_expect(17, 12); // CHECK: ret {{.*}} 17
+}
+
+long my_expected(long foo) {
+  return __builtin_expect(foo, 100);
+}
Index: clang/lib/AST/Interp/InterpState.h
===================================================================
--- clang/lib/AST/Interp/InterpState.h
+++ clang/lib/AST/Interp/InterpState.h
@@ -86,6 +86,8 @@
     return M ? M->getSource(F, PC) : F->getSource(PC);
   }
 
+  std::optional<PrimType> classify(QualType T) const { return Ctx.classify(T); }
+
 private:
   /// AST Walker state.
   State &Parent;
Index: clang/lib/AST/Interp/InterpStack.h
===================================================================
--- clang/lib/AST/Interp/InterpStack.h
+++ clang/lib/AST/Interp/InterpStack.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_AST_INTERP_INTERPSTACK_H
 #define LLVM_CLANG_AST_INTERP_INTERPSTACK_H
 
+#include "Pointer.h"
 #include "PrimType.h"
 #include <memory>
 #include <vector>
@@ -61,6 +62,17 @@
     shrink(aligned_size<T>());
   }
 
+  /// Discards the top value of the given PrimType.
+  void discard(PrimType Type) {
+#ifndef NDEBUG
+    assert(ItemTypes.back() == Type);
+    ItemTypes.pop_back();
+#endif
+
+    TYPE_SWITCH(Type, auto *Ptr = &peek<T>(); Ptr->~T();
+                shrink(aligned_size<T>()););
+  }
+
   /// Returns a reference to the value on the top of the stack.
   template <typename T> T &peek() const {
     return *reinterpret_cast<T *>(peek(aligned_size<T>()));
Index: clang/lib/AST/Interp/InterpBuiltin.cpp
===================================================================
--- clang/lib/AST/Interp/InterpBuiltin.cpp
+++ clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -36,12 +36,25 @@
   return true;
 }
 
-bool InterpretBuiltin(InterpState &S, CodePtr PC, unsigned BuiltinID) {
+bool InterpretBuiltin(InterpState &S, CodePtr PC,
+                      const FunctionDecl *FuncDecl) {
+  unsigned BuiltinID = FuncDecl->getBuiltinID();
+  assert(BuiltinID != 0);
+
   switch (BuiltinID) {
   case Builtin::BI__builtin_is_constant_evaluated:
     S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
     Ret<PT_Bool>(S, PC);
     return true;
+
+  case Builtin::BI__builtin_expect: {
+    // __builtin_expect(long, long).
+    //   Pop the last argument from the stack,
+    //   leave the first one and just ignore the function.
+    PrimType LongT = *S.classify(FuncDecl->getParamDecl(1)->getType());
+    S.Stk.discard(LongT);
+    return true;
+  }
   }
 
   return false;
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -109,7 +109,7 @@
 /// Interpreter entry point.
 bool Interpret(InterpState &S, APValue &Result);
 
-bool InterpretBuiltin(InterpState &S, CodePtr PC, unsigned BuiltinID);
+bool InterpretBuiltin(InterpState &S, CodePtr PC, const FunctionDecl *FuncDecl);
 
 enum class ArithOp { Add, Sub };
 
@@ -1407,7 +1407,7 @@
   InterpFrame *FrameBefore = S.Current;
   S.Current = NewFrame.get();
 
-  if (InterpretBuiltin(S, PC, Func->getBuiltinID())) {
+  if (InterpretBuiltin(S, PC, Func->getDecl())) {
     NewFrame.release();
     return true;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to