//===-- LanaiMemAluCombiner.cpp - Pass to combine memory & ALU operations -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // Simple pass to combine memory and ALU operations // // The Lanai ISA supports instructions where a load/store modifies the base // register used in the load/store operation. This pass finds suitable // load/store and ALU instructions and combines them into one instruction. // // For example, // ld [ %r6 -- ], %r12 // is a supported instruction that is not currently generated by the instruction // selection pass of this backend. This pass generates these instructions by // merging // add %r6, -4, %r6 // followed by // ld [ %r6 ], %r12 // in the same machine basic block into one machine instruction. //===----------------------------------------------------------------------===// #include "LanaiAluCode.h" #include "LanaiTargetMachine.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/Support/CommandLine.h" usingnamespacellvm; #define GET_INSTRMAP_INFO #include "LanaiGenInstrInfo.inc" #define DEBUG_TYPE … STATISTIC(NumLdStAluCombined, "Number of memory and ALU instructions combined"); static llvm::cl::opt<bool> DisableMemAluCombiner( "disable-lanai-mem-alu-combiner", llvm::cl::init(false), llvm::cl::desc("Do not combine ALU and memory operators"), llvm::cl::Hidden); namespace llvm { void initializeLanaiMemAluCombinerPass(PassRegistry &); } // namespace llvm namespace { MbbIterator; MfIterator; class LanaiMemAluCombiner : public MachineFunctionPass { … }; } // namespace char LanaiMemAluCombiner::ID = …; INITIALIZE_PASS(…) namespace { bool isSpls(uint16_t Opcode) { … } // Determine the opcode for the merged instruction created by considering the // old memory operation's opcode and whether the merged opcode will have an // immediate offset. unsigned mergedOpcode(unsigned OldOpcode, bool ImmediateOffset) { … } // Check if the machine instruction has non-volatile memory operands of the type // supported for combining with ALU instructions. bool isNonVolatileMemoryOp(const MachineInstr &MI) { … } // Test to see if two machine operands are of the same type. This test is less // strict than the MachineOperand::isIdenticalTo function. bool isSameOperand(const MachineOperand &Op1, const MachineOperand &Op2) { … } bool isZeroOperand(const MachineOperand &Op) { … } // Determines whether a register is used by an instruction. bool InstrUsesReg(const MbbIterator &Instr, const MachineOperand *Reg) { … } // Converts between machine opcode and AluCode. // Flag using/modifying ALU operations should not be considered for merging and // are omitted from this list. LPAC::AluCode mergedAluCode(unsigned AluOpcode) { … } // Insert a new combined memory and ALU operation instruction. // // This function builds a new machine instruction using the MachineInstrBuilder // class and inserts it before the memory instruction. void LanaiMemAluCombiner::insertMergedInstruction(MachineBasicBlock *BB, const MbbIterator &MemInstr, const MbbIterator &AluInstr, bool Before) { … } // Function determines if ALU operation (in alu_iter) can be combined with // a load/store with base and offset. bool isSuitableAluInstr(bool IsSpls, const MbbIterator &AluIter, const MachineOperand &Base, const MachineOperand &Offset) { … } MbbIterator LanaiMemAluCombiner::findClosestSuitableAluInstr( MachineBasicBlock *BB, const MbbIterator &MemInstr, const bool Decrement) { … } bool LanaiMemAluCombiner::combineMemAluInBasicBlock(MachineBasicBlock *BB) { … } // Driver function that iterates over the machine basic building blocks of a // machine function bool LanaiMemAluCombiner::runOnMachineFunction(MachineFunction &MF) { … } } // namespace FunctionPass *llvm::createLanaiMemAluCombinerPass() { … }