1 //===-- OptimizeExts.cpp - Optimize sign / zero extension instrs -----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define DEBUG_TYPE "ext-opt"
11 #include "llvm/CodeGen/Passes.h"
12 #include "llvm/CodeGen/MachineDominators.h"
13 #include "llvm/CodeGen/MachineInstrBuilder.h"
14 #include "llvm/CodeGen/MachineRegisterInfo.h"
15 #include "llvm/Target/TargetInstrInfo.h"
16 #include "llvm/Target/TargetRegisterInfo.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/ADT/Statistic.h"
22 static cl::opt<bool> Aggressive("aggressive-ext-opt", cl::Hidden,
23 cl::desc("Aggressive extension optimization"));
25 STATISTIC(NumReuse, "Number of extension results reused");
28 class OptimizeExts : public MachineFunctionPass {
29 const TargetMachine *TM;
30 const TargetInstrInfo *TII;
31 MachineRegisterInfo *MRI;
32 MachineDominatorTree *DT; // Machine dominator tree
35 static char ID; // Pass identification
36 OptimizeExts() : MachineFunctionPass(&ID) {}
38 virtual bool runOnMachineFunction(MachineFunction &MF);
40 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
42 MachineFunctionPass::getAnalysisUsage(AU);
43 AU.addRequired<MachineDominatorTree>();
44 AU.addPreserved<MachineDominatorTree>();
49 char OptimizeExts::ID = 0;
50 static RegisterPass<OptimizeExts>
51 X("opt-exts", "Optimize sign / zero extensions");
53 FunctionPass *llvm::createOptimizeExtsPass() { return new OptimizeExts(); }
55 bool OptimizeExts::runOnMachineFunction(MachineFunction &MF) {
57 TII = TM->getInstrInfo();
58 MRI = &MF.getRegInfo();
59 DT = &getAnalysis<MachineDominatorTree>();
63 SmallPtrSet<MachineInstr*, 8> LocalMIs;
64 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
65 MachineBasicBlock *MBB = &*I;
66 for (MachineBasicBlock::iterator MII = I->begin(), ME = I->end(); MII != ME;
68 MachineInstr *MI = &*MII;
71 unsigned SrcReg, DstReg, SubIdx;
72 if (TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx)) {
73 if (TargetRegisterInfo::isPhysicalRegister(DstReg) ||
74 TargetRegisterInfo::isPhysicalRegister(SrcReg))
77 MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg);
78 if (++UI == MRI->use_end())
82 // Ok, the source has other uses. See if we can replace the other uses
83 // with use of the result of the extension.
85 SmallPtrSet<MachineBasicBlock*, 4> ReachedBBs;
86 UI = MRI->use_begin(DstReg);
87 for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
89 ReachedBBs.insert(UI->getParent());
91 bool ExtendLife = true;
92 SmallVector<MachineOperand*, 8> Uses;
93 SmallVector<MachineOperand*, 8> ExtendedUses;
95 UI = MRI->use_begin(SrcReg);
96 for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
98 MachineOperand &UseMO = UI.getOperand();
99 MachineInstr *UseMI = &*UI;
102 MachineBasicBlock *UseMBB = UseMI->getParent();
104 // Local uses that come after the extension.
105 if (!LocalMIs.count(UseMI))
106 Uses.push_back(&UseMO);
107 } else if (ReachedBBs.count(UseMBB))
108 // Non-local uses where the result of extension is used. Always
110 Uses.push_back(&UseMO);
111 else if (Aggressive && DT->dominates(MBB, UseMBB))
112 // We may want to extend live range of the extension result in order
113 // to replace these uses.
114 ExtendedUses.push_back(&UseMO);
116 // Both will be live out of the def MBB anyway. Don't extend live
117 // range of the extension result.
123 if (ExtendLife && !ExtendedUses.empty())
124 // Ok, we'll extend the liveness of the extension result.
125 std::copy(ExtendedUses.begin(), ExtendedUses.end(),
126 std::back_inserter(Uses));
128 // Now replace all uses.
130 const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
131 for (unsigned i = 0, e = Uses.size(); i != e; ++i) {
132 MachineOperand *UseMO = Uses[i];
133 MachineInstr *UseMI = UseMO->getParent();
134 MachineBasicBlock *UseMBB = UseMI->getParent();
135 unsigned NewVR = MRI->createVirtualRegister(RC);
136 BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(),
137 TII->get(TargetInstrInfo::EXTRACT_SUBREG), NewVR)
138 .addReg(DstReg).addImm(SubIdx);
139 UseMO->setReg(NewVR);