"llvm/git@repo.hca.bsc.es:rferrer/llvm-epi-0.8.git" did not exist on "dd1e562ec3a49b2b1f9ccfe59ce3b681be6ab729"
Newer
Older
Evan Cheng
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//===-- OptimizeExts.cpp - Optimize sign / zero extension instrs -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "ext-opt"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
static cl::opt<bool> Aggressive("aggressive-ext-opt", cl::Hidden,
cl::desc("Aggressive extension optimization"));
STATISTIC(NumReuse, "Number of extension results reused");
namespace {
class OptimizeExts : public MachineFunctionPass {
const TargetMachine *TM;
const TargetInstrInfo *TII;
MachineRegisterInfo *MRI;
MachineDominatorTree *DT; // Machine dominator tree
public:
static char ID; // Pass identification
OptimizeExts() : MachineFunctionPass(&ID) {}
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
MachineFunctionPass::getAnalysisUsage(AU);
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
}
};
}
char OptimizeExts::ID = 0;
static RegisterPass<OptimizeExts>
X("opt-exts", "Optimize sign / zero extensions");
FunctionPass *llvm::createOptimizeExtsPass() { return new OptimizeExts(); }
bool OptimizeExts::runOnMachineFunction(MachineFunction &MF) {
TM = &MF.getTarget();
TII = TM->getInstrInfo();
MRI = &MF.getRegInfo();
DT = &getAnalysis<MachineDominatorTree>();
bool Changed = false;
SmallPtrSet<MachineInstr*, 8> LocalMIs;
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
MachineBasicBlock *MBB = &*I;
for (MachineBasicBlock::iterator MII = I->begin(), ME = I->end(); MII != ME;
++MII) {
MachineInstr *MI = &*MII;
LocalMIs.insert(MI);
unsigned SrcReg, DstReg, SubIdx;
if (TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx)) {
if (TargetRegisterInfo::isPhysicalRegister(DstReg) ||
TargetRegisterInfo::isPhysicalRegister(SrcReg))
continue;
MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg);
if (++UI == MRI->use_end())
// No other uses.
continue;
// Ok, the source has other uses. See if we can replace the other uses
// with use of the result of the extension.
SmallPtrSet<MachineBasicBlock*, 4> ReachedBBs;
UI = MRI->use_begin(DstReg);
for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
++UI)
ReachedBBs.insert(UI->getParent());
bool ExtendLife = true;
SmallVector<MachineOperand*, 8> Uses;
SmallVector<MachineOperand*, 8> ExtendedUses;
UI = MRI->use_begin(SrcReg);
for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
++UI) {
MachineOperand &UseMO = UI.getOperand();
MachineInstr *UseMI = &*UI;
if (UseMI == MI)
continue;
MachineBasicBlock *UseMBB = UseMI->getParent();
if (UseMBB == MBB) {
// Local uses that come after the extension.
if (!LocalMIs.count(UseMI))
Uses.push_back(&UseMO);
} else if (ReachedBBs.count(UseMBB))
// Non-local uses where the result of extension is used. Always
// replace these.
Uses.push_back(&UseMO);
else if (Aggressive && DT->dominates(MBB, UseMBB))
// We may want to extend live range of the extension result in order
// to replace these uses.
ExtendedUses.push_back(&UseMO);
else {
// Both will be live out of the def MBB anyway. Don't extend live
// range of the extension result.
ExtendLife = false;
break;
}
}
if (ExtendLife && !ExtendedUses.empty())
// Ok, we'll extend the liveness of the extension result.
std::copy(ExtendedUses.begin(), ExtendedUses.end(),
std::back_inserter(Uses));
// Now replace all uses.
if (!Uses.empty()) {
const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
for (unsigned i = 0, e = Uses.size(); i != e; ++i) {
MachineOperand *UseMO = Uses[i];
MachineInstr *UseMI = UseMO->getParent();
MachineBasicBlock *UseMBB = UseMI->getParent();
unsigned NewVR = MRI->createVirtualRegister(RC);
BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(),
TII->get(TargetInstrInfo::EXTRACT_SUBREG), NewVR)
.addReg(DstReg).addImm(SubIdx);
UseMO->setReg(NewVR);
++NumReuse;
Changed = true;
}
}
}
}
}
return Changed;
}