File indexing completed on 2026-05-10 08:43:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
0034 class TargetFolder final : public IRBuilderFolder {
0035 const DataLayout &DL;
0036
0037
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
0049
0050
0051
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
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
0202
0203
0204 Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
0205 if (C->getType() == DestTy)
0206 return C;
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;
0214 return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
0215 }
0216 };
0217
0218 }
0219
0220 #endif