LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/IR - OperandTraits.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 4 4
Test Date: 2026-02-27 04:14:43 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : //===-- llvm/OperandTraits.h - OperandTraits class definition ---*- C++ -*-===//
       2              : //
       3              : // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
       4              : // See https://llvm.org/LICENSE.txt for license information.
       5              : // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
       6              : //
       7              : //===----------------------------------------------------------------------===//
       8              : //
       9              : // This file defines the traits classes that are handy for enforcing the correct
      10              : // layout of various User subclasses. It also provides the means for accessing
      11              : // the operands in the most efficient manner.
      12              : //
      13              : 
      14              : #ifndef LLVM_IR_OPERANDTRAITS_H
      15              : #define LLVM_IR_OPERANDTRAITS_H
      16              : 
      17              : #include "llvm/IR/User.h"
      18              : 
      19              : namespace llvm {
      20              : 
      21              : //===----------------------------------------------------------------------===//
      22              : //                          FixedNumOperand Trait Class
      23              : //===----------------------------------------------------------------------===//
      24              : 
      25              : /// FixedNumOperandTraits - determine the allocation regime of the Use array
      26              : /// when it is a prefix to the User object, and the number of Use objects is
      27              : /// known at compile time.
      28              : 
      29              : template <typename SubClass, unsigned ARITY>
      30              : struct FixedNumOperandTraits {
      31        20498 :   static Use *op_begin(SubClass* U) {
      32              :     static_assert(
      33              :         !std::is_polymorphic<SubClass>::value,
      34              :         "adding virtual methods to subclasses of User breaks use lists");
      35        20498 :     return reinterpret_cast<Use*>(U) - ARITY;
      36              :   }
      37              :   static Use *op_end(SubClass* U) {
      38              :     return reinterpret_cast<Use*>(U);
      39              :   }
      40              :   static unsigned operands(const User*) {
      41              :     return ARITY;
      42              :   }
      43              : };
      44              : 
      45              : //===----------------------------------------------------------------------===//
      46              : //                          OptionalOperand Trait Class
      47              : //===----------------------------------------------------------------------===//
      48              : 
      49              : /// OptionalOperandTraits - when the number of operands may change at runtime.
      50              : /// Naturally it may only decrease, because the allocations may not change.
      51              : 
      52              : template <typename SubClass, unsigned ARITY = 1>
      53              : struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
      54              :   static unsigned operands(const User *U) {
      55              :     return U->getNumOperands();
      56              :   }
      57              : };
      58              : 
      59              : //===----------------------------------------------------------------------===//
      60              : //                          VariadicOperand Trait Class
      61              : //===----------------------------------------------------------------------===//
      62              : 
      63              : /// VariadicOperandTraits - determine the allocation regime of the Use array
      64              : /// when it is a prefix to the User object, and the number of Use objects is
      65              : /// only known at allocation time.
      66              : 
      67              : template <typename SubClass, unsigned MINARITY = 0>
      68              : struct VariadicOperandTraits {
      69              :   static Use *op_begin(SubClass* U) {
      70              :     static_assert(
      71              :         !std::is_polymorphic<SubClass>::value,
      72              :         "adding virtual methods to subclasses of User breaks use lists");
      73              :     return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
      74              :   }
      75        60997 :   static Use *op_end(SubClass* U) {
      76        60997 :     return reinterpret_cast<Use*>(U);
      77              :   }
      78              :   static unsigned operands(const User *U) {
      79              :     return U->getNumOperands();
      80              :   }
      81              : };
      82              : 
      83              : //===----------------------------------------------------------------------===//
      84              : //                          HungoffOperand Trait Class
      85              : //===----------------------------------------------------------------------===//
      86              : 
      87              : /// HungoffOperandTraits - determine the allocation regime of the Use array
      88              : /// when it is not a prefix to the User object, but allocated at an unrelated
      89              : /// heap address.
      90              : ///
      91              : /// This is the traits class that is needed when the Use array must be
      92              : /// resizable.
      93              : 
      94              : template <unsigned MINARITY = 1>
      95              : struct HungoffOperandTraits {
      96              :   static Use *op_begin(User* U) {
      97              :     return U->getHungOffOperands();
      98              :   }
      99              :   static Use *op_end(User* U) {
     100              :     return U->getHungOffOperands() + U->getNumOperands();
     101              :   }
     102              :   static unsigned operands(const User *U) {
     103              :     return U->getNumOperands();
     104              :   }
     105              : };
     106              : 
     107              : /// Macro for generating in-class operand accessor declarations.
     108              : /// It should only be called in the public section of the interface.
     109              : ///
     110              : #define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \
     111              :   public: \
     112              :   inline VALUECLASS *getOperand(unsigned) const; \
     113              :   inline void setOperand(unsigned, VALUECLASS*); \
     114              :   inline op_iterator op_begin(); \
     115              :   inline const_op_iterator op_begin() const; \
     116              :   inline op_iterator op_end(); \
     117              :   inline const_op_iterator op_end() const; \
     118              :   protected: \
     119              :   template <int> inline Use &Op(); \
     120              :   template <int> inline const Use &Op() const; \
     121              :   public: \
     122              :   inline unsigned getNumOperands() const
     123              : 
     124              : /// Macro for generating out-of-class operand accessor definitions
     125              : #define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
     126              : CLASS::op_iterator CLASS::op_begin() { \
     127              :   return OperandTraits<CLASS>::op_begin(this); \
     128              : } \
     129              : CLASS::const_op_iterator CLASS::op_begin() const { \
     130              :   return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \
     131              : } \
     132              : CLASS::op_iterator CLASS::op_end() { \
     133              :   return OperandTraits<CLASS>::op_end(this); \
     134              : } \
     135              : CLASS::const_op_iterator CLASS::op_end() const { \
     136              :   return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \
     137              : } \
     138              : VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
     139              :   assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
     140              :          && "getOperand() out of range!"); \
     141              :   return cast_or_null<VALUECLASS>( \
     142              :     OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \
     143              : } \
     144              : void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
     145              :   assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
     146              :          && "setOperand() out of range!"); \
     147              :   OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
     148              : } \
     149              : unsigned CLASS::getNumOperands() const { \
     150              :   return OperandTraits<CLASS>::operands(this); \
     151              : } \
     152              : template <int Idx_nocapture> Use &CLASS::Op() { \
     153              :   return this->OpFrom<Idx_nocapture>(this); \
     154              : } \
     155              : template <int Idx_nocapture> const Use &CLASS::Op() const { \
     156              :   return this->OpFrom<Idx_nocapture>(this); \
     157              : }
     158              : 
     159              : 
     160              : } // End llvm namespace
     161              : 
     162              : #endif
        

Generated by: LCOV version 2.0-1