1//===- InstSimplifyFolder.h - InstSimplify 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 InstSimplifyFolder class, a helper for IRBuilder.
10// It provides IRBuilder with a set of methods for folding operations to
11// existing values using InstructionSimplify. At the moment, only a subset of
12// the implementation uses InstructionSimplify. The rest of the implementation
13// only folds constants.
14//
15// The folder also applies target-specific constant folding.
16//
17//===----------------------------------------------------------------------===//
18
19#ifndef LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H
20#define LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H
21
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/Analysis/InstructionSimplify.h"
24#include "llvm/Analysis/TargetFolder.h"
25#include "llvm/IR/IRBuilderFolder.h"
26#include "llvm/IR/Instruction.h"
27
28namespace llvm {
29class Constant;
30
31/// InstSimplifyFolder - Use InstructionSimplify to fold operations to existing
32/// values. Also applies target-specific constant folding when not using
33/// InstructionSimplify.
34class InstSimplifyFolder final : public IRBuilderFolder {
35 TargetFolder ConstFolder;
36 SimplifyQuery SQ;
37
38 virtual void anchor();
39
40public:
41 InstSimplifyFolder(const DataLayout &DL) : ConstFolder(DL), SQ(DL) {}
42
43 //===--------------------------------------------------------------------===//
44 // Value-based folders.
45 //
46 // Return an existing value or a constant if the operation can be simplified.
47 // Otherwise return nullptr.
48 //===--------------------------------------------------------------------===//
49
50 Value *FoldBinOp(Instruction::BinaryOps Opc, Value *LHS,
51 Value *RHS) const override {
52 return simplifyBinOp(Opcode: Opc, LHS, RHS, Q: SQ);
53 }
54
55 Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
56 bool IsExact) const override {
57 return simplifyBinOp(Opcode: Opc, LHS, RHS, Q: SQ);
58 }
59
60 Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
61 bool HasNUW, bool HasNSW) const override {
62 return simplifyBinOp(Opcode: Opc, LHS, RHS, Q: SQ);
63 }
64
65 Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
66 FastMathFlags FMF) const override {
67 return simplifyBinOp(Opcode: Opc, LHS, RHS, FMF, Q: SQ);
68 }
69
70 Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V,
71 FastMathFlags FMF) const override {
72 return simplifyUnOp(Opcode: Opc, Op: V, FMF, Q: SQ);
73 }
74
75 Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
76 return simplifyICmpInst(Predicate: P, LHS, RHS, Q: SQ);
77 }
78
79 Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
80 bool IsInBounds = false) const override {
81 return simplifyGEPInst(SrcTy: Ty, Ptr, Indices: IdxList, InBounds: IsInBounds, Q: SQ);
82 }
83
84 Value *FoldSelect(Value *C, Value *True, Value *False) const override {
85 return simplifySelectInst(Cond: C, TrueVal: True, FalseVal: False, Q: SQ);
86 }
87
88 Value *FoldExtractValue(Value *Agg,
89 ArrayRef<unsigned> IdxList) const override {
90 return simplifyExtractValueInst(Agg, Idxs: IdxList, Q: SQ);
91 };
92
93 Value *FoldInsertValue(Value *Agg, Value *Val,
94 ArrayRef<unsigned> IdxList) const override {
95 return simplifyInsertValueInst(Agg, Val, Idxs: IdxList, Q: SQ);
96 }
97
98 Value *FoldExtractElement(Value *Vec, Value *Idx) const override {
99 return simplifyExtractElementInst(Vec, Idx, Q: SQ);
100 }
101
102 Value *FoldInsertElement(Value *Vec, Value *NewElt,
103 Value *Idx) const override {
104 return simplifyInsertElementInst(Vec, Elt: NewElt, Idx, Q: SQ);
105 }
106
107 Value *FoldShuffleVector(Value *V1, Value *V2,
108 ArrayRef<int> Mask) const override {
109 Type *RetTy = VectorType::get(
110 ElementType: cast<VectorType>(Val: V1->getType())->getElementType(), NumElements: Mask.size(),
111 Scalable: isa<ScalableVectorType>(Val: V1->getType()));
112 return simplifyShuffleVectorInst(Op0: V1, Op1: V2, Mask, RetTy, Q: SQ);
113 }
114
115 Value *FoldCast(Instruction::CastOps Op, Value *V,
116 Type *DestTy) const override {
117 return simplifyCastInst(CastOpc: Op, Op: V, Ty: DestTy, Q: SQ);
118 }
119
120 //===--------------------------------------------------------------------===//
121 // Cast/Conversion Operators
122 //===--------------------------------------------------------------------===//
123
124 Value *CreatePointerCast(Constant *C, Type *DestTy) const override {
125 if (C->getType() == DestTy)
126 return C; // avoid calling Fold
127 return ConstFolder.CreatePointerCast(C, DestTy);
128 }
129
130 Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
131 Type *DestTy) const override {
132 if (C->getType() == DestTy)
133 return C; // avoid calling Fold
134 return ConstFolder.CreatePointerBitCastOrAddrSpaceCast(C, DestTy);
135 }
136
137 //===--------------------------------------------------------------------===//
138 // Compare Instructions
139 //===--------------------------------------------------------------------===//
140
141 Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
142 Constant *RHS) const override {
143 return ConstFolder.CreateFCmp(P, LHS, RHS);
144 }
145};
146
147} // end namespace llvm
148
149#endif // LLVM_ANALYSIS_INSTSIMPLIFYFOLDER_H
150

source code of llvm/include/llvm/Analysis/InstSimplifyFolder.h