blob: 02fc82ec3140553b878de491e36dbbc98f9aee7c [file] [log] [blame]
Evan Cheng7da9ecf2010-01-13 00:30:23 +00001//===-- OptimizeExts.cpp - Optimize sign / zero extension instrs -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
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"
20using namespace llvm;
21
22static cl::opt<bool> Aggressive("aggressive-ext-opt", cl::Hidden,
23 cl::desc("Aggressive extension optimization"));
24
25STATISTIC(NumReuse, "Number of extension results reused");
26
27namespace {
28 class OptimizeExts : public MachineFunctionPass {
29 const TargetMachine *TM;
30 const TargetInstrInfo *TII;
31 MachineRegisterInfo *MRI;
32 MachineDominatorTree *DT; // Machine dominator tree
33
34 public:
35 static char ID; // Pass identification
36 OptimizeExts() : MachineFunctionPass(&ID) {}
37
38 virtual bool runOnMachineFunction(MachineFunction &MF);
39
40 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
41 AU.setPreservesCFG();
42 MachineFunctionPass::getAnalysisUsage(AU);
43 AU.addRequired<MachineDominatorTree>();
44 AU.addPreserved<MachineDominatorTree>();
45 }
46 };
47}
48
49char OptimizeExts::ID = 0;
50static RegisterPass<OptimizeExts>
51X("opt-exts", "Optimize sign / zero extensions");
52
53FunctionPass *llvm::createOptimizeExtsPass() { return new OptimizeExts(); }
54
55bool OptimizeExts::runOnMachineFunction(MachineFunction &MF) {
56 TM = &MF.getTarget();
57 TII = TM->getInstrInfo();
58 MRI = &MF.getRegInfo();
59 DT = &getAnalysis<MachineDominatorTree>();
60
61 bool Changed = false;
62
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;
67 ++MII) {
68 MachineInstr *MI = &*MII;
69 LocalMIs.insert(MI);
70
71 unsigned SrcReg, DstReg, SubIdx;
72 if (TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx)) {
73 if (TargetRegisterInfo::isPhysicalRegister(DstReg) ||
74 TargetRegisterInfo::isPhysicalRegister(SrcReg))
75 continue;
76
77 MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg);
78 if (++UI == MRI->use_end())
79 // No other uses.
80 continue;
81
82 // Ok, the source has other uses. See if we can replace the other uses
83 // with use of the result of the extension.
84
85 SmallPtrSet<MachineBasicBlock*, 4> ReachedBBs;
86 UI = MRI->use_begin(DstReg);
87 for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
88 ++UI)
89 ReachedBBs.insert(UI->getParent());
90
91 bool ExtendLife = true;
92 SmallVector<MachineOperand*, 8> Uses;
93 SmallVector<MachineOperand*, 8> ExtendedUses;
94
95 UI = MRI->use_begin(SrcReg);
96 for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
97 ++UI) {
98 MachineOperand &UseMO = UI.getOperand();
99 MachineInstr *UseMI = &*UI;
100 if (UseMI == MI)
101 continue;
102 MachineBasicBlock *UseMBB = UseMI->getParent();
103 if (UseMBB == MBB) {
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
109 // replace these.
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);
115 else {
116 // Both will be live out of the def MBB anyway. Don't extend live
117 // range of the extension result.
118 ExtendLife = false;
119 break;
120 }
121 }
122
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));
127
128 // Now replace all uses.
129 if (!Uses.empty()) {
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);
140 ++NumReuse;
141 Changed = true;
142 }
143 }
144 }
145 }
146 }
147
148 return Changed;
149}