Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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(Opc, LHS, RHS, SQ); |
||
53 | } |
||
54 | |||
55 | Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, |
||
56 | bool IsExact) const override { |
||
57 | return simplifyBinOp(Opc, LHS, RHS, SQ); |
||
58 | } |
||
59 | |||
60 | Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, |
||
61 | bool HasNUW, bool HasNSW) const override { |
||
62 | return simplifyBinOp(Opc, LHS, RHS, SQ); |
||
63 | } |
||
64 | |||
65 | Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, |
||
66 | FastMathFlags FMF) const override { |
||
67 | return simplifyBinOp(Opc, LHS, RHS, FMF, SQ); |
||
68 | } |
||
69 | |||
70 | Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V, |
||
71 | FastMathFlags FMF) const override { |
||
72 | return simplifyUnOp(Opc, V, FMF, SQ); |
||
73 | } |
||
74 | |||
75 | Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override { |
||
76 | return simplifyICmpInst(P, LHS, RHS, SQ); |
||
77 | } |
||
78 | |||
79 | Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList, |
||
80 | bool IsInBounds = false) const override { |
||
81 | return simplifyGEPInst(Ty, Ptr, IdxList, IsInBounds, SQ); |
||
82 | } |
||
83 | |||
84 | Value *FoldSelect(Value *C, Value *True, Value *False) const override { |
||
85 | return simplifySelectInst(C, True, False, SQ); |
||
86 | } |
||
87 | |||
88 | Value *FoldExtractValue(Value *Agg, |
||
89 | ArrayRef<unsigned> IdxList) const override { |
||
90 | return simplifyExtractValueInst(Agg, IdxList, SQ); |
||
91 | }; |
||
92 | |||
93 | Value *FoldInsertValue(Value *Agg, Value *Val, |
||
94 | ArrayRef<unsigned> IdxList) const override { |
||
95 | return simplifyInsertValueInst(Agg, Val, IdxList, SQ); |
||
96 | } |
||
97 | |||
98 | Value *FoldExtractElement(Value *Vec, Value *Idx) const override { |
||
99 | return simplifyExtractElementInst(Vec, Idx, SQ); |
||
100 | } |
||
101 | |||
102 | Value *FoldInsertElement(Value *Vec, Value *NewElt, |
||
103 | Value *Idx) const override { |
||
104 | return simplifyInsertElementInst(Vec, NewElt, Idx, SQ); |
||
105 | } |
||
106 | |||
107 | Value *FoldShuffleVector(Value *V1, Value *V2, |
||
108 | ArrayRef<int> Mask) const override { |
||
109 | Type *RetTy = VectorType::get( |
||
110 | cast<VectorType>(V1->getType())->getElementType(), Mask.size(), |
||
111 | isa<ScalableVectorType>(V1->getType())); |
||
112 | return simplifyShuffleVectorInst(V1, V2, Mask, RetTy, SQ); |
||
113 | } |
||
114 | |||
115 | //===--------------------------------------------------------------------===// |
||
116 | // Cast/Conversion Operators |
||
117 | //===--------------------------------------------------------------------===// |
||
118 | |||
119 | Value *CreateCast(Instruction::CastOps Op, Constant *C, |
||
120 | Type *DestTy) const override { |
||
121 | if (C->getType() == DestTy) |
||
122 | return C; // avoid calling Fold |
||
123 | return ConstFolder.CreateCast(Op, C, DestTy); |
||
124 | } |
||
125 | Value *CreateIntCast(Constant *C, Type *DestTy, |
||
126 | bool isSigned) const override { |
||
127 | if (C->getType() == DestTy) |
||
128 | return C; // avoid calling Fold |
||
129 | return ConstFolder.CreateIntCast(C, DestTy, isSigned); |
||
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 | Value *CreateFPCast(Constant *C, Type *DestTy) const override { |
||
137 | if (C->getType() == DestTy) |
||
138 | return C; // avoid calling Fold |
||
139 | return ConstFolder.CreateFPCast(C, DestTy); |
||
140 | } |
||
141 | Value *CreateBitCast(Constant *C, Type *DestTy) const override { |
||
142 | return ConstFolder.CreateBitCast(C, DestTy); |
||
143 | } |
||
144 | Value *CreateIntToPtr(Constant *C, Type *DestTy) const override { |
||
145 | return ConstFolder.CreateIntToPtr(C, DestTy); |
||
146 | } |
||
147 | Value *CreatePtrToInt(Constant *C, Type *DestTy) const override { |
||
148 | return ConstFolder.CreatePtrToInt(C, DestTy); |
||
149 | } |
||
150 | Value *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override { |
||
151 | if (C->getType() == DestTy) |
||
152 | return C; // avoid calling Fold |
||
153 | return ConstFolder.CreateZExtOrBitCast(C, DestTy); |
||
154 | } |
||
155 | Value *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override { |
||
156 | if (C->getType() == DestTy) |
||
157 | return C; // avoid calling Fold |
||
158 | return ConstFolder.CreateSExtOrBitCast(C, DestTy); |
||
159 | } |
||
160 | Value *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override { |
||
161 | if (C->getType() == DestTy) |
||
162 | return C; // avoid calling Fold |
||
163 | return ConstFolder.CreateTruncOrBitCast(C, DestTy); |
||
164 | } |
||
165 | |||
166 | Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C, |
||
167 | Type *DestTy) const override { |
||
168 | if (C->getType() == DestTy) |
||
169 | return C; // avoid calling Fold |
||
170 | return ConstFolder.CreatePointerBitCastOrAddrSpaceCast(C, DestTy); |
||
171 | } |
||
172 | |||
173 | //===--------------------------------------------------------------------===// |
||
174 | // Compare Instructions |
||
175 | //===--------------------------------------------------------------------===// |
||
176 | |||
177 | Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS, |
||
178 | Constant *RHS) const override { |
||
179 | return ConstFolder.CreateFCmp(P, LHS, RHS); |
||
180 | } |
||
181 | }; |
||
182 | |||
183 | } // end namespace llvm |
||
184 | |||
185 | #endif // LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H |