Reassociate.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Reassociate.h - Reassociate binary expressions -----------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This pass reassociates commutative expressions in an order that is designed
  15. // to promote better constant propagation, GCSE, LICM, PRE, etc.
  16. //
  17. // For example: 4 + (x + 5) -> x + (4 + 5)
  18. //
  19. // In the implementation of this algorithm, constants are assigned rank = 0,
  20. // function arguments are rank = 1, and other values are assigned ranks
  21. // corresponding to the reverse post order traversal of current function
  22. // (starting at 2), which effectively gives values in deep loops higher rank
  23. // than values not in loops.
  24. //
  25. //===----------------------------------------------------------------------===//
  26. #ifndef LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H
  27. #define LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H
  28. #include "llvm/ADT/DenseMap.h"
  29. #include "llvm/ADT/PostOrderIterator.h"
  30. #include "llvm/ADT/SetVector.h"
  31. #include "llvm/IR/PassManager.h"
  32. #include "llvm/IR/ValueHandle.h"
  33. #include <deque>
  34. namespace llvm {
  35. class APInt;
  36. class BasicBlock;
  37. class BinaryOperator;
  38. class Function;
  39. class Instruction;
  40. class IRBuilderBase;
  41. class Value;
  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 {
  45. struct ValueEntry {
  46. unsigned Rank;
  47. Value *Op;
  48. ValueEntry(unsigned R, Value *O) : Rank(R), Op(O) {}
  49. };
  50. inline bool operator<(const ValueEntry &LHS, const ValueEntry &RHS) {
  51. return LHS.Rank > RHS.Rank; // Sort so that highest rank goes to start.
  52. }
  53. /// Utility class representing a base and exponent pair which form one
  54. /// factor of some product.
  55. struct Factor {
  56. Value *Base;
  57. unsigned Power;
  58. Factor(Value *Base, unsigned Power) : Base(Base), Power(Power) {}
  59. };
  60. class XorOpnd;
  61. } // end namespace reassociate
  62. /// Reassociate commutative expressions.
  63. class ReassociatePass : public PassInfoMixin<ReassociatePass> {
  64. public:
  65. using OrderedSet =
  66. SetVector<AssertingVH<Instruction>, std::deque<AssertingVH<Instruction>>>;
  67. protected:
  68. DenseMap<BasicBlock *, unsigned> RankMap;
  69. DenseMap<AssertingVH<Value>, unsigned> ValueRankMap;
  70. OrderedSet RedoInsts;
  71. // Arbitrary, but prevents quadratic behavior.
  72. static const unsigned GlobalReassociateLimit = 10;
  73. static const unsigned NumBinaryOps =
  74. Instruction::BinaryOpsEnd - Instruction::BinaryOpsBegin;
  75. struct PairMapValue {
  76. WeakVH Value1;
  77. WeakVH Value2;
  78. unsigned Score;
  79. bool isValid() const { return Value1 && Value2; }
  80. };
  81. DenseMap<std::pair<Value *, Value *>, PairMapValue> PairMap[NumBinaryOps];
  82. bool MadeChange;
  83. public:
  84. PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
  85. private:
  86. void BuildRankMap(Function &F, ReversePostOrderTraversal<Function *> &RPOT);
  87. unsigned getRank(Value *V);
  88. void canonicalizeOperands(Instruction *I);
  89. void ReassociateExpression(BinaryOperator *I);
  90. void RewriteExprTree(BinaryOperator *I,
  91. SmallVectorImpl<reassociate::ValueEntry> &Ops);
  92. Value *OptimizeExpression(BinaryOperator *I,
  93. SmallVectorImpl<reassociate::ValueEntry> &Ops);
  94. Value *OptimizeAdd(Instruction *I,
  95. SmallVectorImpl<reassociate::ValueEntry> &Ops);
  96. Value *OptimizeXor(Instruction *I,
  97. SmallVectorImpl<reassociate::ValueEntry> &Ops);
  98. bool CombineXorOpnd(Instruction *I, reassociate::XorOpnd *Opnd1,
  99. APInt &ConstOpnd, Value *&Res);
  100. bool CombineXorOpnd(Instruction *I, reassociate::XorOpnd *Opnd1,
  101. reassociate::XorOpnd *Opnd2, APInt &ConstOpnd,
  102. Value *&Res);
  103. Value *buildMinimalMultiplyDAG(IRBuilderBase &Builder,
  104. SmallVectorImpl<reassociate::Factor> &Factors);
  105. Value *OptimizeMul(BinaryOperator *I,
  106. SmallVectorImpl<reassociate::ValueEntry> &Ops);
  107. Value *RemoveFactorFromExpression(Value *V, Value *Factor);
  108. void EraseInst(Instruction *I);
  109. void RecursivelyEraseDeadInsts(Instruction *I, OrderedSet &Insts);
  110. void OptimizeInst(Instruction *I);
  111. Instruction *canonicalizeNegFPConstantsForOp(Instruction *I, Instruction *Op,
  112. Value *OtherOp);
  113. Instruction *canonicalizeNegFPConstants(Instruction *I);
  114. void BuildPairMap(ReversePostOrderTraversal<Function *> &RPOT);
  115. };
  116. } // end namespace llvm
  117. #endif // LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H
  118. #ifdef __GNUC__
  119. #pragma GCC diagnostic pop
  120. #endif