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/IRBuilderFolder.h" |
26 | #include "llvm/IR/Instruction.h" |
27 | |
28 | namespace llvm { |
29 | class Constant; |
30 | |
31 | /// InstSimplifyFolder - Use InstructionSimplify to fold operations to existing |
32 | /// values. Also applies target-specific constant folding when not using |
33 | /// InstructionSimplify. |
34 | class InstSimplifyFolder final : public IRBuilderFolder { |
35 | TargetFolder ConstFolder; |
36 | SimplifyQuery SQ; |
37 | |
38 | virtual void anchor(); |
39 | |
40 | public: |
41 | InstSimplifyFolder(const DataLayout &DL) : ConstFolder(DL), SQ(DL) {} |
42 | |
43 | //===--------------------------------------------------------------------===// |
44 | // Value-based folders. |
45 | // |
46 | // Return an existing value or a constant if the operation can be simplified. |
47 | // Otherwise return nullptr. |
48 | //===--------------------------------------------------------------------===// |
49 | |
50 | Value *FoldBinOp(Instruction::BinaryOps Opc, Value *LHS, |
51 | Value *RHS) const override { |
52 | return simplifyBinOp(Opcode: Opc, LHS, RHS, Q: SQ); |
53 | } |
54 | |
55 | Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, |
56 | bool IsExact) const override { |
57 | return simplifyBinOp(Opcode: Opc, LHS, RHS, Q: SQ); |
58 | } |
59 | |
60 | Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, |
61 | bool HasNUW, bool HasNSW) const override { |
62 | return simplifyBinOp(Opcode: Opc, LHS, RHS, Q: SQ); |
63 | } |
64 | |
65 | Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, |
66 | FastMathFlags FMF) const override { |
67 | return simplifyBinOp(Opcode: Opc, LHS, RHS, FMF, Q: SQ); |
68 | } |
69 | |
70 | Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V, |
71 | FastMathFlags FMF) const override { |
72 | return simplifyUnOp(Opcode: Opc, Op: V, FMF, Q: SQ); |
73 | } |
74 | |
75 | Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override { |
76 | return simplifyICmpInst(Predicate: P, LHS, RHS, Q: SQ); |
77 | } |
78 | |
79 | Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList, |
80 | bool IsInBounds = false) const override { |
81 | return simplifyGEPInst(SrcTy: Ty, Ptr, Indices: IdxList, InBounds: IsInBounds, Q: SQ); |
82 | } |
83 | |
84 | Value *FoldSelect(Value *C, Value *True, Value *False) const override { |
85 | return simplifySelectInst(Cond: C, TrueVal: True, FalseVal: False, Q: SQ); |
86 | } |
87 | |
88 | Value *(Value *Agg, |
89 | ArrayRef<unsigned> IdxList) const override { |
90 | return simplifyExtractValueInst(Agg, Idxs: IdxList, Q: SQ); |
91 | }; |
92 | |
93 | Value *FoldInsertValue(Value *Agg, Value *Val, |
94 | ArrayRef<unsigned> IdxList) const override { |
95 | return simplifyInsertValueInst(Agg, Val, Idxs: IdxList, Q: SQ); |
96 | } |
97 | |
98 | Value *(Value *Vec, Value *Idx) const override { |
99 | return simplifyExtractElementInst(Vec, Idx, Q: SQ); |
100 | } |
101 | |
102 | Value *FoldInsertElement(Value *Vec, Value *NewElt, |
103 | Value *Idx) const override { |
104 | return simplifyInsertElementInst(Vec, Elt: NewElt, Idx, Q: SQ); |
105 | } |
106 | |
107 | Value *FoldShuffleVector(Value *V1, Value *V2, |
108 | ArrayRef<int> Mask) const override { |
109 | Type *RetTy = VectorType::get( |
110 | ElementType: cast<VectorType>(Val: V1->getType())->getElementType(), NumElements: Mask.size(), |
111 | Scalable: isa<ScalableVectorType>(Val: V1->getType())); |
112 | return simplifyShuffleVectorInst(Op0: V1, Op1: V2, Mask, RetTy, Q: SQ); |
113 | } |
114 | |
115 | Value *FoldCast(Instruction::CastOps Op, Value *V, |
116 | Type *DestTy) const override { |
117 | return simplifyCastInst(CastOpc: Op, Op: V, Ty: DestTy, Q: SQ); |
118 | } |
119 | |
120 | //===--------------------------------------------------------------------===// |
121 | // Cast/Conversion Operators |
122 | //===--------------------------------------------------------------------===// |
123 | |
124 | Value *CreatePointerCast(Constant *C, Type *DestTy) const override { |
125 | if (C->getType() == DestTy) |
126 | return C; // avoid calling Fold |
127 | return ConstFolder.CreatePointerCast(C, DestTy); |
128 | } |
129 | |
130 | Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C, |
131 | Type *DestTy) const override { |
132 | if (C->getType() == DestTy) |
133 | return C; // avoid calling Fold |
134 | return ConstFolder.CreatePointerBitCastOrAddrSpaceCast(C, DestTy); |
135 | } |
136 | |
137 | //===--------------------------------------------------------------------===// |
138 | // Compare Instructions |
139 | //===--------------------------------------------------------------------===// |
140 | |
141 | Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS, |
142 | Constant *RHS) const override { |
143 | return ConstFolder.CreateFCmp(P, LHS, RHS); |
144 | } |
145 | }; |
146 | |
147 | } // end namespace llvm |
148 | |
149 | #endif // LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H |
150 | |