1 //===-- SIFoldOperands.cpp - Fold operands --- ----------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
13 #include "AMDGPUSubtarget.h"
14 #include "SIInstrInfo.h"
15 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
16 #include "llvm/CodeGen/MachineDominators.h"
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Target/TargetMachine.h"
25 #define DEBUG_TYPE "si-fold-operands"
30 class SIFoldOperands : public MachineFunctionPass {
35 SIFoldOperands() : MachineFunctionPass(ID) {
36 initializeSIFoldOperandsPass(*PassRegistry::getPassRegistry());
39 bool runOnMachineFunction(MachineFunction &MF) override;
41 const char *getPassName() const override {
42 return "SI Fold Operands";
45 void getAnalysisUsage(AnalysisUsage &AU) const override {
46 AU.addRequired<MachineDominatorTree>();
48 MachineFunctionPass::getAnalysisUsage(AU);
52 } // End anonymous namespace.
54 INITIALIZE_PASS_BEGIN(SIFoldOperands, DEBUG_TYPE,
55 "SI Fold Operands", false, false)
56 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
57 INITIALIZE_PASS_END(SIFoldOperands, DEBUG_TYPE,
58 "SI Fold Operands", false, false)
60 char SIFoldOperands::ID = 0;
62 char &llvm::SIFoldOperandsID = SIFoldOperands::ID;
64 FunctionPass *llvm::createSIFoldOperandsPass() {
65 return new SIFoldOperands();
68 static bool isSafeToFold(unsigned Opcode) {
70 case AMDGPU::V_MOV_B32_e32:
71 case AMDGPU::V_MOV_B32_e64:
72 case AMDGPU::S_MOV_B32:
73 case AMDGPU::S_MOV_B64:
81 static bool updateOperand(MachineInstr *MI, unsigned OpNo,
82 const MachineOperand &New,
83 const TargetRegisterInfo &TRI) {
84 MachineOperand &Old = MI->getOperand(OpNo);
88 Old.ChangeToImmediate(New.getImm());
93 Old.ChangeToFPImmediate(New.getFPImm());
98 if (TargetRegisterInfo::isVirtualRegister(Old.getReg()) &&
99 TargetRegisterInfo::isVirtualRegister(New.getReg())) {
100 Old.substVirtReg(New.getReg(), New.getSubReg(), TRI);
105 // FIXME: Handle physical registers.
110 bool SIFoldOperands::runOnMachineFunction(MachineFunction &MF) {
111 MachineRegisterInfo &MRI = MF.getRegInfo();
112 const SIInstrInfo *TII =
113 static_cast<const SIInstrInfo *>(MF.getSubtarget().getInstrInfo());
114 const SIRegisterInfo &TRI = TII->getRegisterInfo();
116 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
119 MachineBasicBlock &MBB = *BI;
120 MachineBasicBlock::iterator I, Next;
121 for (I = MBB.begin(); I != MBB.end(); I = Next) {
123 MachineInstr &MI = *I;
125 if (!isSafeToFold(MI.getOpcode()))
128 MachineOperand &OpToFold = MI.getOperand(1);
130 // FIXME: Fold operands with subregs.
131 if (OpToFold.isReg() &&
132 (!TargetRegisterInfo::isVirtualRegister(OpToFold.getReg()) ||
133 OpToFold.getSubReg()))
136 std::vector<std::pair<MachineInstr *, unsigned>> FoldList;
137 for (MachineRegisterInfo::use_iterator
138 Use = MRI.use_begin(MI.getOperand(0).getReg()), E = MRI.use_end();
141 MachineInstr *UseMI = Use->getParent();
142 const MachineOperand &UseOp = UseMI->getOperand(Use.getOperandNo());
144 // FIXME: Fold operands with subregs.
145 if (UseOp.isReg() && UseOp.getSubReg()) {
149 // In order to fold immediates into copies, we need to change the
151 if ((OpToFold.isImm() || OpToFold.isFPImm()) &&
152 UseMI->getOpcode() == AMDGPU::COPY) {
153 const TargetRegisterClass *TRC =
154 MRI.getRegClass(UseMI->getOperand(0).getReg());
156 if (TRC->getSize() == 4) {
157 if (TRI.isSGPRClass(TRC))
158 UseMI->setDesc(TII->get(AMDGPU::S_MOV_B32));
160 UseMI->setDesc(TII->get(AMDGPU::V_MOV_B32_e32));
161 } else if (TRC->getSize() == 8 && TRI.isSGPRClass(TRC)) {
162 UseMI->setDesc(TII->get(AMDGPU::S_MOV_B64));
168 const MCInstrDesc &UseDesc = UseMI->getDesc();
170 // Don't fold into target independent nodes. Target independent opcodes
171 // don't have defined register classes.
172 if (UseDesc.isVariadic() ||
173 UseDesc.OpInfo[Use.getOperandNo()].RegClass == -1)
176 // Normal substitution
177 if (TII->isOperandLegal(UseMI, Use.getOperandNo(), &OpToFold)) {
178 FoldList.push_back(std::make_pair(UseMI, Use.getOperandNo()));
182 // FIXME: We could commute the instruction to create more opportunites
183 // for folding. This will only be useful if we have 32-bit instructions.
185 // FIXME: We could try to change the instruction from 64-bit to 32-bit
186 // to enable more folding opportunites. The shrink operands pass
187 // already does this.
190 for (std::pair<MachineInstr *, unsigned> Fold : FoldList) {
191 if (updateOperand(Fold.first, Fold.second, OpToFold, TRI)) {
193 if (OpToFold.isReg())
194 OpToFold.setIsKill(false);
195 DEBUG(dbgs() << "Folded source from " << MI << " into OpNo " <<
196 Fold.second << " of " << *Fold.first << '\n');