llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

Instead of doing a GetPtrLocal + Load or GetPtrGlobal + Load pair, try to load 
the value directly.

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


5 Files Affected:

- (modified) clang/lib/AST/ByteCode/ByteCodeEmitter.cpp (+2-1) 
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+19) 
- (modified) clang/lib/AST/ByteCode/EvalEmitter.cpp (+2-1) 
- (modified) clang/lib/AST/ByteCode/Function.h (+1) 
- (modified) clang/lib/AST/ByteCode/Interp.h (+1-7) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp 
b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
index d4746052c5cfe..3300733335747 100644
--- a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
@@ -93,10 +93,11 @@ void ByteCodeEmitter::compileFunc(const FunctionDecl 
*FuncDecl,
 }
 
 Scope::Local ByteCodeEmitter::createLocal(Descriptor *D) {
+  OptPrimType PrimT = D->isPrimitive() ? D->getPrimType() : OptPrimType();
   NextLocalOffset += sizeof(Block);
   unsigned Location = NextLocalOffset;
   NextLocalOffset += align(D->getAllocSize());
-  return {Location, D};
+  return {PrimT, Location, D};
 }
 
 void ByteCodeEmitter::emitLabel(LabelTy Label) {
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 6e451acd4b6b4..ae21d45fa8fa0 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -200,6 +200,25 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
     if (SubExpr->getType().isVolatileQualified())
       return this->emitInvalidCast(CastKind::Volatile, /*Fatal=*/true, CE);
 
+    // Try to load the value directly. This is purely a performance
+    // optimization.
+    if (const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
+      const ValueDecl *D = DRE->getDecl();
+      bool IsReference = D->getType()->isReferenceType();
+
+      if (!IsReference) {
+        if (auto It = Locals.find(D); It != Locals.end()) {
+          OptPrimType PrimT = It->second.PrimT;
+          unsigned Offset = It->second.Offset;
+          if (PrimT)
+            return this->emitGetLocal(*PrimT, Offset, CE);
+        } else if (auto GlobalIndex = P.getGlobal(D)) {
+          if (OptPrimType T = classify(CE))
+            return this->emitGetGlobal(*T, *GlobalIndex, CE);
+        }
+      }
+    }
+
     OptPrimType SubExprT = classify(SubExpr->getType());
     // Prepare storage for the result.
     if (!Initializing && !SubExprT) {
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp 
b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index 81ebc5694d6f0..271ffd67ff5fe 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -124,9 +124,10 @@ Scope::Local EvalEmitter::createLocal(Descriptor *D) {
   Desc.IsInitialized = false;
 
   // Register the local.
+  OptPrimType PrimT = D->isPrimitive() ? D->getPrimType() : OptPrimType();
   unsigned Off = Locals.size();
   Locals.push_back(std::move(Memory));
-  return {Off, D};
+  return {PrimT, Off, D};
 }
 
 bool EvalEmitter::jumpTrue(const LabelTy &Label) {
diff --git a/clang/lib/AST/ByteCode/Function.h 
b/clang/lib/AST/ByteCode/Function.h
index de88f3ded34dc..d42438ffde6a1 100644
--- a/clang/lib/AST/ByteCode/Function.h
+++ b/clang/lib/AST/ByteCode/Function.h
@@ -37,6 +37,7 @@ class Scope final {
 public:
   /// Information about a local's storage.
   struct Local {
+    OptPrimType PrimT;
     /// Offset of the local in frame.
     unsigned Offset;
     /// Descriptor of the local.
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 9a325ab55ca6a..8c77dbd85c950 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1465,14 +1465,8 @@ bool SetThisField(InterpState &S, CodePtr OpPC, uint32_t 
I) {
 template <PrimType Name, class T = typename PrimConv<Name>::T>
 bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
   const Pointer &Ptr = S.P.getPtrGlobal(I);
-  if (!CheckConstant(S, OpPC, Ptr.getFieldDesc()))
-    return false;
-  if (Ptr.isExtern())
-    return false;
 
-  // If a global variable is uninitialized, that means the initializer we've
-  // compiled for it wasn't a constant expression. Diagnose that.
-  if (!CheckGlobalInitialized(S, OpPC, Ptr))
+  if (!CheckLoad(S, OpPC, Ptr))
     return false;
 
   S.Stk.push<T>(Ptr.deref<T>());

``````````

</details>


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

Reply via email to