Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- ConstantFolder.h - Constant 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 ConstantFolder class, a helper for IRBuilder.
10
// It provides IRBuilder with a set of methods for creating constants
11
// with minimal folding.  For general constant creation and folding,
12
// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
13
//
14
//===----------------------------------------------------------------------===//
15
 
16
#ifndef LLVM_IR_CONSTANTFOLDER_H
17
#define LLVM_IR_CONSTANTFOLDER_H
18
 
19
#include "llvm/ADT/ArrayRef.h"
20
#include "llvm/ADT/STLExtras.h"
21
#include "llvm/IR/Constants.h"
22
#include "llvm/IR/ConstantFold.h"
23
#include "llvm/IR/IRBuilderFolder.h"
24
#include "llvm/IR/Instruction.h"
25
#include "llvm/IR/Operator.h"
26
 
27
namespace llvm {
28
 
29
/// ConstantFolder - Create constants with minimum, target independent, folding.
30
class ConstantFolder final : public IRBuilderFolder {
31
  virtual void anchor();
32
 
33
public:
34
  explicit ConstantFolder() = default;
35
 
36
  //===--------------------------------------------------------------------===//
37
  // Value-based folders.
38
  //
39
  // Return an existing value or a constant if the operation can be simplified.
40
  // Otherwise return nullptr.
41
  //===--------------------------------------------------------------------===//
42
 
43
  Value *FoldBinOp(Instruction::BinaryOps Opc, Value *LHS,
44
                   Value *RHS) const override {
45
    auto *LC = dyn_cast<Constant>(LHS);
46
    auto *RC = dyn_cast<Constant>(RHS);
47
    if (LC && RC) {
48
      if (ConstantExpr::isDesirableBinOp(Opc))
49
        return ConstantExpr::get(Opc, LC, RC);
50
      return ConstantFoldBinaryInstruction(Opc, LC, RC);
51
    }
52
    return nullptr;
53
  }
54
 
55
  Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
56
                        bool IsExact) const override {
57
    auto *LC = dyn_cast<Constant>(LHS);
58
    auto *RC = dyn_cast<Constant>(RHS);
59
    if (LC && RC) {
60
      if (ConstantExpr::isDesirableBinOp(Opc))
61
        return ConstantExpr::get(Opc, LC, RC,
62
                                 IsExact ? PossiblyExactOperator::IsExact : 0);
63
      return ConstantFoldBinaryInstruction(Opc, LC, RC);
64
    }
65
    return nullptr;
66
  }
67
 
68
  Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
69
                         bool HasNUW, bool HasNSW) const override {
70
    auto *LC = dyn_cast<Constant>(LHS);
71
    auto *RC = dyn_cast<Constant>(RHS);
72
    if (LC && RC) {
73
      if (ConstantExpr::isDesirableBinOp(Opc)) {
74
        unsigned Flags = 0;
75
        if (HasNUW)
76
          Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
77
        if (HasNSW)
78
          Flags |= OverflowingBinaryOperator::NoSignedWrap;
79
        return ConstantExpr::get(Opc, LC, RC, Flags);
80
      }
81
      return ConstantFoldBinaryInstruction(Opc, LC, RC);
82
    }
83
    return nullptr;
84
  }
85
 
86
  Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
87
                      FastMathFlags FMF) const override {
88
    return FoldBinOp(Opc, LHS, RHS);
89
  }
90
 
91
  Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V,
92
                      FastMathFlags FMF) const override {
93
    if (Constant *C = dyn_cast<Constant>(V))
94
      return ConstantFoldUnaryInstruction(Opc, C);
95
    return nullptr;
96
  }
97
 
98
  Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
99
    auto *LC = dyn_cast<Constant>(LHS);
100
    auto *RC = dyn_cast<Constant>(RHS);
101
    if (LC && RC)
102
      return ConstantExpr::getCompare(P, LC, RC);
103
    return nullptr;
104
  }
105
 
106
  Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
107
                 bool IsInBounds = false) const override {
108
    if (auto *PC = dyn_cast<Constant>(Ptr)) {
109
      // Every index must be constant.
110
      if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
111
        return nullptr;
112
 
113
      if (IsInBounds)
114
        return ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList);
115
      else
116
        return ConstantExpr::getGetElementPtr(Ty, PC, IdxList);
117
    }
118
    return nullptr;
119
  }
120
 
