1 //===- Reassociate.h - Reassociate binary expressions -----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This pass reassociates commutative expressions in an order that is designed
10 // to promote better constant propagation, GCSE, LICM, PRE, etc.
12 // For example: 4 + (x + 5) -> x + (4 + 5)
14 // In the implementation of this algorithm, constants are assigned rank = 0,
15 // function arguments are rank = 1, and other values are assigned ranks
16 // corresponding to the reverse post order traversal of current function
17 // (starting at 2), which effectively gives values in deep loops higher rank
18 // than values not in loops.
20 //===----------------------------------------------------------------------===//
22 #ifndef LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H
23 #define LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H
25 #include "llvm/ADT/DenseMap.h"
26 #include "llvm/ADT/PostOrderIterator.h"
27 #include "llvm/ADT/SetVector.h"
28 #include "llvm/IR/IRBuilder.h"
29 #include "llvm/IR/PassManager.h"
30 #include "llvm/IR/ValueHandle.h"
42 /// A private "module" namespace for types and utilities used by Reassociate.
43 /// These are implementation details and should not be used by clients.
44 namespace reassociate
{
50 ValueEntry(unsigned R
, Value
*O
) : Rank(R
), Op(O
) {}
53 inline bool operator<(const ValueEntry
&LHS
, const ValueEntry
&RHS
) {
54 return LHS
.Rank
> RHS
.Rank
; // Sort so that highest rank goes to start.
57 /// Utility class representing a base and exponent pair which form one
58 /// factor of some product.
63 Factor(Value
*Base
, unsigned Power
) : Base(Base
), Power(Power
) {}
68 } // end namespace reassociate
70 /// Reassociate commutative expressions.
71 class ReassociatePass
: public PassInfoMixin
<ReassociatePass
> {
74 SetVector
<AssertingVH
<Instruction
>, std::deque
<AssertingVH
<Instruction
>>>;
77 DenseMap
<BasicBlock
*, unsigned> RankMap
;
78 DenseMap
<AssertingVH
<Value
>, unsigned> ValueRankMap
;
81 // Arbitrary, but prevents quadratic behavior.
82 static const unsigned GlobalReassociateLimit
= 10;
83 static const unsigned NumBinaryOps
=
84 Instruction::BinaryOpsEnd
- Instruction::BinaryOpsBegin
;
90 bool isValid() const { return Value1
&& Value2
; }
92 DenseMap
<std::pair
<Value
*, Value
*>, PairMapValue
> PairMap
[NumBinaryOps
];
97 PreservedAnalyses
run(Function
&F
, FunctionAnalysisManager
&);
100 void BuildRankMap(Function
&F
, ReversePostOrderTraversal
<Function
*> &RPOT
);
101 unsigned getRank(Value
*V
);
102 void canonicalizeOperands(Instruction
*I
);
103 void ReassociateExpression(BinaryOperator
*I
);
104 void RewriteExprTree(BinaryOperator
*I
,
105 SmallVectorImpl
<reassociate::ValueEntry
> &Ops
);
106 Value
*OptimizeExpression(BinaryOperator
*I
,
107 SmallVectorImpl
<reassociate::ValueEntry
> &Ops
);
108 Value
*OptimizeAdd(Instruction
*I
,
109 SmallVectorImpl
<reassociate::ValueEntry
> &Ops
);
110 Value
*OptimizeXor(Instruction
*I
,
111 SmallVectorImpl
<reassociate::ValueEntry
> &Ops
);
112 bool CombineXorOpnd(Instruction
*I
, reassociate::XorOpnd
*Opnd1
,
113 APInt
&ConstOpnd
, Value
*&Res
);
114 bool CombineXorOpnd(Instruction
*I
, reassociate::XorOpnd
*Opnd1
,
115 reassociate::XorOpnd
*Opnd2
, APInt
&ConstOpnd
,
117 Value
*buildMinimalMultiplyDAG(IRBuilder
<> &Builder
,
118 SmallVectorImpl
<reassociate::Factor
> &Factors
);
119 Value
*OptimizeMul(BinaryOperator
*I
,
120 SmallVectorImpl
<reassociate::ValueEntry
> &Ops
);
121 Value
*RemoveFactorFromExpression(Value
*V
, Value
*Factor
);
122 void EraseInst(Instruction
*I
);
123 void RecursivelyEraseDeadInsts(Instruction
*I
, OrderedSet
&Insts
);
124 void OptimizeInst(Instruction
*I
);
125 Instruction
*canonicalizeNegFPConstantsForOp(Instruction
*I
, Instruction
*Op
,
127 Instruction
*canonicalizeNegFPConstants(Instruction
*I
);
128 void BuildPairMap(ReversePostOrderTraversal
<Function
*> &RPOT
);
131 } // end namespace llvm
133 #endif // LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H