TargetFolder.h revision 3548ea8e905269e819fdd4c7fab42142b745c6c5
1//====-- llvm/Support/TargetFolder.h - Constant folding helper -*- C++ -*-====//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the TargetFolder class, a helper for IRBuilder.
11// It provides IRBuilder with a set of methods for creating constants with
12// target dependent folding, in addition to the same target-independent
13// folding that the ConstantFolder class provides.  For general constant
14// creation and folding, use ConstantExpr and the routines in
15// llvm/Analysis/ConstantFolding.h.
16//
17//===----------------------------------------------------------------------===//
18
19#ifndef LLVM_SUPPORT_TARGETFOLDER_H
20#define LLVM_SUPPORT_TARGETFOLDER_H
21
22#include "llvm/Constants.h"
23#include "llvm/Analysis/ConstantFolding.h"
24
25namespace llvm {
26
27class TargetData;
28class LLVMContext;
29
30/// TargetFolder - Create constants with target dependent folding.
31class TargetFolder {
32  const TargetData *TD;
33  LLVMContext &Context;
34
35  /// Fold - Fold the constant using target specific information.
36  Constant *Fold(Constant *C) const {
37    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
38      if (Constant *CF = ConstantFoldConstantExpression(CE, Context, TD))
39        return CF;
40    return C;
41  }
42
43public:
44  explicit TargetFolder(const TargetData *TheTD, LLVMContext &C) :
45    TD(TheTD), Context(C) {}
46
47  //===--------------------------------------------------------------------===//
48  // Binary Operators
49  //===--------------------------------------------------------------------===//
50
51  Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
52    return Fold(ConstantExpr::getAdd(LHS, RHS));
53  }
54  Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
55    return Fold(ConstantExpr::getNSWAdd(LHS, RHS));
56  }
57  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
58    return Fold(ConstantExpr::getFAdd(LHS, RHS));
59  }
60  Constant *CreateSub(Constant *LHS, Constant *RHS) const {
61    return Fold(ConstantExpr::getSub(LHS, RHS));
62  }
63  Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const {
64    return Fold(ConstantExpr::getNSWSub(LHS, RHS));
65  }
66  Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
67    return Fold(ConstantExpr::getFSub(LHS, RHS));
68  }
69  Constant *CreateMul(Constant *LHS, Constant *RHS) const {
70    return Fold(ConstantExpr::getMul(LHS, RHS));
71  }
72  Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
73    return Fold(ConstantExpr::getFMul(LHS, RHS));
74  }
75  Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
76    return Fold(ConstantExpr::getUDiv(LHS, RHS));
77  }
78  Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
79    return Fold(ConstantExpr::getSDiv(LHS, RHS));
80  }
81  Constant *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
82    return Fold(ConstantExpr::getExactSDiv(LHS, RHS));
83  }
84  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
85    return Fold(ConstantExpr::getFDiv(LHS, RHS));
86  }
87  Constant *CreateURem(Constant *LHS, Constant *RHS) const {
88    return Fold(ConstantExpr::getURem(LHS, RHS));
89  }
90  Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
91    return Fold(ConstantExpr::getSRem(LHS, RHS));
92  }
93  Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
94    return Fold(ConstantExpr::getFRem(LHS, RHS));
95  }
96  Constant *CreateShl(Constant *LHS, Constant *RHS) const {
97    return Fold(ConstantExpr::getShl(LHS, RHS));
98  }
99  Constant *CreateLShr(Constant *LHS, Constant *RHS) const {
100    return Fold(ConstantExpr::getLShr(LHS, RHS));
101  }
102  Constant *CreateAShr(Constant *LHS, Constant *RHS) const {
103    return Fold(ConstantExpr::getAShr(LHS, RHS));
104  }
105  Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
106    return Fold(ConstantExpr::getAnd(LHS, RHS));
107  }
108  Constant *CreateOr(Constant *LHS, Constant *RHS) const {
109    return Fold(ConstantExpr::getOr(LHS, RHS));
110  }
111  Constant *CreateXor(Constant *LHS, Constant *RHS) const {
112    return Fold(ConstantExpr::getXor(LHS, RHS));
113  }
114
115  Constant *CreateBinOp(Instruction::BinaryOps Opc,
116                        Constant *LHS, Constant *RHS) const {
117    return Fold(ConstantExpr::get(Opc, LHS, RHS));
118  }
119
120  //===--------------------------------------------------------------------===//
121  // Unary Operators
122  //===--------------------------------------------------------------------===//
123
124  Constant *CreateNeg(Constant *C) const {
125    return Fold(ConstantExpr::getNeg(C));
126  }
127  Constant *CreateFNeg(Constant *C) const {
128    return Fold(ConstantExpr::getFNeg(C));
129  }
130  Constant *CreateNot(Constant *C) const {
131    return Fold(ConstantExpr::getNot(C));
132  }
133
134  //===--------------------------------------------------------------------===//
135  // Memory Instructions
136  //===--------------------------------------------------------------------===//
137
138  Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList,
139                                unsigned NumIdx) const {
140    return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
141  }
142  Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList,
143                                unsigned NumIdx) const {
144    return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
145  }
146
147  Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
148                                        unsigned NumIdx) const {
149    return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx));
150  }
151  Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
152                                        unsigned NumIdx) const {
153    return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx));
154  }
155
156  //===--------------------------------------------------------------------===//
157  // Cast/Conversion Operators
158  //===--------------------------------------------------------------------===//
159
160  Constant *CreateCast(Instruction::CastOps Op, Constant *C,
161                       const Type *DestTy) const {
162    if (C->getType() == DestTy)
163      return C; // avoid calling Fold
164    return Fold(ConstantExpr::getCast(Op, C, DestTy));
165  }
166  Constant *CreateIntCast(Constant *C, const Type *DestTy,
167                          bool isSigned) const {
168    if (C->getType() == DestTy)
169      return C; // avoid calling Fold
170    return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
171  }
172
173  Constant *CreateBitCast(Constant *C, const Type *DestTy) const {
174    return CreateCast(Instruction::BitCast, C, DestTy);
175  }
176  Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const {
177    return CreateCast(Instruction::IntToPtr, C, DestTy);
178  }
179  Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const {
180    return CreateCast(Instruction::PtrToInt, C, DestTy);
181  }
182  Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
183    if (C->getType() == DestTy)
184      return C; // avoid calling Fold
185    return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
186  }
187
188  //===--------------------------------------------------------------------===//
189  // Compare Instructions
190  //===--------------------------------------------------------------------===//
191
192  Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
193                       Constant *RHS) const {
194    return Fold(ConstantExpr::getCompare(P, LHS, RHS));
195  }
196  Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
197                       Constant *RHS) const {
198    return Fold(ConstantExpr::getCompare(P, LHS, RHS));
199  }
200
201  //===--------------------------------------------------------------------===//
202  // Other Instructions
203  //===--------------------------------------------------------------------===//
204
205  Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
206    return Fold(ConstantExpr::getSelect(C, True, False));
207  }
208
209  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
210    return Fold(ConstantExpr::getExtractElement(Vec, Idx));
211  }
212
213  Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
214                                Constant *Idx) const {
215    return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
216  }
217
218  Constant *CreateShuffleVector(Constant *V1, Constant *V2,
219                                Constant *Mask) const {
220    return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
221  }
222
223  Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
224                               unsigned NumIdx) const {
225    return Fold(ConstantExpr::getExtractValue(Agg, IdxList, NumIdx));
226  }
227
228  Constant *CreateInsertValue(Constant *Agg, Constant *Val,
229                              const unsigned *IdxList, unsigned NumIdx) const {
230    return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx));
231  }
232};
233
234}
235
236#endif
237