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