121
  Value *FoldSelect(Value *C, Value *True, Value *False) const override {
122
    auto *CC = dyn_cast<Constant>(C);
123
    auto *TC = dyn_cast<Constant>(True);
124
    auto *FC = dyn_cast<Constant>(False);
125
    if (CC && TC && FC)
126
      return ConstantExpr::getSelect(CC, TC, FC);
127
    return nullptr;
128
  }
129
 
130
  Value *FoldExtractValue(Value *Agg,
131
                          ArrayRef<unsigned> IdxList) const override {
132
    if (auto *CAgg = dyn_cast<Constant>(Agg))
133
      return ConstantFoldExtractValueInstruction(CAgg, IdxList);
134
    return nullptr;
135
  };
136
 
137
  Value *FoldInsertValue(Value *Agg, Value *Val,
138
                         ArrayRef<unsigned> IdxList) const override {
139
    auto *CAgg = dyn_cast<Constant>(Agg);
140
    auto *CVal = dyn_cast<Constant>(Val);
141
    if (CAgg && CVal)
142
      return ConstantFoldInsertValueInstruction(CAgg, CVal, IdxList);
143
    return nullptr;
144
  }
145
 
146
  Value *FoldExtractElement(Value *Vec, Value *Idx) const override {
147
    auto *CVec = dyn_cast<Constant>(Vec);
148
    auto *CIdx = dyn_cast<Constant>(Idx);
149
    if (CVec && CIdx)
150
      return ConstantExpr::getExtractElement(CVec, CIdx);
151
    return nullptr;
152
  }
153
 
154
  Value *FoldInsertElement(Value *Vec, Value *NewElt,
155
                           Value *Idx) const override {
156
    auto *CVec = dyn_cast<Constant>(Vec);
157
    auto *CNewElt = dyn_cast<Constant>(NewElt);
158
    auto *CIdx = dyn_cast<Constant>(Idx);
159
    if (CVec && CNewElt && CIdx)
160
      return ConstantExpr::getInsertElement(CVec, CNewElt, CIdx);
161
    return nullptr;
162
  }
163
 
164
  Value *FoldShuffleVector(Value *V1, Value *V2,
165
                           ArrayRef<int> Mask) const override {
166
    auto *C1 = dyn_cast<Constant>(V1);
167
    auto *C2 = dyn_cast<Constant>(V2);
168
    if (C1 && C2)
169
      return ConstantExpr::getShuffleVector(C1, C2, Mask);
170
    return nullptr;
171
  }
172
 
173
  //===--------------------------------------------------------------------===//
174
  // Cast/Conversion Operators
175
  //===--------------------------------------------------------------------===//
176
 
177
  Constant *CreateCast(Instruction::CastOps Op, Constant *C,
178
                       Type *DestTy) const override {
179
    return ConstantExpr::getCast(Op, C, DestTy);
180
  }
181
 
182
  Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
183
    return ConstantExpr::getPointerCast(C, DestTy);
184
  }
185
 
186
  Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
187
                                                Type *DestTy) const override {
188
    return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
189
  }
190
 
191
  Constant *CreateIntCast(Constant *C, Type *DestTy,
192
                          bool isSigned) const override {
193
    return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
194
  }
195
 
196
  Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
197
    return ConstantExpr::getFPCast(C, DestTy);
198
  }
199
 
200
  Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
201
    return CreateCast(Instruction::BitCast, C, DestTy);
202
  }
203
 
204
  Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
205
    return CreateCast(Instruction::IntToPtr, C, DestTy);
206
  }
207
 
208
  Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
209
    return CreateCast(Instruction::PtrToInt, C, DestTy);
210
  }
211
 
212
  Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
213
    return ConstantExpr::getZExtOrBitCast(C, DestTy);
214
  }
215
 
216
  Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
217
    return ConstantExpr::getSExtOrBitCast(C, DestTy);
218
  }
219
 
220
  Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
221
    return ConstantExpr::getTruncOrBitCast(C, DestTy);
222
  }
223
 
224
  //===--------------------------------------------------------------------===//
225
  // Compare Instructions
226
  //===--------------------------------------------------------------------===//
227
 
228
  Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
229
                       Constant *RHS) const override {
230
    return ConstantExpr::getCompare(P, LHS, RHS);
231
  }
232
};
233
 
234
} // end namespace llvm
235
 
236
#endif // LLVM_IR_CONSTANTFOLDER_H