Back to home page

EIC code displayed by LXR

 
 

    


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

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