LoadStoreOpt.h 6.8 KB

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