LoadStoreOpt.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //== llvm/CodeGen/GlobalISel/LoadStoreOpt.h - LoadStoreOpt -------*- 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 is an optimization pass for GlobalISel generic memory operations.
  15. /// Specifically, it focuses on merging stores and loads to consecutive
  16. /// addresses.
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CODEGEN_GLOBALISEL_LOADSTOREOPT_H
  19. #define LLVM_CODEGEN_GLOBALISEL_LOADSTOREOPT_H
  20. #include "llvm/ADT/BitVector.h"
  21. #include "llvm/ADT/SmallVector.h"
  22. #include "llvm/Analysis/AliasAnalysis.h"
  23. #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
  24. #include "llvm/CodeGen/MachineFunction.h"
  25. #include "llvm/CodeGen/MachineFunctionPass.h"
  26. namespace llvm {
  27. // Forward declarations.
  28. class AnalysisUsage;
  29. class GStore;
  30. class LegalizerInfo;
  31. class MachineBasicBlock;
  32. class MachineInstr;
  33. class TargetLowering;
  34. struct LegalityQuery;
  35. class MachineRegisterInfo;
  36. namespace GISelAddressing {
  37. /// Helper struct to store a base, index and offset that forms an address
  38. struct BaseIndexOffset {
  39. Register BaseReg;
  40. Register IndexReg;
  41. int64_t Offset = 0;
  42. bool IsIndexSignExt = false;
  43. };
  44. /// Returns a BaseIndexOffset which describes the pointer in \p Ptr.
  45. BaseIndexOffset getPointerInfo(Register Ptr, MachineRegisterInfo &MRI);
  46. /// Compute whether or not a memory access at \p MI1 aliases with an access at
  47. /// \p MI2 \returns true if either alias/no-alias is known. Sets \p IsAlias
  48. /// accordingly.
  49. bool aliasIsKnownForLoadStore(const MachineInstr &MI1, const MachineInstr &MI2,
  50. bool &IsAlias, MachineRegisterInfo &MRI);
  51. /// Returns true if the instruction \p MI may alias \p Other.
  52. /// This function uses multiple strategies to detect aliasing, whereas
  53. /// aliasIsKnownForLoadStore just looks at the addresses of load/stores and is
  54. /// tries to reason about base/index/offsets.
  55. bool instMayAlias(const MachineInstr &MI, const MachineInstr &Other,
  56. MachineRegisterInfo &MRI, AliasAnalysis *AA);
  57. } // namespace GISelAddressing
  58. using namespace GISelAddressing;
  59. class LoadStoreOpt : public MachineFunctionPass {
  60. public:
  61. static char ID;
  62. private:
  63. /// An input function to decide if the pass should run or not
  64. /// on the given MachineFunction.
  65. std::function<bool(const MachineFunction &)> DoNotRunPass;
  66. MachineRegisterInfo *MRI;
  67. const TargetLowering *TLI;
  68. MachineFunction *MF;
  69. AliasAnalysis *AA;
  70. const LegalizerInfo *LI;
  71. MachineIRBuilder Builder;
  72. /// Initialize the field members using \p MF.
  73. void init(MachineFunction &MF);
  74. class StoreMergeCandidate {
  75. public:
  76. // The base pointer used as the base for all stores in this candidate.
  77. Register BasePtr;
  78. // Our algorithm is very simple at the moment. We assume that in instruction
  79. // order stores are writing to incremeneting consecutive addresses. So when
  80. // we walk the block in reverse order, the next eligible store must write to
  81. // an offset one store width lower than CurrentLowestOffset.
  82. uint64_t CurrentLowestOffset;
  83. SmallVector<GStore *> Stores;
  84. // A vector of MachineInstr/unsigned pairs to denote potential aliases that
  85. // need to be checked before the candidate is considered safe to merge. The
  86. // unsigned value is an index into the Stores vector. The indexed store is
  87. // the highest-indexed store that has already been checked to not have an
  88. // alias with the instruction. We record this so we don't have to repeat
  89. // alias checks that have been already done, only those with stores added
  90. // after the potential alias is recorded.
  91. SmallVector<std::pair<MachineInstr *, unsigned>> PotentialAliases;
  92. void addPotentialAlias(MachineInstr &MI);
  93. /// Reset this candidate back to an empty one.
  94. void reset() {
  95. Stores.clear();
  96. PotentialAliases.clear();
  97. CurrentLowestOffset = 0;
  98. BasePtr = Register();
  99. }
  100. };
  101. bool isLegalOrBeforeLegalizer(const LegalityQuery &Query,
  102. MachineFunction &MF) const;
  103. /// If the given store is valid to be a member of the candidate, add it and
  104. /// return true. Otherwise, returns false.
  105. bool addStoreToCandidate(GStore &MI, StoreMergeCandidate &C);
  106. /// Returns true if the instruction \p MI would potentially alias with any
  107. /// stores in the candidate \p C.
  108. bool operationAliasesWithCandidate(MachineInstr &MI, StoreMergeCandidate &C);
  109. /// Merges the stores in the given vector into a wide store.
  110. /// \p returns true if at least some of the stores were merged.
  111. /// This may decide not to merge stores if heuristics predict it will not be
  112. /// worth it.
  113. bool mergeStores(SmallVectorImpl<GStore *> &StoresToMerge);
  114. /// Perform a merge of all the stores in \p Stores into a single store.
  115. /// Erases the old stores from the block when finished.
  116. /// \returns true if merging was done. It may fail to perform a merge if
  117. /// there are issues with materializing legal wide values.
  118. bool doSingleStoreMerge(SmallVectorImpl<GStore *> &Stores);
  119. bool processMergeCandidate(StoreMergeCandidate &C);
  120. bool mergeBlockStores(MachineBasicBlock &MBB);
  121. bool mergeFunctionStores(MachineFunction &MF);
  122. /// Initialize some target-specific data structures for the store merging
  123. /// optimization. \p AddrSpace indicates which address space to use when
  124. /// probing the legalizer info for legal stores.
  125. void initializeStoreMergeTargetInfo(unsigned AddrSpace = 0);
  126. /// A map between address space numbers and a bitvector of supported stores
  127. /// sizes. Each bit in the bitvector represents whether a store size of
  128. /// that bit's value is legal. E.g. if bit 64 is set, then 64 bit scalar
  129. /// stores are legal.
  130. DenseMap<unsigned, BitVector> LegalStoreSizes;
  131. bool IsPreLegalizer;
  132. /// Contains instructions to be erased at the end of a block scan.
  133. SmallSet<MachineInstr *, 16> InstsToErase;
  134. public:
  135. LoadStoreOpt();
  136. LoadStoreOpt(std::function<bool(const MachineFunction &)>);
  137. StringRef getPassName() const override { return "LoadStoreOpt"; }
  138. MachineFunctionProperties getRequiredProperties() const override {
  139. return MachineFunctionProperties()
  140. .set(MachineFunctionProperties::Property::IsSSA);
  141. }
  142. void getAnalysisUsage(AnalysisUsage &AU) const override;
  143. bool runOnMachineFunction(MachineFunction &MF) override;
  144. };
  145. } // End namespace llvm.
  146. #endif
  147. #ifdef __GNUC__
  148. #pragma GCC diagnostic pop
  149. #endif