LCOV - code coverage report
Current view: top level - lib/IR - ConstantsContext.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 188 215 87.4 %
Date: 2017-09-14 15:23:50 Functions: 49 52 94.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ConstantsContext.h - Constants-related Context Interals -*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : //  This file defines various helper methods and classes used by
      11             : // LLVMContextImpl for creating and managing constants.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_LIB_IR_CONSTANTSCONTEXT_H
      16             : #define LLVM_LIB_IR_CONSTANTSCONTEXT_H
      17             : 
      18             : #include "llvm/ADT/ArrayRef.h"
      19             : #include "llvm/ADT/DenseMapInfo.h"
      20             : #include "llvm/ADT/DenseSet.h"
      21             : #include "llvm/ADT/Hashing.h"
      22             : #include "llvm/ADT/None.h"
      23             : #include "llvm/ADT/SmallVector.h"
      24             : #include "llvm/ADT/StringRef.h"
      25             : #include "llvm/IR/Constant.h"
      26             : #include "llvm/IR/Constants.h"
      27             : #include "llvm/IR/DerivedTypes.h"
      28             : #include "llvm/IR/InlineAsm.h"
      29             : #include "llvm/IR/Instruction.h"
      30             : #include "llvm/IR/OperandTraits.h"
      31             : #include "llvm/Support/Casting.h"
      32             : #include "llvm/Support/Debug.h"
      33             : #include "llvm/Support/ErrorHandling.h"
      34             : #include "llvm/Support/raw_ostream.h"
      35             : #include <cassert>
      36             : #include <cstddef>
      37             : #include <cstdint>
      38             : #include <utility>
      39             : 
      40             : #define DEBUG_TYPE "ir"
      41             : 
      42             : namespace llvm {
      43             : 
      44             : /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
      45             : /// behind the scenes to implement unary constant exprs.
      46             : class UnaryConstantExpr : public ConstantExpr {
      47             : public:
      48             :   UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
      49      322077 :     : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
      50      214718 :     Op<0>() = C;
      51             :   }
      52             : 
      53             :   // allocate space for exactly one operand
      54             :   void *operator new(size_t s) {
      55      107359 :     return User::operator new(s, 1);
      56             :   }
      57             : 
      58             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
      59             : };
      60             : 
      61             : /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
      62             : /// behind the scenes to implement binary constant exprs.
      63             : class BinaryConstantExpr : public ConstantExpr {
      64             : public:
      65        1854 :   BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
      66             :                      unsigned Flags)
      67        5562 :     : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
      68        3708 :     Op<0>() = C1;
      69        3708 :     Op<1>() = C2;
      70        1854 :     SubclassOptionalData = Flags;
      71        1854 :   }
      72             : 
      73             :   // allocate space for exactly two operands
      74             :   void *operator new(size_t s) {
      75        1854 :     return User::operator new(s, 2);
      76             :   }
      77             : 
      78             :   /// Transparently provide more efficient getOperand methods.
      79             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
      80             : };
      81             : 
      82             : /// SelectConstantExpr - This class is private to Constants.cpp, and is used
      83             : /// behind the scenes to implement select constant exprs.
      84             : class SelectConstantExpr : public ConstantExpr {
      85             : public:
      86          85 :   SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
      87         255 :     : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
      88         170 :     Op<0>() = C1;
      89         170 :     Op<1>() = C2;
      90         170 :     Op<2>() = C3;
      91          85 :   }
      92             : 
      93             :   // allocate space for exactly three operands
      94             :   void *operator new(size_t s) {
      95          85 :     return User::operator new(s, 3);
      96             :   }
      97             : 
      98             :   /// Transparently provide more efficient getOperand methods.
      99             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     100             : };
     101             : 
     102             : /// ExtractElementConstantExpr - This class is private to
     103             : /// Constants.cpp, and is used behind the scenes to implement
     104             : /// extractelement constant exprs.
     105             : class ExtractElementConstantExpr : public ConstantExpr {
     106             : public:
     107          54 :   ExtractElementConstantExpr(Constant *C1, Constant *C2)
     108         162 :     : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
     109         216 :                    Instruction::ExtractElement, &Op<0>(), 2) {
     110         108 :     Op<0>() = C1;
     111         108 :     Op<1>() = C2;
     112          54 :   }
     113             : 
     114             :   // allocate space for exactly two operands
     115             :   void *operator new(size_t s) {
     116          54 :     return User::operator new(s, 2);
     117             :   }
     118             : 
     119             :   /// Transparently provide more efficient getOperand methods.
     120             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     121             : };
     122             : 
     123             : /// InsertElementConstantExpr - This class is private to
     124             : /// Constants.cpp, and is used behind the scenes to implement
     125             : /// insertelement constant exprs.
     126             : class InsertElementConstantExpr : public ConstantExpr {
     127             : public:
     128           0 :   InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     129           0 :     : ConstantExpr(C1->getType(), Instruction::InsertElement,
     130           0 :                    &Op<0>(), 3) {
     131           0 :     Op<0>() = C1;
     132           0 :     Op<1>() = C2;
     133           0 :     Op<2>() = C3;
     134           0 :   }
     135             : 
     136             :   // allocate space for exactly three operands
     137             :   void *operator new(size_t s) {
     138           0 :     return User::operator new(s, 3);
     139             :   }
     140             : 
     141             :   /// Transparently provide more efficient getOperand methods.
     142             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     143             : };
     144             : 
     145             : /// ShuffleVectorConstantExpr - This class is private to
     146             : /// Constants.cpp, and is used behind the scenes to implement
     147             : /// shufflevector constant exprs.
     148             : class ShuffleVectorConstantExpr : public ConstantExpr {
     149             : public:
     150           0 :   ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     151           0 :   : ConstantExpr(VectorType::get(
     152           0 :                    cast<VectorType>(C1->getType())->getElementType(),
     153           0 :                    cast<VectorType>(C3->getType())->getNumElements()),
     154             :                  Instruction::ShuffleVector,
     155           0 :                  &Op<0>(), 3) {
     156           0 :     Op<0>() = C1;
     157           0 :     Op<1>() = C2;
     158           0 :     Op<2>() = C3;
     159           0 :   }
     160             : 
     161             :   // allocate space for exactly three operands
     162             :   void *operator new(size_t s) {
     163           0 :     return User::operator new(s, 3);
     164             :   }
     165             : 
     166             :   /// Transparently provide more efficient getOperand methods.
     167             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     168             : };
     169             : 
     170             : /// ExtractValueConstantExpr - This class is private to
     171             : /// Constants.cpp, and is used behind the scenes to implement
     172             : /// extractvalue constant exprs.
     173             : class ExtractValueConstantExpr : public ConstantExpr {
     174             : public:
     175           4 :   ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList,
     176             :                            Type *DestTy)
     177           8 :       : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
     178          16 :         Indices(IdxList.begin(), IdxList.end()) {
     179           8 :     Op<0>() = Agg;
     180           4 :   }
     181             : 
     182             :   // allocate space for exactly one operand
     183             :   void *operator new(size_t s) {
     184           4 :     return User::operator new(s, 1);
     185             :   }
     186             : 
     187             :   /// Indices - These identify which value to extract.
     188             :   const SmallVector<unsigned, 4> Indices;
     189             : 
     190             :   /// Transparently provide more efficient getOperand methods.
     191             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     192             : 
     193             :   static bool classof(const ConstantExpr *CE) {
     194           6 :     return CE->getOpcode() == Instruction::ExtractValue;
     195             :   }
     196             :   static bool classof(const Value *V) {
     197             :     return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
     198             :   }
     199             : };
     200             : 
     201             : /// InsertValueConstantExpr - This class is private to
     202             : /// Constants.cpp, and is used behind the scenes to implement
     203             : /// insertvalue constant exprs.
     204             : class InsertValueConstantExpr : public ConstantExpr {
     205             : public:
     206           1 :   InsertValueConstantExpr(Constant *Agg, Constant *Val,
     207             :                           ArrayRef<unsigned> IdxList, Type *DestTy)
     208           2 :       : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
     209           4 :         Indices(IdxList.begin(), IdxList.end()) {
     210           2 :     Op<0>() = Agg;
     211           2 :     Op<1>() = Val;
     212           1 :   }
     213             : 
     214             :   // allocate space for exactly one operand
     215             :   void *operator new(size_t s) {
     216           1 :     return User::operator new(s, 2);
     217             :   }
     218             : 
     219             :   /// Indices - These identify the position for the insertion.
     220             :   const SmallVector<unsigned, 4> Indices;
     221             : 
     222             :   /// Transparently provide more efficient getOperand methods.
     223             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     224             : 
     225             :   static bool classof(const ConstantExpr *CE) {
     226             :     return CE->getOpcode() == Instruction::InsertValue;
     227             :   }
     228             :   static bool classof(const Value *V) {
     229             :     return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
     230             :   }
     231             : };
     232             : 
     233             : /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
     234             : /// used behind the scenes to implement getelementpr constant exprs.
     235             : class GetElementPtrConstantExpr : public ConstantExpr {
     236             :   Type *SrcElementTy;
     237             :   Type *ResElementTy;
     238             : 
     239             :   GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
     240             :                             ArrayRef<Constant *> IdxList, Type *DestTy);
     241             : 
     242             : public:
     243      378550 :   static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C,
     244             :                                            ArrayRef<Constant *> IdxList,
     245             :                                            Type *DestTy, unsigned Flags) {
     246      378550 :     GetElementPtrConstantExpr *Result = new (IdxList.size() + 1)
     247      757100 :         GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy);
     248      378550 :     Result->SubclassOptionalData = Flags;
     249      378550 :     return Result;
     250             :   }
     251             : 
     252             :   Type *getSourceElementType() const;
     253             :   Type *getResultElementType() const;
     254             : 
     255             :   /// Transparently provide more efficient getOperand methods.
     256             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     257             : 
     258             :   static bool classof(const ConstantExpr *CE) {
     259             :     return CE->getOpcode() == Instruction::GetElementPtr;
     260             :   }
     261             :   static bool classof(const Value *V) {
     262             :     return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
     263             :   }
     264             : };
     265             : 
     266             : // CompareConstantExpr - This class is private to Constants.cpp, and is used
     267             : // behind the scenes to implement ICmp and FCmp constant expressions. This is
     268             : // needed in order to store the predicate value for these instructions.
     269             : class CompareConstantExpr : public ConstantExpr {
     270             : public:
     271             :   unsigned short predicate;
     272         387 :   CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
     273             :                       unsigned short pred,  Constant* LHS, Constant* RHS)
     274        1161 :     : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
     275         774 :     Op<0>() = LHS;
     276         774 :     Op<1>() = RHS;
     277         387 :   }
     278             : 
     279             :   // allocate space for exactly two operands
     280             :   void *operator new(size_t s) {
     281         387 :     return User::operator new(s, 2);
     282             :   }
     283             : 
     284             :   /// Transparently provide more efficient getOperand methods.
     285             :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     286             : 
     287             :   static bool classof(const ConstantExpr *CE) {
     288             :     return CE->getOpcode() == Instruction::ICmp ||
     289             :            CE->getOpcode() == Instruction::FCmp;
     290             :   }
     291             :   static bool classof(const Value *V) {
     292             :     return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
     293             :   }
     294             : };
     295             : 
     296             : template <>
     297             : struct OperandTraits<UnaryConstantExpr>
     298             :     : public FixedNumOperandTraits<UnaryConstantExpr, 1> {};
     299      214718 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
     300             : 
     301             : template <>
     302             : struct OperandTraits<BinaryConstantExpr>
     303             :     : public FixedNumOperandTraits<BinaryConstantExpr, 2> {};
     304        5562 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
     305             : 
     306             : template <>
     307             : struct OperandTraits<SelectConstantExpr>
     308             :     : public FixedNumOperandTraits<SelectConstantExpr, 3> {};
     309         340 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
     310             : 
     311             : template <>
     312             : struct OperandTraits<ExtractElementConstantExpr>
     313             :     : public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {};
     314         162 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
     315             : 
     316             : template <>
     317             : struct OperandTraits<InsertElementConstantExpr>
     318             :     : public FixedNumOperandTraits<InsertElementConstantExpr, 3> {};
     319           0 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
     320             : 
     321             : template <>
     322             : struct OperandTraits<ShuffleVectorConstantExpr>
     323             :     : public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {};
     324           0 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
     325             : 
     326             : template <>
     327             : struct OperandTraits<ExtractValueConstantExpr>
     328             :     : public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {};
     329           8 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
     330             : 
     331             : template <>
     332             : struct OperandTraits<InsertValueConstantExpr>
     333             :     : public FixedNumOperandTraits<InsertValueConstantExpr, 2> {};
     334           3 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
     335             : 
     336             : template <>
     337             : struct OperandTraits<GetElementPtrConstantExpr>
     338             :     : public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {};
     339             : 
     340      378550 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
     341             : 
     342             : template <>
     343             : struct OperandTraits<CompareConstantExpr>
     344             :     : public FixedNumOperandTraits<CompareConstantExpr, 2> {};
     345        1161 : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
     346             : 
     347             : template <class ConstantClass> struct ConstantAggrKeyType;
     348             : struct InlineAsmKeyType;
     349             : struct ConstantExprKeyType;
     350             : 
     351             : template <class ConstantClass> struct ConstantInfo;
     352             : template <> struct ConstantInfo<ConstantExpr> {
     353             :   using ValType = ConstantExprKeyType;
     354             :   using TypeClass = Type;
     355             : };
     356             : template <> struct ConstantInfo<InlineAsm> {
     357             :   using ValType = InlineAsmKeyType;
     358             :   using TypeClass = PointerType;
     359             : };
     360             : template <> struct ConstantInfo<ConstantArray> {
     361             :   using ValType = ConstantAggrKeyType<ConstantArray>;
     362             :   using TypeClass = ArrayType;
     363             : };
     364             : template <> struct ConstantInfo<ConstantStruct> {
     365             :   using ValType = ConstantAggrKeyType<ConstantStruct>;
     366             :   using TypeClass = StructType;
     367             : };
     368             : template <> struct ConstantInfo<ConstantVector> {
     369             :   using ValType = ConstantAggrKeyType<ConstantVector>;
     370             :   using TypeClass = VectorType;
     371             : };
     372             : 
     373             : template <class ConstantClass> struct ConstantAggrKeyType {
     374             :   ArrayRef<Constant *> Operands;
     375             : 
     376      132209 :   ConstantAggrKeyType(ArrayRef<Constant *> Operands) : Operands(Operands) {}
     377             : 
     378             :   ConstantAggrKeyType(ArrayRef<Constant *> Operands, const ConstantClass *)
     379             :       : Operands(Operands) {}
     380             : 
     381       39278 :   ConstantAggrKeyType(const ConstantClass *C,
     382       78556 :                       SmallVectorImpl<Constant *> &Storage) {
     383             :     assert(Storage.empty() && "Expected empty storage");
     384     3602315 :     for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I)
     385     7047518 :       Storage.push_back(C->getOperand(I));
     386       78556 :     Operands = Storage;
     387       39278 :   }
     388             : 
     389             :   bool operator==(const ConstantAggrKeyType &X) const {
     390             :     return Operands == X.Operands;
     391             :   }
     392             : 
     393      102690 :   bool operator==(const ConstantClass *C) const {
     394      205380 :     if (Operands.size() != C->getNumOperands())
     395             :       return false;
     396      438057 :     for (unsigned I = 0, E = Operands.size(); I != E; ++I)
     397     1048920 :       if (Operands[I] != C->getOperand(I))
     398             :         return false;
     399             :     return true;
     400             :   }
     401             : 
     402             :   unsigned getHash() const {
     403      517752 :     return hash_combine_range(Operands.begin(), Operands.end());
     404             :   }
     405             : 
     406             :   using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
     407             : 
     408       43796 :   ConstantClass *create(TypeClass *Ty) const {
     409       43796 :     return new (Operands.size()) ConstantClass(Ty, Operands);
     410             :   }
     411             : };
     412             : 
     413             : struct InlineAsmKeyType {
     414             :   StringRef AsmString;
     415             :   StringRef Constraints;
     416             :   FunctionType *FTy;
     417             :   bool HasSideEffects;
     418             :   bool IsAlignStack;
     419             :   InlineAsm::AsmDialect AsmDialect;
     420             : 
     421             :   InlineAsmKeyType(StringRef AsmString, StringRef Constraints,
     422             :                    FunctionType *FTy, bool HasSideEffects, bool IsAlignStack,
     423             :                    InlineAsm::AsmDialect AsmDialect)
     424       10870 :       : AsmString(AsmString), Constraints(Constraints), FTy(FTy),
     425             :         HasSideEffects(HasSideEffects), IsAlignStack(IsAlignStack),
     426       10870 :         AsmDialect(AsmDialect) {}
     427             : 
     428             :   InlineAsmKeyType(const InlineAsm *Asm, SmallVectorImpl<Constant *> &)
     429             :       : AsmString(Asm->getAsmString()), Constraints(Asm->getConstraintString()),
     430         522 :         FTy(Asm->getFunctionType()), HasSideEffects(Asm->hasSideEffects()),
     431        3132 :         IsAlignStack(Asm->isAlignStack()), AsmDialect(Asm->getDialect()) {}
     432             : 
     433             :   bool operator==(const InlineAsmKeyType &X) const {
     434             :     return HasSideEffects == X.HasSideEffects &&
     435             :            IsAlignStack == X.IsAlignStack && AsmDialect == X.AsmDialect &&
     436             :            AsmString == X.AsmString && Constraints == X.Constraints &&
     437             :            FTy == X.FTy;
     438             :   }
     439             : 
     440        7755 :   bool operator==(const InlineAsm *Asm) const {
     441       15504 :     return HasSideEffects == Asm->hasSideEffects() &&
     442       15498 :            IsAlignStack == Asm->isAlignStack() &&
     443        7749 :            AsmDialect == Asm->getDialect() &&
     444       15498 :            AsmString == Asm->getAsmString() &&
     445       28600 :            Constraints == Asm->getConstraintString() &&
     446       14384 :            FTy == Asm->getFunctionType();
     447             :   }
     448             : 
     449             :   unsigned getHash() const {
     450       22784 :     return hash_combine(AsmString, Constraints, HasSideEffects, IsAlignStack,
     451       22784 :                         AsmDialect, FTy);
     452             :   }
     453             : 
     454             :   using TypeClass = ConstantInfo<InlineAsm>::TypeClass;
     455             : 
     456        4241 :   InlineAsm *create(TypeClass *Ty) const {
     457             :     assert(PointerType::getUnqual(FTy) == Ty);
     458        8482 :     return new InlineAsm(FTy, AsmString, Constraints, HasSideEffects,
     459       29687 :                          IsAlignStack, AsmDialect);
     460             :   }
     461             : };
     462             : 
     463             : struct ConstantExprKeyType {
     464             :   uint8_t Opcode;
     465             :   uint8_t SubclassOptionalData;
     466             :   uint16_t SubclassData;
     467             :   ArrayRef<Constant *> Ops;
     468             :   ArrayRef<unsigned> Indexes;
     469             :   Type *ExplicitTy;
     470             : 
     471             :   ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops,
     472             :                       unsigned short SubclassData = 0,
     473             :                       unsigned short SubclassOptionalData = 0,
     474             :                       ArrayRef<unsigned> Indexes = None,
     475             :                       Type *ExplicitTy = nullptr)
     476    11817349 :       : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData),
     477             :         SubclassData(SubclassData), Ops(Ops), Indexes(Indexes),
     478    11817349 :         ExplicitTy(ExplicitTy) {}
     479             : 
     480         871 :   ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE)
     481        1742 :       : Opcode(CE->getOpcode()),
     482        1742 :         SubclassOptionalData(CE->getRawSubclassOptionalData()),
     483         879 :         SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands),
     484        2621 :         Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {}
     485             : 
     486      844555 :   ConstantExprKeyType(const ConstantExpr *CE,
     487             :                       SmallVectorImpl<Constant *> &Storage)
     488     1689110 :       : Opcode(CE->getOpcode()),
     489     1689110 :         SubclassOptionalData(CE->getRawSubclassOptionalData()),
     490      845010 :         SubclassData(CE->isCompare() ? CE->getPredicate() : 0),
     491     3378675 :         Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {
     492             :     assert(Storage.empty() && "Expected empty storage");
     493     4025599 :     for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I)
     494     4672978 :       Storage.push_back(CE->getOperand(I));
     495     1689110 :     Ops = Storage;
     496      844555 :   }
     497             : 
     498             :   bool operator==(const ConstantExprKeyType &X) const {
     499             :     return Opcode == X.Opcode && SubclassData == X.SubclassData &&
     500             :            SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops &&
     501             :            Indexes == X.Indexes;
     502             :   }
     503             : 
     504    15541662 :   bool operator==(const ConstantExpr *CE) const {
     505    31083324 :     if (Opcode != CE->getOpcode())
     506             :       return false;
     507    30944814 :     if (SubclassOptionalData != CE->getRawSubclassOptionalData())
     508             :       return false;
     509    30939938 :     if (Ops.size() != CE->getNumOperands())
     510             :       return false;
     511    15469764 :     if (SubclassData != (CE->isCompare() ? CE->getPredicate() : 0))
     512             :       return false;
     513    46813364 :     for (unsigned I = 0, E = Ops.size(); I != E; ++I)
     514   106452567 :       if (Ops[I] != CE->getOperand(I))
     515             :         return false;
     516    22658350 :     if (Indexes != (CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()))
     517             :       return false;
     518    11329175 :     return true;
     519             :   }
     520             : 
     521    12662775 :   unsigned getHash() const {
     522    25325550 :     return hash_combine(Opcode, SubclassOptionalData, SubclassData,
     523    50651100 :                         hash_combine_range(Ops.begin(), Ops.end()),
     524    75976650 :                         hash_combine_range(Indexes.begin(), Indexes.end()));
     525             :   }
     526             : 
     527             :   using TypeClass = ConstantInfo<ConstantExpr>::TypeClass;
     528             : 
     529      488294 :   ConstantExpr *create(TypeClass *Ty) const {
     530      488294 :     switch (Opcode) {
     531      109213 :     default:
     532      218426 :       if (Instruction::isCast(Opcode))
     533      322077 :         return new UnaryConstantExpr(Opcode, Ops[0], Ty);
     534        1854 :       if ((Opcode >= Instruction::BinaryOpsBegin &&
     535             :            Opcode < Instruction::BinaryOpsEnd))
     536        5562 :         return new BinaryConstantExpr(Opcode, Ops[0], Ops[1],
     537        7416 :                                       SubclassOptionalData);
     538           0 :       llvm_unreachable("Invalid ConstantExpr!");
     539          85 :     case Instruction::Select:
     540         170 :       return new SelectConstantExpr(Ops[0], Ops[1], Ops[2]);
     541          54 :     case Instruction::ExtractElement:
     542         108 :       return new ExtractElementConstantExpr(Ops[0], Ops[1]);
     543           0 :     case Instruction::InsertElement:
     544           0 :       return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]);
     545           0 :     case Instruction::ShuffleVector:
     546           0 :       return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]);
     547           1 :     case Instruction::InsertValue:
     548           2 :       return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty);
     549           4 :     case Instruction::ExtractValue:
     550           8 :       return new ExtractValueConstantExpr(Ops[0], Indexes, Ty);
     551      378550 :     case Instruction::GetElementPtr:
     552     1514200 :       return GetElementPtrConstantExpr::Create(
     553      378550 :           ExplicitTy ? ExplicitTy
     554           0 :                      : cast<PointerType>(Ops[0]->getType()->getScalarType())
     555           0 :                            ->getElementType(),
     556     1135650 :           Ops[0], Ops.slice(1), Ty, SubclassOptionalData);
     557         375 :     case Instruction::ICmp:
     558         375 :       return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData,
     559        1125 :                                      Ops[0], Ops[1]);
     560          12 :     case Instruction::FCmp:
     561          12 :       return new CompareConstantExpr(Ty, Instruction::FCmp, SubclassData,
     562          36 :                                      Ops[0], Ops[1]);
     563             :     }
     564             :   }
     565             : };
     566             : 
     567      742500 : template <class ConstantClass> class ConstantUniqueMap {
     568             : public:
     569             :   using ValType = typename ConstantInfo<ConstantClass>::ValType;
     570             :   using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
     571             :   using LookupKey = std::pair<TypeClass *, ValType>;
     572             : 
     573             :   /// Key and hash together, so that we compute the hash only once and reuse it.
     574             :   using LookupKeyHashed = std::pair<unsigned, LookupKey>;
     575             : 
     576             : private:
     577             :   struct MapInfo {
     578             :     using ConstantClassInfo = DenseMapInfo<ConstantClass *>;
     579             : 
     580             :     static inline ConstantClass *getEmptyKey() {
     581             :       return ConstantClassInfo::getEmptyKey();
     582             :     }
     583             : 
     584             :     static inline ConstantClass *getTombstoneKey() {
     585             :       return ConstantClassInfo::getTombstoneKey();
     586             :     }
     587             : 
     588      884355 :     static unsigned getHashValue(const ConstantClass *CP) {
     589     1768710 :       SmallVector<Constant *, 32> Storage;
     590     2692865 :       return getHashValue(LookupKey(CP->getType(), ValType(CP, Storage)));
     591             :     }
     592             : 
     593             :     static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) {
     594    12507309 :       return LHS == RHS;
     595             :     }
     596             : 
     597    12846751 :     static unsigned getHashValue(const LookupKey &Val) {
     598    25877478 :       return hash_combine(Val.first, Val.second.getHash());
     599             :     }
     600             : 
     601             :     static unsigned getHashValue(const LookupKeyHashed &Val) {
     602             :       return Val.first;
     603             :     }
     604             : 
     605             :     static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) {
     606    42599738 :       if (RHS == getEmptyKey() || RHS == getTombstoneKey())
     607             :         return false;
     608    20789726 :       if (LHS.first != RHS->getType())
     609             :         return false;
     610    15652107 :       return LHS.second == RHS;
     611             :     }
     612             : 
     613             :     static bool isEqual(const LookupKeyHashed &LHS, const ConstantClass *RHS) {
     614    43661348 :       return isEqual(LHS.second, RHS);
     615             :     }
     616             :   };
     617             : 
     618             : public:
     619             :   using MapTy = DenseSet<ConstantClass *, MapInfo>;
     620             : 
     621             : private:
     622             :   MapTy Map;
     623             : 
     624             : public:
     625      295267 :   typename MapTy::iterator begin() { return Map.begin(); }
     626      295268 :   typename MapTy::iterator end() { return Map.end(); }
     627             : 
     628      183314 :   void freeConstants() {
     629      973039 :     for (auto &I : Map)
     630       33790 :       delete I; // Asserts that use_empty().
     631      183314 :   }
     632             : 
     633             : private:
     634       43796 :   ConstantClass *create(TypeClass *Ty, ValType V, LookupKeyHashed &HashKey) {
     635      536331 :     ConstantClass *Result = V.create(Ty);
     636             : 
     637             :     assert(Result->getType() == Ty && "Type specified is not correct!");
     638     1072662 :     Map.insert_as(Result, HashKey);
     639             : 
     640       43796 :     return Result;
     641             :   }
     642             : 
     643             : public:
     644             :   /// Return the specified constant from the map, creating it if necessary.
     645    11960428 :   ConstantClass *getOrCreate(TypeClass *Ty, ValType V) {
     646    11960428 :     LookupKey Key(Ty, V);
     647             :     /// Hash once, and reuse it for the lookup and the insertion if needed.
     648    23920856 :     LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
     649             : 
     650    11960428 :     ConstantClass *Result = nullptr;
     651             : 
     652    23920856 :     auto I = Map.find_as(Lookup);
     653    47841712 :     if (I == Map.end())
     654     1028866 :       Result = create(Ty, V, Lookup);
     655             :     else
     656    11424097 :       Result = *I;
     657             :     assert(Result && "Unexpected nullptr");
     658             : 
     659    11960428 :     return Result;
     660             :   }
     661             : 
     662             :   /// Remove this constant from the map
     663             :   void remove(ConstantClass *CP) {
     664      578532 :     typename MapTy::iterator I = Map.find(CP);
     665             :     assert(I != Map.end() && "Constant not found in constant table!");
     666             :     assert(*I == CP && "Didn't find correct element?");
     667      578532 :     Map.erase(I);
     668             :   }
     669             : 
     670        1968 :   ConstantClass *replaceOperandsInPlace(ArrayRef<Constant *> Operands,
     671             :                                         ConstantClass *CP, Value *From,
     672             :                                         Constant *To, unsigned NumUpdated = 0,
     673             :                                         unsigned OperandNo = ~0u) {
     674        5033 :     LookupKey Key(CP->getType(), ValType(Operands, CP));
     675             :     /// Hash once, and reuse it for the lookup and the insertion if needed.
     676        3936 :     LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
     677             : 
     678        3936 :     auto I = Map.find_as(Lookup);
     679        7872 :     if (I != Map.end())
     680         124 :       return *I;
     681             : 
     682             :     // Update to the new value.  Optimize for the case when we have a single
     683             :     // operand that we're changing, but handle bulk updates efficiently.
     684        3688 :     remove(CP);
     685        1844 :     if (NumUpdated == 1) {
     686             :       assert(OperandNo < CP->getNumOperands() && "Invalid index");
     687             :       assert(CP->getOperand(OperandNo) != To && "I didn't contain From!");
     688        1833 :       CP->setOperand(OperandNo, To);
     689             :     } else {
     690          66 :       for (unsigned I = 0, E = CP->getNumOperands(); I != E; ++I)
     691          88 :         if (CP->getOperand(I) == From)
     692          27 :           CP->setOperand(I, To);
     693             :     }
     694        3688 :     Map.insert_as(CP, Lookup);
     695        1844 :     return nullptr;
     696             :   }
     697             : 
     698             :   void dump() const { DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); }
     699             : };
     700             : 
     701             : } // end namespace llvm
     702             : 
     703             : #endif // LLVM_LIB_IR_CONSTANTSCONTEXT_H

Generated by: LCOV version 1.13