1 //===- InstSimplifyFolder.h - InstSimplify 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 InstSimplifyFolder class, a helper for IRBuilder. 10 // It provides IRBuilder with a set of methods for folding operations to 11 // existing values using InstructionSimplify. At the moment, only a subset of 12 // the implementation uses InstructionSimplify. The rest of the implementation 13 // only folds constants. 14 // 15 // The folder also applies target-specific constant folding. 16 // 17 //===----------------------------------------------------------------------===// 18 19 #ifndef LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H 20 #define LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H 21 22 #include "llvm/ADT/ArrayRef.h" 23 #include "llvm/Analysis/InstructionSimplify.h" 24 #include "llvm/Analysis/TargetFolder.h" 25 #include "llvm/IR/CmpPredicate.h" 26 #include "llvm/IR/IRBuilderFolder.h" 27 #include "llvm/IR/Instruction.h" 28 29 namespace llvm { 30 class Constant; 31 32 /// InstSimplifyFolder - Use InstructionSimplify to fold operations to existing 33 /// values. Also applies target-specific constant folding when not using 34 /// InstructionSimplify. 35 class InstSimplifyFolder final : public IRBuilderFolder { 36 TargetFolder ConstFolder; 37 SimplifyQuery SQ; 38 39 virtual void anchor(); 40 41 public: 42 explicit InstSimplifyFolder(const DataLayout &DL) : ConstFolder(DL), SQ(DL) {} 43 44 //===--------------------------------------------------------------------===// 45 // Value-based folders. 46 // 47 // Return an existing value or a constant if the operation can be simplified. 48 // Otherwise return nullptr. 49 //===--------------------------------------------------------------------===// 50 51 Value *FoldBinOp(Instruction::BinaryOps Opc, Value *LHS, 52 Value *RHS) const override { 53 return simplifyBinOp(Opc, LHS, RHS, SQ); 54 } 55 56 Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, 57 bool IsExact) const override { 58 return simplifyBinOp(Opc, LHS, RHS, SQ); 59 } 60 61 Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, 62 bool HasNUW, bool HasNSW) const override { 63 return simplifyBinOp(Opc, LHS, RHS, SQ); 64 } 65 66 Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, 67 FastMathFlags FMF) const override { 68 return simplifyBinOp(Opc, LHS, RHS, FMF, SQ); 69 } 70 71 Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V, 72 FastMathFlags FMF) const override { 73 return simplifyUnOp(Opc, V, FMF, SQ); 74 } 75 76 Value *FoldCmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override { 77 return simplifyCmpInst(P, LHS, RHS, SQ); 78 } 79 80 Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList, 81 GEPNoWrapFlags NW) const override { 82 return simplifyGEPInst(Ty, Ptr, IdxList, NW, SQ); 83 } 84 85 Value *FoldSelect(Value *C, Value *True, Value *False) const override { 86 return simplifySelectInst(C, True, False, SQ); 87 } 88 89 Value *FoldExtractValue(Value *Agg, 90 ArrayRef<unsigned> IdxList) const override { 91 return simplifyExtractValueInst(Agg, IdxList, SQ); 92 }; 93 94 Value *FoldInsertValue(Value *Agg, Value *Val, 95 ArrayRef<unsigned> IdxList) const override { 96 return simplifyInsertValueInst(Agg, Val, IdxList, SQ); 97 } 98 99 Value *FoldExtractElement(Value *Vec, Value *Idx) const override { 100 return simplifyExtractElementInst(Vec, Idx, SQ); 101 } 102 103 Value *FoldInsertElement(Value *Vec, Value *NewElt, 104 Value *Idx) const override { 105 return simplifyInsertElementInst(Vec, NewElt, Idx, SQ); 106 } 107 108 Value *FoldShuffleVector(Value *V1, Value *V2, 109 ArrayRef<int> Mask) const override { 110 Type *RetTy = VectorType::get( 111 cast<VectorType>(V1->getType())->getElementType(), Mask.size(), 112 isa<ScalableVectorType>(V1->getType())); 113 return simplifyShuffleVectorInst(V1, V2, Mask, RetTy, SQ); 114 } 115 116 Value *FoldCast(Instruction::CastOps Op, Value *V, 117 Type *DestTy) const override { 118 return simplifyCastInst(Op, V, DestTy, SQ); 119 } 120 121 Value *FoldBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Type *Ty, 122 Instruction *FMFSource) const override { 123 return simplifyBinaryIntrinsic(ID, Ty, LHS, RHS, SQ, 124 dyn_cast_if_present<CallBase>(FMFSource)); 125 } 126 127 //===--------------------------------------------------------------------===// 128 // Cast/Conversion Operators 129 //===--------------------------------------------------------------------===// 130 131 Value *CreatePointerCast(Constant *C, Type *DestTy) const override { 132 if (C->getType() == DestTy) 133 return C; // avoid calling Fold 134 return ConstFolder.CreatePointerCast(C, DestTy); 135 } 136 137 Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C, 138 Type *DestTy) const override { 139 if (C->getType() == DestTy) 140 return C; // avoid calling Fold 141 return ConstFolder.CreatePointerBitCastOrAddrSpaceCast(C, DestTy); 142 } 143 }; 144 145 } // end namespace llvm 146 147 #endif // LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H 148