LLVM: lib/Target/Hexagon/HexagonGenMemAbsolute.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
24
25#define DEBUG_TYPE "hexagon-abs"
26
27using namespace llvm;
28
30 "Number of Load instructions converted to absolute-set form");
32 "Number of Store instructions converted to absolute-set form");
33
34namespace {
35
40
41public:
42 static char ID;
44
45 StringRef getPassName() const override {
46 return "Hexagon Generate Load/Store Set Absolute Address Instruction";
47 }
48
49 void getAnalysisUsage(AnalysisUsage &AU) const override {
51 AU.addRequired();
52 AU.addPreserved();
53 }
54
55 bool runOnMachineFunction(MachineFunction &Fn) override;
56
57private:
59 static bool isValidIndexedStore(int &Opcode, int &NewOpcode);
60};
61}
62
63char HexagonGenMemAbsolute::ID = 0;
64
65INITIALIZE_PASS(HexagonGenMemAbsolute, "hexagon-gen-load-absolute",
66 "Hexagon Generate Load/Store Set Absolute Address Instruction",
67 false, false)
68
70 if (skipFunction(Fn.getFunction()))
71 return false;
72
74 MRI = &Fn.getRegInfo();
75 TRI = Fn.getRegInfo().getTargetRegisterInfo();
76
78 getAnalysis().getDomTree();
79
80
82
84 ++MII) {
87 if (Opc != Hexagon::CONST32 && Opc != Hexagon::A2_tfrsi)
88 continue;
89
92 continue;
93
94 unsigned DstReg = MO.getReg();
95 if (MRI->use_nodbg_empty(DstReg))
96 continue;
97
99 use_iterator NextUseMI = MRI->use_nodbg_begin(DstReg);
100
102 int NextOpc = NextMI->getOpcode();
103 int NewOpc;
105
106 if (!IsLoad && !isValidIndexedStore(NextOpc, NewOpc))
107 continue;
108
109
110
111
112 unsigned BaseRegPos, ImmPos, RegPos;
113 if (->getBaseAndOffsetPosition(*NextMI, BaseRegPos, ImmPos))
114 continue;
115 RegPos = IsLoad ? 0 : 2;
116
117 bool IsGlobal = MI->getOperand(1).isGlobal();
118 if (->getOperand(1).isImm() && !IsGlobal)
119 continue;
120
123 bool Scalable;
124 TII->getMemOperandWithOffset(*NextMI, BaseOp, Offset, Scalable, TRI);
125
126
127 if (!BaseOp || !BaseOp->isReg())
128 continue;
129
130 if (Scalable)
131 continue;
132
133 unsigned BaseReg = BaseOp->getReg();
134 if ((DstReg != BaseReg) || (Offset != 0))
135 continue;
136
138
139 if (!MO0.isReg())
140 continue;
141
142 unsigned LoadStoreReg = MO0.getReg();
143
144
145
146 if (LoadStoreReg == BaseReg)
147 continue;
148
149
150
151
152 bool Dominates = true;
153 unsigned Counter = 0;
154 for (use_iterator I = NextUseMI, E = MRI->use_nodbg_end(); I != E; ++I) {
155 Counter++;
156 if (!MDT.dominates(NextMI, I->getParent()))
157 Dominates = false;
158 }
159
160 if ((!Dominates) || (Counter < 3))
161 continue;
162
163
164
166 dbgs() << "Found a pair of instructions for absolute-set "
167 << (IsLoad ? "load" : "store") << "\n";
169 dbgs() << *NextMI;
170 });
173 if (IsLoad) {
174 ++HexagonNumLoadAbsConversions;
176 TII->get(NewOpc), LoadStoreReg)
178 } else {
179 ++HexagonNumStoreAbsConversions;
181 TII->get(NewOpc), DstReg);
182 }
183
185 if (IsGlobal)
188 else
190
191 if (IsLoad)
193 else
195
196 LLVM_DEBUG(dbgs() << "Replaced with " << *MIB << "\n");
197
199 --MII;
201 }
202 }
203
204 return true;
205}
206
207bool HexagonGenMemAbsolute::isValidIndexedLoad(int &Opc, int &NewOpc) {
208
210 switch (Opc) {
211 case Hexagon::L2_loadrb_io:
212 NewOpc = Hexagon::L4_loadrb_ap;
213 break;
214 case Hexagon::L2_loadrh_io:
215 NewOpc = Hexagon::L4_loadrh_ap;
216 break;
217 case Hexagon::L2_loadri_io:
218 NewOpc = Hexagon::L4_loadri_ap;
219 break;
220 case Hexagon::L2_loadrd_io:
221 NewOpc = Hexagon::L4_loadrd_ap;
222 break;
223 case Hexagon::L2_loadruh_io:
224 NewOpc = Hexagon::L4_loadruh_ap;
225 break;
226 case Hexagon::L2_loadrub_io:
227 NewOpc = Hexagon::L4_loadrub_ap;
228 break;
229 default:
231 }
232
234}
235
236bool HexagonGenMemAbsolute::isValidIndexedStore(int &Opc, int &NewOpc) {
237
239 switch (Opc) {
240 case Hexagon::S2_storerd_io:
241 NewOpc = Hexagon::S4_storerd_ap;
242 break;
243 case Hexagon::S2_storeri_io:
244 NewOpc = Hexagon::S4_storeri_ap;
245 break;
246 case Hexagon::S2_storerh_io:
247 NewOpc = Hexagon::S4_storerh_ap;
248 break;
249 case Hexagon::S2_storerb_io:
250 NewOpc = Hexagon::S4_storerb_ap;
251 break;
252 default:
254 }
255
257}
258
259
260
261
262
264 return new HexagonGenMemAbsolute();
265}
unsigned const MachineRegisterInfo * MRI
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
const TargetInstrInfo & TII
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isValidIndexedLoad(const LoadSDNode *LD)
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
FunctionPass class - This class is used to implement most global optimizations.
const HexagonInstrInfo * getInstrInfo() const override
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstrBundleIterator< MachineInstr > iterator
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
unsigned getTargetFlags() const
Register getReg() const
getReg - Returns the register number.
int64_t getOffset() const
Return the offset from the symbol in this operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_iterator< true, false, true, true, false > use_nodbg_iterator
use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the specified register,...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Define
Register definition.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createHexagonGenMemAbsolute()
Definition HexagonGenMemAbsolute.cpp:263