Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:57

0001 //===- ConstantFolder.h - Constant folding helper ---------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the ConstantFolder class, a helper for IRBuilder.
0010 // It provides IRBuilder with a set of methods for creating constants
0011 // with minimal folding.  For general constant creation and folding,
0012 // use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 #ifndef LLVM_IR_CONSTANTFOLDER_H
0017 #define LLVM_IR_CONSTANTFOLDER_H
0018 
0019 #include "llvm/ADT/ArrayRef.h"
0020 #include "llvm/ADT/STLExtras.h"
0021 #include "llvm/IR/ConstantFold.h"
0022 #include "llvm/IR/Constants.h"
0023 #include "llvm/IR/IRBuilderFolder.h"
0024 #include "llvm/IR/Instruction.h"
0025 #include "llvm/IR/Operator.h"
0026 
0027 namespace llvm {
0028 
0029 /// ConstantFolder - Create constants with minimum, target independent, folding.
0030 class ConstantFolder final : public IRBuilderFolder {
0031   virtual void anchor();
0032 
0033 public:
0034   explicit ConstantFolder() = default;
0035 
0036   //===--------------------------------------------------------------------===//
0037   // Value-based folders.
0038   //
0039   // Return an existing value or a constant if the operation can be simplified.
0040   // Otherwise return nullptr.
0041   //===--------------------------------------------------------------------===//
0042 
0043   Value *FoldBinOp(Instruction::BinaryOps Opc, Value *LHS,
0044                    Value *RHS) const override {
0045     auto *LC = dyn_cast<Constant>(LHS);
0046     auto *RC = dyn_cast<Constant>(RHS);
0047     if (LC && RC) {
0048       if (ConstantExpr::isDesirableBinOp(Opc))
0049         return ConstantExpr::get(Opc, LC, RC);
0050       return ConstantFoldBinaryInstruction(Opc, LC, RC);
0051     }
0052     return nullptr;
0053   }
0054 
0055   Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
0056                         bool IsExact) const override {
0057     auto *LC = dyn_cast<Constant>(LHS);
0058     auto *RC = dyn_cast<Constant>(RHS);
0059     if (LC && RC) {
0060       if (ConstantExpr::isDesirableBinOp(Opc))
0061         return ConstantExpr::get(Opc, LC, RC,
0062                                  IsExact ? PossiblyExactOperator::IsExact : 0);
0063       return ConstantFoldBinaryInstruction(Opc, LC, RC);
0064     }
0065     return nullptr;
0066   }
0067 
0068   Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
0069                          bool HasNUW, bool HasNSW) const override {
0070     auto *LC = dyn_cast<Constant>(LHS);
0071     auto *RC = dyn_cast<Constant>(RHS);
0072     if (LC && RC) {
0073       if (ConstantExpr::isDesirableBinOp(Opc)) {
0074         unsigned Flags = 0;
0075         if (HasNUW)
0076           Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
0077         if (HasNSW)
0078           Flags |= OverflowingBinaryOperator::NoSignedWrap;
0079         return ConstantExpr::get(Opc, LC, RC, Flags);
0080       }
0081       return ConstantFoldBinaryInstruction(Opc, LC, RC);
0082     }
0083     return nullptr;
0084   }
0085 
0086   Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
0087                       FastMathFlags FMF) const override {
0088     return FoldBinOp(Opc, LHS, RHS);
0089   }
0090 
0091   Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V,
0092                      FastMathFlags FMF) const override {
0093     if (Constant *C = dyn_cast<Constant>(V))
0094       return ConstantFoldUnaryInstruction(Opc, C);
0095     return nullptr;
0096   }
0097 
0098   Value *FoldCmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
0099     auto *LC = dyn_cast<Constant>(LHS);
0100     auto *RC = dyn_cast<Constant>(RHS);
0101     if (LC && RC)
0102       return ConstantFoldCompareInstruction(P, LC, RC);
0103     return nullptr;
0104   }
0105 
0106   Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
0107                  GEPNoWrapFlags NW) const override {
0108     if (!ConstantExpr::isSupportedGetElementPtr(Ty))
0109       return nullptr;
0110 
0111     if (auto *PC = dyn_cast<Constant>(Ptr)) {
0112       // Every index must be constant.
0113       if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
0114         return nullptr;
0115 
0116       return ConstantExpr::getGetElementPtr(Ty, PC, IdxList, NW);
0117     }
0118     return nullptr;
0119   }
0120 
0121   Value *FoldSelect(Value *C, Value *True, Value *False) const override {
0122     auto *CC = dyn_cast<Constant>(C);
0123     auto *TC = dyn_cast<Constant>(True);
0124     auto *FC = dyn_cast<Constant>(False);
0125     if (CC && TC && FC)
0126       return ConstantFoldSelectInstruction(CC, TC, FC);
0127     return nullptr;
0128   }
0129 
0130   Value *FoldExtractValue(Value *Agg,
0131                           ArrayRef<unsigned> IdxList) const override {
0132     if (auto *CAgg = dyn_cast<Constant>(Agg))
0133       return ConstantFoldExtractValueInstruction(CAgg, IdxList);
0134     return nullptr;
0135   };
0136 
0137   Value *FoldInsertValue(Value *Agg, Value *Val,
0138                          ArrayRef<unsigned> IdxList) const override {
0139     auto *CAgg = dyn_cast<Constant>(Agg);
0140     auto *CVal = dyn_cast<Constant>(Val);
0141     if (CAgg && CVal)
0142       return ConstantFoldInsertValueInstruction(CAgg, CVal, IdxList);
0143     return nullptr;
0144   }
0145 
0146   Value *FoldExtractElement(Value *Vec, Value *Idx) const override {
0147     auto *CVec = dyn_cast<Constant>(Vec);
0148     auto *CIdx = dyn_cast<Constant>(Idx);
0149     if (CVec && CIdx)
0150       return ConstantExpr::getExtractElement(CVec, CIdx);
0151     return nullptr;
0152   }
0153 
0154   Value *FoldInsertElement(Value *Vec, Value *NewElt,
0155                            Value *Idx) const override {
0156     auto *CVec = dyn_cast<Constant>(Vec);
0157     auto *CNewElt = dyn_cast<Constant>(NewElt);
0158     auto *CIdx = dyn_cast<Constant>(Idx);
0159     if (CVec && CNewElt && CIdx)
0160       return ConstantExpr::getInsertElement(CVec, CNewElt, CIdx);
0161     return nullptr;
0162   }
0163 
0164   Value *FoldShuffleVector(Value *V1, Value *V2,
0165                            ArrayRef<int> Mask) const override {
0166     auto *C1 = dyn_cast<Constant>(V1);
0167     auto *C2 = dyn_cast<Constant>(V2);
0168     if (C1 && C2)
0169       return ConstantExpr::getShuffleVector(C1, C2, Mask);
0170     return nullptr;
0171   }
0172 
0173   Value *FoldCast(Instruction::CastOps Op, Value *V,
0174                   Type *DestTy) const override {
0175     if (auto *C = dyn_cast<Constant>(V)) {
0176       if (ConstantExpr::isDesirableCastOp(Op))
0177         return ConstantExpr::getCast(Op, C, DestTy);
0178       return ConstantFoldCastInstruction(Op, C, DestTy);
0179     }
0180     return nullptr;
0181   }
0182 
0183   Value *FoldBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Type *Ty,
0184                              Instruction *FMFSource) const override {
0185     // Use TargetFolder or InstSimplifyFolder instead.
0186     return nullptr;
0187   }
0188 
0189   //===--------------------------------------------------------------------===//
0190   // Cast/Conversion Operators
0191   //===--------------------------------------------------------------------===//
0192 
0193   Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
0194     return ConstantExpr::getPointerCast(C, DestTy);
0195   }
0196 
0197   Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
0198                                                 Type *DestTy) const override {
0199     return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
0200   }
0201 };
0202 
0203 } // end namespace llvm
0204 
0205 #endif // LLVM_IR_CONSTANTFOLDER_H