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

            Line data    Source code
       1              : //===- ConstantFolder.h - Constant folding helper ---------------*- 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 ConstantFolder class, a helper for IRBuilder.
      10              : // It provides IRBuilder with a set of methods for creating constants
      11              : // with minimal folding.  For general constant creation and folding,
      12              : // use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
      13              : //
      14              : //===----------------------------------------------------------------------===//
      15              : 
      16              : #ifndef LLVM_IR_CONSTANTFOLDER_H
      17              : #define LLVM_IR_CONSTANTFOLDER_H
      18              : 
      19              : #include "llvm/ADT/ArrayRef.h"
      20              : #include "llvm/ADT/STLExtras.h"
      21              : #include "llvm/IR/ConstantFold.h"
      22              : #include "llvm/IR/Constants.h"
      23              : #include "llvm/IR/IRBuilderFolder.h"
      24              : #include "llvm/IR/Instruction.h"
      25              : #include "llvm/IR/Operator.h"
      26              : 
      27              : namespace llvm {
      28              : 
      29              : /// ConstantFolder - Create constants with minimum, target independent, folding.
      30              : class ConstantFolder final : public IRBuilderFolder {
      31              :   virtual void anchor();
      32              : 
      33              : public:
      34            0 :   explicit ConstantFolder() = default;
      35              : 
      36              :   //===--------------------------------------------------------------------===//
      37              :   // Value-based folders.
      38              :   //
      39              :   // Return an existing value or a constant if the operation can be simplified.
      40              :   // Otherwise return nullptr.
      41              :   //===--------------------------------------------------------------------===//
      42              : 
      43              :   Value *FoldBinOp(Instruction::BinaryOps Opc, Value *LHS,
      44              :                    Value *RHS) const override {
      45              :     auto *LC = dyn_cast<Constant>(LHS);
      46              :     auto *RC = dyn_cast<Constant>(RHS);
      47              :     if (LC && RC) {
      48              :       if (ConstantExpr::isDesirableBinOp(Opc))
      49              :         return ConstantExpr::get(Opc, LC, RC);
      50              :       return ConstantFoldBinaryInstruction(Opc, LC, RC);
      51              :     }
      52              :     return nullptr;
      53              :   }
      54              : 
      55              :   Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
      56              :                         bool IsExact) const override {
      57              :     auto *LC = dyn_cast<Constant>(LHS);
      58              :     auto *RC = dyn_cast<Constant>(RHS);
      59              :     if (LC && RC) {
      60              :       if (ConstantExpr::isDesirableBinOp(Opc))
      61              :         return ConstantExpr::get(Opc, LC, RC,
      62              :                                  IsExact ? PossiblyExactOperator::IsExact : 0);
      63              :       return ConstantFoldBinaryInstruction(Opc, LC, RC);
      64              :     }
      65              :     return nullptr;
      66              :   }
      67              : 
      68              :   Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
      69              :                          bool HasNUW, bool HasNSW) const override {
      70              :     auto *LC = dyn_cast<Constant>(LHS);
      71              :     auto *RC = dyn_cast<Constant>(RHS);
      72              :     if (LC && RC) {
      73              :       if (ConstantExpr::isDesirableBinOp(Opc)) {
      74              :         unsigned Flags = 0;
      75              :         if (HasNUW)
      76              :           Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
      77              :         if (HasNSW)
      78              :           Flags |= OverflowingBinaryOperator::NoSignedWrap;
      79              :         return ConstantExpr::get(Opc, LC, RC, Flags);
      80              :       }
      81              :       return ConstantFoldBinaryInstruction(Opc, LC, RC);
      82              :     }
      83              :     return nullptr;
      84              :   }
      85              : 
      86              :   Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
      87              :                       FastMathFlags FMF) const override {
      88              :     return FoldBinOp(Opc, LHS, RHS);
      89              :   }
      90              : 
      91              :   Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V,
      92              :                      FastMathFlags FMF) const override {
      93              :     if (Constant *C = dyn_cast<Constant>(V))
      94              :       return ConstantFoldUnaryInstruction(Opc, C);
      95              :     return nullptr;
      96              :   }
      97              : 
      98              :   Value *FoldCmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
      99              :     auto *LC = dyn_cast<Constant>(LHS);
     100              :     auto *RC = dyn_cast<Constant>(RHS);
     101              :     if (LC && RC)
     102              :       return ConstantFoldCompareInstruction(P, LC, RC);
     103              :     return nullptr;
     104              :   }
     105              : 
     106              :   Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
     107              :                  GEPNoWrapFlags NW) const override {
     108              :     if (!ConstantExpr::isSupportedGetElementPtr(Ty))
     109              :       return nullptr;
     110              : 
     111              :     if (auto *PC = dyn_cast<Constant>(Ptr)) {
     112              :       // Every index must be constant.
     113              :       if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
     114              :         return nullptr;
     115              : 
     116              :       return ConstantExpr::getGetElementPtr(Ty, PC, IdxList, NW);
     117              :     }
     118              :     return nullptr;
     119              :   }
     120              : 
     121              :   Value *FoldSelect(Value *C, Value *True, Value *False) const override {
     122              :     auto *CC = dyn_cast<Constant>(C);
     123              :     auto *TC = dyn_cast<Constant>(True);
     124              :     auto *FC = dyn_cast<Constant>(False);
     125              :     if (CC && TC && FC)
     126              :       return ConstantFoldSelectInstruction(CC, TC, FC);
     127              :     return nullptr;
     128              :   }
     129              : 
     130              :   Value *FoldExtractValue(Value *Agg,
     131              :                           ArrayRef<unsigned> IdxList) const override {
     132              :     if (auto *CAgg = dyn_cast<Constant>(Agg))
     133              :       return ConstantFoldExtractValueInstruction(CAgg, IdxList);
     134              :     return nullptr;
     135              :   };
     136              : 
     137              :   Value *FoldInsertValue(Value *Agg, Value *Val,
     138              :                          ArrayRef<unsigned> IdxList) const override {
     139              :     auto *CAgg = dyn_cast<Constant>(Agg);
     140              :     auto *CVal = dyn_cast<Constant>(Val);
     141              :     if (CAgg && CVal)
     142              :       return ConstantFoldInsertValueInstruction(CAgg, CVal, IdxList);
     143              :     return nullptr;
     144              :   }
     145              : 
     146              :   Value *FoldExtractElement(Value *Vec, Value *Idx) const override {
     147              :     auto *CVec = dyn_cast<Constant>(Vec);
     148              :     auto *CIdx = dyn_cast<Constant>(Idx);
     149              :     if (CVec && CIdx)
     150              :       return ConstantExpr::getExtractElement(CVec, CIdx);
     151              :     return nullptr;
     152              :   }
     153              : 
     154              :   Value *FoldInsertElement(Value *Vec, Value *NewElt,
     155              :                            Value *Idx) const override {
     156              :     auto *CVec = dyn_cast<Constant>(Vec);
     157              :     auto *CNewElt = dyn_cast<Constant>(NewElt);
     158              :     auto *CIdx = dyn_cast<Constant>(Idx);
     159              :     if (CVec && CNewElt && CIdx)
     160              :       return ConstantExpr::getInsertElement(CVec, CNewElt, CIdx);
     161              :     return nullptr;
     162              :   }
     163              : 
     164              :   Value *FoldShuffleVector(Value *V1, Value *V2,
     165              :                            ArrayRef<int> Mask) const override {
     166              :     auto *C1 = dyn_cast<Constant>(V1);
     167              :     auto *C2 = dyn_cast<Constant>(V2);
     168              :     if (C1 && C2)
     169              :       return ConstantExpr::getShuffleVector(C1, C2, Mask);
     170              :     return nullptr;
     171              :   }
     172              : 
     173              :   Value *FoldCast(Instruction::CastOps Op, Value *V,
     174              :                   Type *DestTy) const override {
     175              :     if (auto *C = dyn_cast<Constant>(V)) {
     176              :       if (ConstantExpr::isDesirableCastOp(Op))
     177              :         return ConstantExpr::getCast(Op, C, DestTy);
     178              :       return ConstantFoldCastInstruction(Op, C, DestTy);
     179              :     }
     180              :     return nullptr;
     181              :   }
     182              : 
     183              :   Value *FoldBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Type *Ty,
     184              :                              Instruction *FMFSource) const override {
     185              :     // Use TargetFolder or InstSimplifyFolder instead.
     186              :     return nullptr;
     187              :   }
     188              : 
     189              :   //===--------------------------------------------------------------------===//
     190              :   // Cast/Conversion Operators
     191              :   //===--------------------------------------------------------------------===//
     192              : 
     193              :   Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
     194              :     return ConstantExpr::getPointerCast(C, DestTy);
     195              :   }
     196              : 
     197              :   Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
     198              :                                                 Type *DestTy) const override {
     199              :     return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
     200              :   }
     201              : };
     202              : 
     203              : } // end namespace llvm
     204              : 
     205              : #endif // LLVM_IR_CONSTANTFOLDER_H
        

Generated by: LCOV version 2.0-1