TargetFolder.h revision 45524c58fd5f77b6a3f6e77d43fba85b36ec0b08
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(Context.getConstantExprAdd(LHS, RHS));
53  }
54  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
55    return Fold(Context.getConstantExprFAdd(LHS, RHS));
56  }
57  Constant *CreateSub(Constant *LHS, Constant *RHS) const {
58    return Fold(Context.getConstantExprSub(LHS, RHS));
59  }
60  Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
61    return Fold(Context.getConstantExprFSub(LHS, RHS));
62  }
63  Constant *CreateMul(Constant *LHS, Constant *RHS) const {
64    return Fold(Context.getConstantExprMul(LHS, RHS));
65  }
66  Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
67    return Fold(Context.getConstantExprFMul(LHS, RHS));
68  }
69  Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
70    return Fold(Context.getConstantExprUDiv(LHS, RHS));
71  }
72  Constant *CreateSDiv(Constant *LHS, Constant *RHS) const {
73    return Fold(Context.getConstantExprSDiv(LHS, RHS));
74  }
75  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
76    return Fold(Context.getConstantExprFDiv(LHS, RHS));
77  }
78  Constant *CreateURem(Constant *LHS, Constant *RHS) const {
79    return Fold(Context.getConstantExprURem(LHS, RHS));
80  }
81  Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
82    return Fold(Context.getConstantExprSRem(LHS, RHS));
83  }
84  Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
85    return Fold(Context.getConstantExprFRem(LHS, RHS));
86  }
87  Constant *CreateShl(Constant *LHS, Constant *RHS) const {
88    return Fold(Context.getConstantExprShl(LHS, RHS));
89  }
90  Constant *CreateLShr(Constant *LHS, Constant *RHS) const {
91    return Fold(Context.getConstantExprLShr(LHS, RHS));
92  }
93  Constant *CreateAShr(Constant *LHS, Constant *RHS) const {
94    return Fold(Context.getConstantExprAShr(LHS, RHS));
95  }
96  Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
97    return Fold(Context.getConstantExprAnd(LHS, RHS));
98  }
99  Constant *CreateOr(Constant *LHS, Constant *RHS) const {
100    return Fold(Context.getConstantExprOr(LHS, RHS));
101  }
102  Constant *CreateXor(Constant *LHS, Constant *RHS) const {
103    return Fold(Context.getConstantExprXor(LHS, RHS));
104  }
105
106  Constant *CreateBinOp(Instruction::BinaryOps Opc,
107                        Constant *LHS, Constant *RHS) const {
108    return Fold(Context.getConstantExpr(Opc, LHS, RHS));
109  }
110
111  //===--------------------------------------------------------------------===//
112  // Unary Operators
113  //===--------------------------------------------------------------------===//
114
115  Constant *CreateNeg(Constant *C) const {
116    return Fold(Context.getConstantExprNeg(C));
117  }
118  Constant *CreateFNeg(Constant *C) const {
119    return Fold(Context.getConstantExprFNeg(C));
120  }
121  Constant *CreateNot(Constant *C) const {
122    return Fold(Context.getConstantExprNot(C));
123  }
124
125  //===--------------------------------------------------------------------===//
126  // Memory Instructions
127  //===--------------------------------------------------------------------===//
128
129  Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList,
130                                unsigned NumIdx) const {
131    return Fold(Context.getConstantExprGetElementPtr(C, IdxList, NumIdx));
132  }
133  Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList,
134                                unsigned NumIdx) const {
135    return Fold(Context.getConstantExprGetElementPtr(C, IdxList, NumIdx));
136  }
137
138  //===--------------------------------------------------------------------===//
139  // Cast/Conversion Operators
140  //===--------------------------------------------------------------------===//
141
142  Constant *CreateCast(Instruction::CastOps Op, Constant *C,
143                       const Type *DestTy) const {
144    if (C->getType() == DestTy)
145      return C; // avoid calling Fold
146    return Fold(Context.getConstantExprCast(Op, C, DestTy));
147  }
148  Constant *CreateIntCast(Constant *C, const Type *DestTy,
149                          bool isSigned) const {
150    if (C->getType() == DestTy)
151      return C; // avoid calling Fold
152    return Fold(Context.getConstantExprIntegerCast(C, DestTy, isSigned));
153  }
154
155  Constant *CreateBitCast(Constant *C, const Type *DestTy) const {
156    return CreateCast(Instruction::BitCast, C, DestTy);
157  }
158  Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const {
159    return CreateCast(Instruction::IntToPtr, C, DestTy);
160  }
161  Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const {
162    return CreateCast(Instruction::PtrToInt, C, DestTy);
163  }
164  Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
165    if (C->getType() == DestTy)
166      return C; // avoid calling Fold
167    return Fold(Context.getConstantExprTruncOrBitCast(C, DestTy));
168  }
169
170  //===--------------------------------------------------------------------===//
171  // Compare Instructions
172  //===--------------------------------------------------------------------===//
173
174  Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
175                       Constant *RHS) const {
176    return Fold(Context.getConstantExprCompare(P, LHS, RHS));
177  }
178  Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
179                       Constant *RHS) const {
180    return Fold(Context.getConstantExprCompare(P, LHS, RHS));
181  }
182
183  //===--------------------------------------------------------------------===//
184  // Other Instructions
185  //===--------------------------------------------------------------------===//
186
187  Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
188    return Fold(Context.getConstantExprSelect(C, True, False));
189  }
190
191  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
192    return Fold(Context.getConstantExprExtractElement(Vec, Idx));
193  }
194
195  Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
196                                Constant *Idx) const {
197    return Fold(Context.getConstantExprInsertElement(Vec, NewElt, Idx));
198  }
199
200  Constant *CreateShuffleVector(Constant *V1, Constant *V2,
201                                Constant *Mask) const {
202    return Fold(Context.getConstantExprShuffleVector(V1, V2, Mask));
203  }
204
205  Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
206                               unsigned NumIdx) const {
207    return Fold(Context.getConstantExprExtractValue(Agg, IdxList, NumIdx));
208  }
209
210  Constant *CreateInsertValue(Constant *Agg, Constant *Val,
211                              const unsigned *IdxList, unsigned NumIdx) const {
212    return Fold(Context.getConstantExprInsertValue(Agg, Val, IdxList, NumIdx));
213  }
214};
215
216}
217
218#endif
219