TargetFolder.h revision e56a94ef91009ddb8d8b68783ff1650bcad3b326
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::getAdd(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 *CreateFSub(Constant *LHS, Constant *RHS) const {
64    return Fold(ConstantExpr::getFSub(LHS, RHS));
65  }
66  Constant *CreateMul(Constant *LHS, Constant *RHS) const {
67    return Fold(ConstantExpr::getMul(LHS, RHS));
68  }
69  Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
70    return Fold(ConstantExpr::getFMul(LHS, RHS));
71  }
72  Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
73    return Fold(ConstantExpr::getUDiv(LHS, RHS));
74  }
75  Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
76    return Fold(ConstantExpr::getSDiv(LHS, RHS));
77  }
78  Constant *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
79    return Fold(ConstantExpr::getSDiv(LHS, RHS));
80  }
81  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
82    return Fold(ConstantExpr::getFDiv(LHS, RHS));
83  }
84  Constant *CreateURem(Constant *LHS, Constant *RHS) const {
85    return Fold(ConstantExpr::getURem(LHS, RHS));
86  }
87  Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
88    return Fold(ConstantExpr::getSRem(LHS, RHS));
89  }
90  Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
91    return Fold(ConstantExpr::getFRem(LHS, RHS));
92  }
93  Constant *CreateShl(Constant *LHS, Constant *RHS) const {
94    return Fold(ConstantExpr::getShl(LHS, RHS));
95  }
96  Constant *CreateLShr(Constant *LHS, Constant *RHS) const {
97    return Fold(ConstantExpr::getLShr(LHS, RHS));
98  }
99  Constant *CreateAShr(Constant *LHS, Constant *RHS) const {
100    return Fold(ConstantExpr::getAShr(LHS, RHS));
101  }
102  Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
103    return Fold(ConstantExpr::getAnd(LHS, RHS));
104  }
105  Constant *CreateOr(Constant *LHS, Constant *RHS) const {
106    return Fold(ConstantExpr::getOr(LHS, RHS));
107  }
108  Constant *CreateXor(Constant *LHS, Constant *RHS) const {
109    return Fold(ConstantExpr::getXor(LHS, RHS));
110  }
111
112  Constant *CreateBinOp(Instruction::BinaryOps Opc,
113                        Constant *LHS, Constant *RHS) const {
114    return Fold(ConstantExpr::get(Opc, LHS, RHS));
115  }
116
117  //===--------------------------------------------------------------------===//
118  // Unary Operators
119  //===--------------------------------------------------------------------===//
120
121  Constant *CreateNeg(Constant *C) const {
122    return Fold(ConstantExpr::getNeg(C));
123  }
124  Constant *CreateFNeg(Constant *C) const {
125    return Fold(ConstantExpr::getFNeg(C));
126  }
127  Constant *CreateNot(Constant *C) const {
128    return Fold(ConstantExpr::getNot(C));
129  }
130
131  //===--------------------------------------------------------------------===//
132  // Memory Instructions
133  //===--------------------------------------------------------------------===//
134
135  Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList,
136                                unsigned NumIdx) const {
137    return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
138  }
139  Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList,
140                                unsigned NumIdx) const {
141    return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
142  }
143
144  Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
145                                        unsigned NumIdx) const {
146    return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
147  }
148  Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
149                                        unsigned NumIdx) const {
150    return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
151  }
152
153  //===--------------------------------------------------------------------===//
154  // Cast/Conversion Operators
155  //===--------------------------------------------------------------------===//
156
157  Constant *CreateCast(Instruction::CastOps Op, Constant *C,
158                       const Type *DestTy) const {
159    if (C->getType() == DestTy)
160      return C; // avoid calling Fold
161    return Fold(ConstantExpr::getCast(Op, C, DestTy));
162  }
163  Constant *CreateIntCast(Constant *C, const Type *DestTy,
164                          bool isSigned) const {
165    if (C->getType() == DestTy)
166      return C; // avoid calling Fold
167    return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
168  }
169
170  Constant *CreateBitCast(Constant *C, const Type *DestTy) const {
171    return CreateCast(Instruction::BitCast, C, DestTy);
172  }
173  Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const {
174    return CreateCast(Instruction::IntToPtr, C, DestTy);
175  }
176  Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const {
177    return CreateCast(Instruction::PtrToInt, C, DestTy);
178  }
179  Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
180    if (C->getType() == DestTy)
181      return C; // avoid calling Fold
182    return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
183  }
184
185  //===--------------------------------------------------------------------===//
186  // Compare Instructions
187  //===--------------------------------------------------------------------===//
188
189  Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
190                       Constant *RHS) const {
191    return Fold(ConstantExpr::getCompare(P, LHS, RHS));
192  }
193  Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
194                       Constant *RHS) const {
195    return Fold(ConstantExpr::getCompare(P, LHS, RHS));
196  }
197
198  //===--------------------------------------------------------------------===//
199  // Other Instructions
200  //===--------------------------------------------------------------------===//
201
202  Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
203    return Fold(ConstantExpr::getSelect(C, True, False));
204  }
205
206  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
207    return Fold(ConstantExpr::getExtractElement(Vec, Idx));
208  }
209
210  Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
211                                Constant *Idx) const {
212    return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
213  }
214
215  Constant *CreateShuffleVector(Constant *V1, Constant *V2,
216                                Constant *Mask) const {
217    return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
218  }
219
220  Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
221                               unsigned NumIdx) const {
222    return Fold(ConstantExpr::getExtractValue(Agg, IdxList, NumIdx));
223  }
224
225  Constant *CreateInsertValue(Constant *Agg, Constant *Val,
226                              const unsigned *IdxList, unsigned NumIdx) const {
227    return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx));
228  }
229};
230
231}
232
233#endif
234