25#define DEBUG_TYPE "riscv-fold-mem-offset"
26#define RISCV_FOLD_MEM_OFFSET_NAME "RISC-V Fold Memory Offset"
38 bool foldOffset(
Register OrigReg, int64_t InitialOffset,
52 std::optional<int64_t> Offset;
55 bool hasValue()
const {
return Offset.has_value(); }
56 int64_t getValue()
const {
return *Offset; }
58 FoldableOffset &operator=(int64_t
RHS) {
75char RISCVFoldMemOffset::ID = 0;
80 return new RISCVFoldMemOffset();
90bool RISCVFoldMemOffset::foldOffset(
97 RegToOffsetMap[OrigReg] = InitialOffset;
99 std::queue<Register> Worklist;
100 Worklist.push(OrigReg);
102 while (!Worklist.empty()) {
106 if (!
Reg.isVirtual())
109 for (
auto &
User :
MRI.use_nodbg_instructions(Reg)) {
112 switch (
User.getOpcode()) {
117 I != RegToOffsetMap.
end())
120 I != RegToOffsetMap.
end())
125 I != RegToOffsetMap.
end())
128 I != RegToOffsetMap.
end())
133 I != RegToOffsetMap.
end())
136 I != RegToOffsetMap.
end())
141 I != RegToOffsetMap.
end())
144 I != RegToOffsetMap.
end())
148 case RISCV::SH1ADD_UW:
149 case RISCV::SH2ADD_UW:
150 case RISCV::SH3ADD_UW:
155 I != RegToOffsetMap.
end())
161 I != RegToOffsetMap.
end())
200 if (
I == RegToOffsetMap.
end())
204 assert(isInt<12>(LocalOffset));
206 if (!isInt<12>(CombinedOffset))
209 FoldableInstrs[&
User] = CombinedOffset;
219 int64_t OffsetVal =
Offset.getValue();
224 }
else if (
P.first->second != OffsetVal) {
225 P.first->second = OffsetVal;
244 bool MadeChange =
false;
249 if (
MI.getOpcode() != RISCV::ADDI)
253 if (!
MI.getOperand(1).isReg() || !
MI.getOperand(2).isImm())
257 if (
MI.getOperand(1).getReg() == RISCV::X0)
260 int64_t
Offset =
MI.getOperand(2).getImm();
265 if (!foldOffset(
MI.getOperand(0).getReg(),
Offset,
MRI, FoldableInstrs))
268 if (FoldableInstrs.
empty())
273 for (
auto [MemMI, NewOffset] : FoldableInstrs)
274 MemMI->getOperand(2).setImm(NewOffset);
276 MRI.replaceRegWith(
MI.getOperand(0).getReg(),
MI.getOperand(1).getReg());
277 MRI.clearKillFlags(
MI.getOperand(1).getReg());
278 MI.eraseFromParent();
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define RISCV_FOLD_MEM_OFFSET_NAME
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
StringRef - Represent a constant reference to a string, i.e.
Value * getOperand(unsigned i) const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createRISCVFoldMemOffsetPass()
APInt operator*(APInt a, uint64_t RHS)
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...