Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/Hexagon/HexagonExpandCondsets.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | 3a76565eade5 |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
1 //===--- HexagonExpandCondsets.cpp ----------------------------------------===// | 1 //===- HexagonExpandCondsets.cpp ------------------------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
84 // that, the initial splitting will not add any implicit uses. These | 84 // that, the initial splitting will not add any implicit uses. These |
85 // implicit uses will be added later, after predication. The extra price, | 85 // implicit uses will be added later, after predication. The extra price, |
86 // however, is that finding the locations where the implicit uses need | 86 // however, is that finding the locations where the implicit uses need |
87 // to be added, and updating the live ranges will be more involved. | 87 // to be added, and updating the live ranges will be more involved. |
88 | 88 |
89 #define DEBUG_TYPE "expand-condsets" | 89 #include "HexagonInstrInfo.h" |
90 | 90 #include "HexagonRegisterInfo.h" |
91 #include "HexagonTargetMachine.h" | 91 #include "llvm/ADT/DenseMap.h" |
92 #include "llvm/ADT/SetVector.h" | 92 #include "llvm/ADT/SetVector.h" |
93 #include "llvm/CodeGen/Passes.h" | 93 #include "llvm/ADT/SmallVector.h" |
94 #include "llvm/ADT/StringRef.h" | |
94 #include "llvm/CodeGen/LiveInterval.h" | 95 #include "llvm/CodeGen/LiveInterval.h" |
95 #include "llvm/CodeGen/LiveIntervalAnalysis.h" | 96 #include "llvm/CodeGen/LiveIntervalAnalysis.h" |
97 #include "llvm/CodeGen/MachineBasicBlock.h" | |
96 #include "llvm/CodeGen/MachineDominators.h" | 98 #include "llvm/CodeGen/MachineDominators.h" |
97 #include "llvm/CodeGen/MachineFunction.h" | 99 #include "llvm/CodeGen/MachineFunction.h" |
100 #include "llvm/CodeGen/MachineFunctionPass.h" | |
101 #include "llvm/CodeGen/MachineInstr.h" | |
98 #include "llvm/CodeGen/MachineInstrBuilder.h" | 102 #include "llvm/CodeGen/MachineInstrBuilder.h" |
103 #include "llvm/CodeGen/MachineOperand.h" | |
99 #include "llvm/CodeGen/MachineRegisterInfo.h" | 104 #include "llvm/CodeGen/MachineRegisterInfo.h" |
100 #include "llvm/Target/TargetInstrInfo.h" | 105 #include "llvm/CodeGen/SlotIndexes.h" |
101 #include "llvm/Target/TargetMachine.h" | 106 #include "llvm/IR/DebugLoc.h" |
102 #include "llvm/Target/TargetRegisterInfo.h" | 107 #include "llvm/IR/Function.h" |
108 #include "llvm/MC/LaneBitmask.h" | |
109 #include "llvm/Pass.h" | |
103 #include "llvm/Support/CommandLine.h" | 110 #include "llvm/Support/CommandLine.h" |
104 #include "llvm/Support/Debug.h" | 111 #include "llvm/Support/Debug.h" |
112 #include "llvm/Support/ErrorHandling.h" | |
105 #include "llvm/Support/raw_ostream.h" | 113 #include "llvm/Support/raw_ostream.h" |
106 | 114 #include "llvm/Target/TargetRegisterInfo.h" |
107 #include <algorithm> | 115 #include "llvm/Target/TargetSubtargetInfo.h" |
116 #include <cassert> | |
108 #include <iterator> | 117 #include <iterator> |
109 #include <set> | 118 #include <set> |
110 #include <utility> | 119 #include <utility> |
120 | |
121 #define DEBUG_TYPE "expand-condsets" | |
111 | 122 |
112 using namespace llvm; | 123 using namespace llvm; |
113 | 124 |
114 static cl::opt<unsigned> OptTfrLimit("expand-condsets-tfr-limit", | 125 static cl::opt<unsigned> OptTfrLimit("expand-condsets-tfr-limit", |
115 cl::init(~0U), cl::Hidden, cl::desc("Max number of mux expansions")); | 126 cl::init(~0U), cl::Hidden, cl::desc("Max number of mux expansions")); |
116 static cl::opt<unsigned> OptCoaLimit("expand-condsets-coa-limit", | 127 static cl::opt<unsigned> OptCoaLimit("expand-condsets-coa-limit", |
117 cl::init(~0U), cl::Hidden, cl::desc("Max number of segment coalescings")); | 128 cl::init(~0U), cl::Hidden, cl::desc("Max number of segment coalescings")); |
118 | 129 |
119 namespace llvm { | 130 namespace llvm { |
131 | |
120 void initializeHexagonExpandCondsetsPass(PassRegistry&); | 132 void initializeHexagonExpandCondsetsPass(PassRegistry&); |
121 FunctionPass *createHexagonExpandCondsets(); | 133 FunctionPass *createHexagonExpandCondsets(); |
122 } | 134 |
135 } // end namespace llvm | |
123 | 136 |
124 namespace { | 137 namespace { |
138 | |
125 class HexagonExpandCondsets : public MachineFunctionPass { | 139 class HexagonExpandCondsets : public MachineFunctionPass { |
126 public: | 140 public: |
127 static char ID; | 141 static char ID; |
128 HexagonExpandCondsets() : | 142 |
129 MachineFunctionPass(ID), HII(0), TRI(0), MRI(0), | 143 HexagonExpandCondsets() : MachineFunctionPass(ID) { |
130 LIS(0), CoaLimitActive(false), | |
131 TfrLimitActive(false), CoaCounter(0), TfrCounter(0) { | |
132 if (OptCoaLimit.getPosition()) | 144 if (OptCoaLimit.getPosition()) |
133 CoaLimitActive = true, CoaLimit = OptCoaLimit; | 145 CoaLimitActive = true, CoaLimit = OptCoaLimit; |
134 if (OptTfrLimit.getPosition()) | 146 if (OptTfrLimit.getPosition()) |
135 TfrLimitActive = true, TfrLimit = OptTfrLimit; | 147 TfrLimitActive = true, TfrLimit = OptTfrLimit; |
136 initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry()); | 148 initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry()); |
137 } | 149 } |
138 | 150 |
139 StringRef getPassName() const override { return "Hexagon Expand Condsets"; } | 151 StringRef getPassName() const override { return "Hexagon Expand Condsets"; } |
152 | |
140 void getAnalysisUsage(AnalysisUsage &AU) const override { | 153 void getAnalysisUsage(AnalysisUsage &AU) const override { |
141 AU.addRequired<LiveIntervals>(); | 154 AU.addRequired<LiveIntervals>(); |
142 AU.addPreserved<LiveIntervals>(); | 155 AU.addPreserved<LiveIntervals>(); |
143 AU.addPreserved<SlotIndexes>(); | 156 AU.addPreserved<SlotIndexes>(); |
144 AU.addRequired<MachineDominatorTree>(); | 157 AU.addRequired<MachineDominatorTree>(); |
145 AU.addPreserved<MachineDominatorTree>(); | 158 AU.addPreserved<MachineDominatorTree>(); |
146 MachineFunctionPass::getAnalysisUsage(AU); | 159 MachineFunctionPass::getAnalysisUsage(AU); |
147 } | 160 } |
161 | |
148 bool runOnMachineFunction(MachineFunction &MF) override; | 162 bool runOnMachineFunction(MachineFunction &MF) override; |
149 | 163 |
150 private: | 164 private: |
151 const HexagonInstrInfo *HII; | 165 const HexagonInstrInfo *HII = nullptr; |
152 const TargetRegisterInfo *TRI; | 166 const TargetRegisterInfo *TRI = nullptr; |
153 MachineDominatorTree *MDT; | 167 MachineDominatorTree *MDT; |
154 MachineRegisterInfo *MRI; | 168 MachineRegisterInfo *MRI = nullptr; |
155 LiveIntervals *LIS; | 169 LiveIntervals *LIS = nullptr; |
156 | 170 bool CoaLimitActive = false; |
157 bool CoaLimitActive, TfrLimitActive; | 171 bool TfrLimitActive = false; |
158 unsigned CoaLimit, TfrLimit, CoaCounter, TfrCounter; | 172 unsigned CoaLimit; |
173 unsigned TfrLimit; | |
174 unsigned CoaCounter = 0; | |
175 unsigned TfrCounter = 0; | |
159 | 176 |
160 struct RegisterRef { | 177 struct RegisterRef { |
161 RegisterRef(const MachineOperand &Op) : Reg(Op.getReg()), | 178 RegisterRef(const MachineOperand &Op) : Reg(Op.getReg()), |
162 Sub(Op.getSubReg()) {} | 179 Sub(Op.getSubReg()) {} |
163 RegisterRef(unsigned R = 0, unsigned S = 0) : Reg(R), Sub(S) {} | 180 RegisterRef(unsigned R = 0, unsigned S = 0) : Reg(R), Sub(S) {} |
181 | |
164 bool operator== (RegisterRef RR) const { | 182 bool operator== (RegisterRef RR) const { |
165 return Reg == RR.Reg && Sub == RR.Sub; | 183 return Reg == RR.Reg && Sub == RR.Sub; |
166 } | 184 } |
167 bool operator!= (RegisterRef RR) const { return !operator==(RR); } | 185 bool operator!= (RegisterRef RR) const { return !operator==(RR); } |
168 bool operator< (RegisterRef RR) const { | 186 bool operator< (RegisterRef RR) const { |
169 return Reg < RR.Reg || (Reg == RR.Reg && Sub < RR.Sub); | 187 return Reg < RR.Reg || (Reg == RR.Reg && Sub < RR.Sub); |
170 } | 188 } |
189 | |
171 unsigned Reg, Sub; | 190 unsigned Reg, Sub; |
172 }; | 191 }; |
173 | 192 |
174 typedef DenseMap<unsigned,unsigned> ReferenceMap; | 193 using ReferenceMap = DenseMap<unsigned, unsigned>; |
175 enum { Sub_Low = 0x1, Sub_High = 0x2, Sub_None = (Sub_Low | Sub_High) }; | 194 enum { Sub_Low = 0x1, Sub_High = 0x2, Sub_None = (Sub_Low | Sub_High) }; |
176 enum { Exec_Then = 0x10, Exec_Else = 0x20 }; | 195 enum { Exec_Then = 0x10, Exec_Else = 0x20 }; |
196 | |
177 unsigned getMaskForSub(unsigned Sub); | 197 unsigned getMaskForSub(unsigned Sub); |
178 bool isCondset(const MachineInstr &MI); | 198 bool isCondset(const MachineInstr &MI); |
179 LaneBitmask getLaneMask(unsigned Reg, unsigned Sub); | 199 LaneBitmask getLaneMask(unsigned Reg, unsigned Sub); |
180 | 200 |
181 void addRefToMap(RegisterRef RR, ReferenceMap &Map, unsigned Exec); | 201 void addRefToMap(RegisterRef RR, ReferenceMap &Map, unsigned Exec); |
216 bool isIntraBlocks(LiveInterval &LI); | 236 bool isIntraBlocks(LiveInterval &LI); |
217 bool coalesceRegisters(RegisterRef R1, RegisterRef R2); | 237 bool coalesceRegisters(RegisterRef R1, RegisterRef R2); |
218 bool coalesceSegments(const SmallVectorImpl<MachineInstr*> &Condsets, | 238 bool coalesceSegments(const SmallVectorImpl<MachineInstr*> &Condsets, |
219 std::set<unsigned> &UpdRegs); | 239 std::set<unsigned> &UpdRegs); |
220 }; | 240 }; |
221 } | 241 |
242 } // end anonymous namespace | |
222 | 243 |
223 char HexagonExpandCondsets::ID = 0; | 244 char HexagonExpandCondsets::ID = 0; |
224 | 245 |
225 namespace llvm { | 246 namespace llvm { |
247 | |
226 char &HexagonExpandCondsetsID = HexagonExpandCondsets::ID; | 248 char &HexagonExpandCondsetsID = HexagonExpandCondsets::ID; |
227 } | 249 |
250 } // end namespace llvm | |
228 | 251 |
229 INITIALIZE_PASS_BEGIN(HexagonExpandCondsets, "expand-condsets", | 252 INITIALIZE_PASS_BEGIN(HexagonExpandCondsets, "expand-condsets", |
230 "Hexagon Expand Condsets", false, false) | 253 "Hexagon Expand Condsets", false, false) |
231 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) | 254 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) |
232 INITIALIZE_PASS_DEPENDENCY(SlotIndexes) | 255 INITIALIZE_PASS_DEPENDENCY(SlotIndexes) |
260 break; | 283 break; |
261 } | 284 } |
262 return false; | 285 return false; |
263 } | 286 } |
264 | 287 |
265 | |
266 LaneBitmask HexagonExpandCondsets::getLaneMask(unsigned Reg, unsigned Sub) { | 288 LaneBitmask HexagonExpandCondsets::getLaneMask(unsigned Reg, unsigned Sub) { |
267 assert(TargetRegisterInfo::isVirtualRegister(Reg)); | 289 assert(TargetRegisterInfo::isVirtualRegister(Reg)); |
268 return Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub) | 290 return Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub) |
269 : MRI->getMaxLaneMaskForVReg(Reg); | 291 : MRI->getMaxLaneMaskForVReg(Reg); |
270 } | 292 } |
271 | |
272 | 293 |
273 void HexagonExpandCondsets::addRefToMap(RegisterRef RR, ReferenceMap &Map, | 294 void HexagonExpandCondsets::addRefToMap(RegisterRef RR, ReferenceMap &Map, |
274 unsigned Exec) { | 295 unsigned Exec) { |
275 unsigned Mask = getMaskForSub(RR.Sub) | Exec; | 296 unsigned Mask = getMaskForSub(RR.Sub) | Exec; |
276 ReferenceMap::iterator F = Map.find(RR.Reg); | 297 ReferenceMap::iterator F = Map.find(RR.Reg); |
278 Map.insert(std::make_pair(RR.Reg, Mask)); | 299 Map.insert(std::make_pair(RR.Reg, Mask)); |
279 else | 300 else |
280 F->second |= Mask; | 301 F->second |= Mask; |
281 } | 302 } |
282 | 303 |
283 | |
284 bool HexagonExpandCondsets::isRefInMap(RegisterRef RR, ReferenceMap &Map, | 304 bool HexagonExpandCondsets::isRefInMap(RegisterRef RR, ReferenceMap &Map, |
285 unsigned Exec) { | 305 unsigned Exec) { |
286 ReferenceMap::iterator F = Map.find(RR.Reg); | 306 ReferenceMap::iterator F = Map.find(RR.Reg); |
287 if (F == Map.end()) | 307 if (F == Map.end()) |
288 return false; | 308 return false; |
289 unsigned Mask = getMaskForSub(RR.Sub) | Exec; | 309 unsigned Mask = getMaskForSub(RR.Sub) | Exec; |
290 if (Mask & F->second) | 310 if (Mask & F->second) |
291 return true; | 311 return true; |
292 return false; | 312 return false; |
293 } | 313 } |
294 | |
295 | 314 |
296 void HexagonExpandCondsets::updateKillFlags(unsigned Reg) { | 315 void HexagonExpandCondsets::updateKillFlags(unsigned Reg) { |
297 auto KillAt = [this,Reg] (SlotIndex K, LaneBitmask LM) -> void { | 316 auto KillAt = [this,Reg] (SlotIndex K, LaneBitmask LM) -> void { |
298 // Set the <kill> flag on a use of Reg whose lane mask is contained in LM. | 317 // Set the <kill> flag on a use of Reg whose lane mask is contained in LM. |
299 MachineInstr *MI = LIS->getInstructionFromIndex(K); | 318 MachineInstr *MI = LIS->getInstructionFromIndex(K); |
340 if (WholeReg) | 359 if (WholeReg) |
341 KillAt(I->end, MRI->getMaxLaneMaskForVReg(Reg)); | 360 KillAt(I->end, MRI->getMaxLaneMaskForVReg(Reg)); |
342 } | 361 } |
343 } | 362 } |
344 | 363 |
345 | |
346 void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM, | 364 void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM, |
347 LiveRange &Range) { | 365 LiveRange &Range) { |
348 assert(TargetRegisterInfo::isVirtualRegister(Reg)); | 366 assert(TargetRegisterInfo::isVirtualRegister(Reg)); |
349 if (Range.empty()) | 367 if (Range.empty()) |
350 return; | 368 return; |
351 | 369 |
352 auto IsRegDef = [this,Reg,LM] (MachineOperand &Op) -> bool { | 370 // Return two booleans: { def-modifes-reg, def-covers-reg }. |
371 auto IsRegDef = [this,Reg,LM] (MachineOperand &Op) -> std::pair<bool,bool> { | |
353 if (!Op.isReg() || !Op.isDef()) | 372 if (!Op.isReg() || !Op.isDef()) |
354 return false; | 373 return { false, false }; |
355 unsigned DR = Op.getReg(), DSR = Op.getSubReg(); | 374 unsigned DR = Op.getReg(), DSR = Op.getSubReg(); |
356 if (!TargetRegisterInfo::isVirtualRegister(DR) || DR != Reg) | 375 if (!TargetRegisterInfo::isVirtualRegister(DR) || DR != Reg) |
357 return false; | 376 return { false, false }; |
358 LaneBitmask SLM = getLaneMask(DR, DSR); | 377 LaneBitmask SLM = getLaneMask(DR, DSR); |
359 return (SLM & LM) != 0; | 378 LaneBitmask A = SLM & LM; |
379 return { A.any(), A == SLM }; | |
360 }; | 380 }; |
361 | 381 |
362 // The splitting step will create pairs of predicated definitions without | 382 // The splitting step will create pairs of predicated definitions without |
363 // any implicit uses (since implicit uses would interfere with predication). | 383 // any implicit uses (since implicit uses would interfere with predication). |
364 // This can cause the reaching defs to become dead after live range | 384 // This can cause the reaching defs to become dead after live range |
438 LIS->extendToIndices(Range, ExtTo, Undefs); | 458 LIS->extendToIndices(Range, ExtTo, Undefs); |
439 | 459 |
440 // Remove <dead> flags from all defs that are not dead after live range | 460 // Remove <dead> flags from all defs that are not dead after live range |
441 // extension, and collect all def operands. They will be used to generate | 461 // extension, and collect all def operands. They will be used to generate |
442 // the necessary implicit uses. | 462 // the necessary implicit uses. |
463 // At the same time, add <dead> flag to all defs that are actually dead. | |
464 // This can happen, for example, when a mux with identical inputs is | |
465 // replaced with a COPY: the use of the predicate register disappears and | |
466 // the dead can become dead. | |
443 std::set<RegisterRef> DefRegs; | 467 std::set<RegisterRef> DefRegs; |
444 for (auto &Seg : Range) { | 468 for (auto &Seg : Range) { |
445 if (!Seg.start.isRegister()) | 469 if (!Seg.start.isRegister()) |
446 continue; | 470 continue; |
447 MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start); | 471 MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start); |
448 for (auto &Op : DefI->operands()) { | 472 for (auto &Op : DefI->operands()) { |
449 if (Seg.start.isDead() || !IsRegDef(Op)) | 473 auto P = IsRegDef(Op); |
450 continue; | 474 if (P.second && Seg.end.isDead()) { |
451 DefRegs.insert(Op); | 475 Op.setIsDead(true); |
452 Op.setIsDead(false); | 476 } else if (P.first) { |
453 } | 477 DefRegs.insert(Op); |
454 } | 478 Op.setIsDead(false); |
455 | 479 } |
456 // Finally, add implicit uses to each predicated def that is reached | 480 } |
481 } | |
482 | |
483 // Now, add implicit uses to each predicated def that is reached | |
457 // by other defs. | 484 // by other defs. |
458 for (auto &Seg : Range) { | 485 for (auto &Seg : Range) { |
459 if (!Seg.start.isRegister() || !Range.liveAt(Seg.start.getPrevSlot())) | 486 if (!Seg.start.isRegister() || !Range.liveAt(Seg.start.getPrevSlot())) |
460 continue; | 487 continue; |
461 MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start); | 488 MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start); |
462 if (!HII->isPredicated(*DefI)) | 489 if (!HII->isPredicated(*DefI)) |
463 continue; | 490 continue; |
464 // Construct the set of all necessary implicit uses, based on the def | 491 // Construct the set of all necessary implicit uses, based on the def |
465 // operands in the instruction. | 492 // operands in the instruction. We need to tie the implicit uses to |
466 std::set<RegisterRef> ImpUses; | 493 // the corresponding defs. |
467 for (auto &Op : DefI->operands()) | 494 std::map<RegisterRef,unsigned> ImpUses; |
468 if (Op.isReg() && Op.isDef() && DefRegs.count(Op)) | 495 for (unsigned i = 0, e = DefI->getNumOperands(); i != e; ++i) { |
469 ImpUses.insert(Op); | 496 MachineOperand &Op = DefI->getOperand(i); |
497 if (!Op.isReg() || !DefRegs.count(Op)) | |
498 continue; | |
499 if (Op.isDef()) { | |
500 ImpUses.insert({Op, i}); | |
501 } else { | |
502 // This function can be called for the same register with different | |
503 // lane masks. If the def in this instruction was for the whole | |
504 // register, we can get here more than once. Avoid adding multiple | |
505 // implicit uses (or adding an implicit use when an explicit one is | |
506 // present). | |
507 ImpUses.erase(Op); | |
508 } | |
509 } | |
470 if (ImpUses.empty()) | 510 if (ImpUses.empty()) |
471 continue; | 511 continue; |
472 MachineFunction &MF = *DefI->getParent()->getParent(); | 512 MachineFunction &MF = *DefI->getParent()->getParent(); |
473 for (RegisterRef R : ImpUses) | 513 for (std::pair<RegisterRef, unsigned> P : ImpUses) { |
514 RegisterRef R = P.first; | |
474 MachineInstrBuilder(MF, DefI).addReg(R.Reg, RegState::Implicit, R.Sub); | 515 MachineInstrBuilder(MF, DefI).addReg(R.Reg, RegState::Implicit, R.Sub); |
475 } | 516 DefI->tieOperands(P.second, DefI->getNumOperands()-1); |
476 } | 517 } |
477 | 518 } |
519 } | |
478 | 520 |
479 void HexagonExpandCondsets::updateDeadFlags(unsigned Reg) { | 521 void HexagonExpandCondsets::updateDeadFlags(unsigned Reg) { |
480 LiveInterval &LI = LIS->getInterval(Reg); | 522 LiveInterval &LI = LIS->getInterval(Reg); |
481 if (LI.hasSubRanges()) { | 523 if (LI.hasSubRanges()) { |
482 for (LiveInterval::SubRange &S : LI.subranges()) { | 524 for (LiveInterval::SubRange &S : LI.subranges()) { |
488 } else { | 530 } else { |
489 updateDeadsInRange(Reg, MRI->getMaxLaneMaskForVReg(Reg), LI); | 531 updateDeadsInRange(Reg, MRI->getMaxLaneMaskForVReg(Reg), LI); |
490 } | 532 } |
491 } | 533 } |
492 | 534 |
493 | |
494 void HexagonExpandCondsets::recalculateLiveInterval(unsigned Reg) { | 535 void HexagonExpandCondsets::recalculateLiveInterval(unsigned Reg) { |
495 LIS->removeInterval(Reg); | 536 LIS->removeInterval(Reg); |
496 LIS->createAndComputeVirtRegInterval(Reg); | 537 LIS->createAndComputeVirtRegInterval(Reg); |
497 } | 538 } |
498 | 539 |
499 | |
500 void HexagonExpandCondsets::removeInstr(MachineInstr &MI) { | 540 void HexagonExpandCondsets::removeInstr(MachineInstr &MI) { |
501 LIS->RemoveMachineInstrFromMaps(MI); | 541 LIS->RemoveMachineInstrFromMaps(MI); |
502 MI.eraseFromParent(); | 542 MI.eraseFromParent(); |
503 } | 543 } |
504 | |
505 | 544 |
506 void HexagonExpandCondsets::updateLiveness(std::set<unsigned> &RegSet, | 545 void HexagonExpandCondsets::updateLiveness(std::set<unsigned> &RegSet, |
507 bool Recalc, bool UpdateKills, bool UpdateDeads) { | 546 bool Recalc, bool UpdateKills, bool UpdateDeads) { |
508 UpdateKills |= UpdateDeads; | 547 UpdateKills |= UpdateDeads; |
509 for (auto R : RegSet) { | 548 for (auto R : RegSet) { |
519 updateKillFlags(R); | 558 updateKillFlags(R); |
520 LIS->getInterval(R).verify(); | 559 LIS->getInterval(R).verify(); |
521 } | 560 } |
522 } | 561 } |
523 | 562 |
524 | |
525 /// Get the opcode for a conditional transfer of the value in SO (source | 563 /// Get the opcode for a conditional transfer of the value in SO (source |
526 /// operand). The condition (true/false) is given in Cond. | 564 /// operand). The condition (true/false) is given in Cond. |
527 unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO, | 565 unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO, |
528 bool IfTrue) { | 566 bool IfTrue) { |
529 using namespace Hexagon; | 567 using namespace Hexagon; |
568 | |
530 if (SO.isReg()) { | 569 if (SO.isReg()) { |
531 unsigned PhysR; | 570 unsigned PhysR; |
532 RegisterRef RS = SO; | 571 RegisterRef RS = SO; |
533 if (TargetRegisterInfo::isVirtualRegister(RS.Reg)) { | 572 if (TargetRegisterInfo::isVirtualRegister(RS.Reg)) { |
534 const TargetRegisterClass *VC = MRI->getRegClass(RS.Reg); | 573 const TargetRegisterClass *VC = MRI->getRegClass(RS.Reg); |
538 assert(TargetRegisterInfo::isPhysicalRegister(RS.Reg)); | 577 assert(TargetRegisterInfo::isPhysicalRegister(RS.Reg)); |
539 PhysR = RS.Reg; | 578 PhysR = RS.Reg; |
540 } | 579 } |
541 unsigned PhysS = (RS.Sub == 0) ? PhysR : TRI->getSubReg(PhysR, RS.Sub); | 580 unsigned PhysS = (RS.Sub == 0) ? PhysR : TRI->getSubReg(PhysR, RS.Sub); |
542 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS); | 581 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS); |
543 switch (RC->getSize()) { | 582 switch (TRI->getRegSizeInBits(*RC)) { |
544 case 4: | 583 case 32: |
545 return IfTrue ? A2_tfrt : A2_tfrf; | 584 return IfTrue ? A2_tfrt : A2_tfrf; |
546 case 8: | 585 case 64: |
547 return IfTrue ? A2_tfrpt : A2_tfrpf; | 586 return IfTrue ? A2_tfrpt : A2_tfrpf; |
548 } | 587 } |
549 llvm_unreachable("Invalid register operand"); | 588 llvm_unreachable("Invalid register operand"); |
550 } | 589 } |
551 if (SO.isImm() || SO.isFPImm()) | 590 switch (SO.getType()) { |
552 return IfTrue ? C2_cmoveit : C2_cmoveif; | 591 case MachineOperand::MO_Immediate: |
592 case MachineOperand::MO_FPImmediate: | |
593 case MachineOperand::MO_ConstantPoolIndex: | |
594 case MachineOperand::MO_TargetIndex: | |
595 case MachineOperand::MO_JumpTableIndex: | |
596 case MachineOperand::MO_ExternalSymbol: | |
597 case MachineOperand::MO_GlobalAddress: | |
598 case MachineOperand::MO_BlockAddress: | |
599 return IfTrue ? C2_cmoveit : C2_cmoveif; | |
600 default: | |
601 break; | |
602 } | |
553 llvm_unreachable("Unexpected source operand"); | 603 llvm_unreachable("Unexpected source operand"); |
554 } | 604 } |
555 | |
556 | 605 |
557 /// Generate a conditional transfer, copying the value SrcOp to the | 606 /// Generate a conditional transfer, copying the value SrcOp to the |
558 /// destination register DstR:DstSR, and using the predicate register from | 607 /// destination register DstR:DstSR, and using the predicate register from |
559 /// PredOp. The Cond argument specifies whether the predicate is to be | 608 /// PredOp. The Cond argument specifies whether the predicate is to be |
560 /// if(PredOp), or if(!PredOp). | 609 /// if(PredOp), or if(!PredOp). |
585 .addReg(DstR, DstState, DstSR) | 634 .addReg(DstR, DstState, DstSR) |
586 .addReg(PredOp.getReg(), PredState, PredOp.getSubReg()) | 635 .addReg(PredOp.getReg(), PredState, PredOp.getSubReg()) |
587 .addReg(SrcOp.getReg(), SrcState, SrcOp.getSubReg()); | 636 .addReg(SrcOp.getReg(), SrcState, SrcOp.getSubReg()); |
588 } else { | 637 } else { |
589 MIB = BuildMI(B, At, DL, HII->get(Opc)) | 638 MIB = BuildMI(B, At, DL, HII->get(Opc)) |
590 .addReg(DstR, DstState, DstSR) | 639 .addReg(DstR, DstState, DstSR) |
591 .addReg(PredOp.getReg(), PredState, PredOp.getSubReg()) | 640 .addReg(PredOp.getReg(), PredState, PredOp.getSubReg()) |
592 .addOperand(SrcOp); | 641 .add(SrcOp); |
593 } | 642 } |
594 | 643 |
595 DEBUG(dbgs() << "created an initial copy: " << *MIB); | 644 DEBUG(dbgs() << "created an initial copy: " << *MIB); |
596 return &*MIB; | 645 return &*MIB; |
597 } | 646 } |
598 | |
599 | 647 |
600 /// Replace a MUX instruction MI with a pair A2_tfrt/A2_tfrf. This function | 648 /// Replace a MUX instruction MI with a pair A2_tfrt/A2_tfrf. This function |
601 /// performs all necessary changes to complete the replacement. | 649 /// performs all necessary changes to complete the replacement. |
602 bool HexagonExpandCondsets::split(MachineInstr &MI, | 650 bool HexagonExpandCondsets::split(MachineInstr &MI, |
603 std::set<unsigned> &UpdRegs) { | 651 std::set<unsigned> &UpdRegs) { |
613 assert(MD.isDef()); | 661 assert(MD.isDef()); |
614 unsigned DR = MD.getReg(), DSR = MD.getSubReg(); | 662 unsigned DR = MD.getReg(), DSR = MD.getSubReg(); |
615 bool ReadUndef = MD.isUndef(); | 663 bool ReadUndef = MD.isUndef(); |
616 MachineBasicBlock::iterator At = MI; | 664 MachineBasicBlock::iterator At = MI; |
617 | 665 |
666 auto updateRegs = [&UpdRegs] (const MachineInstr &MI) -> void { | |
667 for (auto &Op : MI.operands()) | |
668 if (Op.isReg()) | |
669 UpdRegs.insert(Op.getReg()); | |
670 }; | |
671 | |
618 // If this is a mux of the same register, just replace it with COPY. | 672 // If this is a mux of the same register, just replace it with COPY. |
619 // Ideally, this would happen earlier, so that register coalescing would | 673 // Ideally, this would happen earlier, so that register coalescing would |
620 // see it. | 674 // see it. |
621 MachineOperand &ST = MI.getOperand(2); | 675 MachineOperand &ST = MI.getOperand(2); |
622 MachineOperand &SF = MI.getOperand(3); | 676 MachineOperand &SF = MI.getOperand(3); |
623 if (ST.isReg() && SF.isReg()) { | 677 if (ST.isReg() && SF.isReg()) { |
624 RegisterRef RT(ST); | 678 RegisterRef RT(ST); |
625 if (RT == RegisterRef(SF)) { | 679 if (RT == RegisterRef(SF)) { |
680 // Copy regs to update first. | |
681 updateRegs(MI); | |
626 MI.setDesc(HII->get(TargetOpcode::COPY)); | 682 MI.setDesc(HII->get(TargetOpcode::COPY)); |
627 unsigned S = getRegState(ST); | 683 unsigned S = getRegState(ST); |
628 while (MI.getNumOperands() > 1) | 684 while (MI.getNumOperands() > 1) |
629 MI.RemoveOperand(MI.getNumOperands()-1); | 685 MI.RemoveOperand(MI.getNumOperands()-1); |
630 MachineFunction &MF = *MI.getParent()->getParent(); | 686 MachineFunction &MF = *MI.getParent()->getParent(); |
642 genCondTfrFor(SF, At, DR, DSR, MP, false, ReadUndef, true); | 698 genCondTfrFor(SF, At, DR, DSR, MP, false, ReadUndef, true); |
643 LIS->InsertMachineInstrInMaps(*TfrT); | 699 LIS->InsertMachineInstrInMaps(*TfrT); |
644 LIS->InsertMachineInstrInMaps(*TfrF); | 700 LIS->InsertMachineInstrInMaps(*TfrF); |
645 | 701 |
646 // Will need to recalculate live intervals for all registers in MI. | 702 // Will need to recalculate live intervals for all registers in MI. |
647 for (auto &Op : MI.operands()) | 703 updateRegs(MI); |
648 if (Op.isReg()) | |
649 UpdRegs.insert(Op.getReg()); | |
650 | 704 |
651 removeInstr(MI); | 705 removeInstr(MI); |
652 return true; | 706 return true; |
653 } | 707 } |
654 | 708 |
669 for (auto &Mo : MI->memoperands()) | 723 for (auto &Mo : MI->memoperands()) |
670 if (Mo->isVolatile()) | 724 if (Mo->isVolatile()) |
671 return false; | 725 return false; |
672 return true; | 726 return true; |
673 } | 727 } |
674 | |
675 | 728 |
676 /// Find the reaching definition for a predicated use of RD. The RD is used | 729 /// Find the reaching definition for a predicated use of RD. The RD is used |
677 /// under the conditions given by PredR and Cond, and this function will ignore | 730 /// under the conditions given by PredR and Cond, and this function will ignore |
678 /// definitions that set RD under the opposite conditions. | 731 /// definitions that set RD under the opposite conditions. |
679 MachineInstr *HexagonExpandCondsets::getReachingDefForPred(RegisterRef RD, | 732 MachineInstr *HexagonExpandCondsets::getReachingDefForPred(RegisterRef RD, |
680 MachineBasicBlock::iterator UseIt, unsigned PredR, bool Cond) { | 733 MachineBasicBlock::iterator UseIt, unsigned PredR, bool Cond) { |
681 MachineBasicBlock &B = *UseIt->getParent(); | 734 MachineBasicBlock &B = *UseIt->getParent(); |
682 MachineBasicBlock::iterator I = UseIt, S = B.begin(); | 735 MachineBasicBlock::iterator I = UseIt, S = B.begin(); |
683 if (I == S) | 736 if (I == S) |
684 return 0; | 737 return nullptr; |
685 | 738 |
686 bool PredValid = true; | 739 bool PredValid = true; |
687 do { | 740 do { |
688 --I; | 741 --I; |
689 MachineInstr *MI = &*I; | 742 MachineInstr *MI = &*I; |
710 // If we are looking for vreg1:loreg, we can skip vreg1:hireg, but | 763 // If we are looking for vreg1:loreg, we can skip vreg1:hireg, but |
711 // not vreg1 (w/o subregisters). | 764 // not vreg1 (w/o subregisters). |
712 if (RR.Sub == RD.Sub) | 765 if (RR.Sub == RD.Sub) |
713 return MI; | 766 return MI; |
714 if (RR.Sub == 0 || RD.Sub == 0) | 767 if (RR.Sub == 0 || RD.Sub == 0) |
715 return 0; | 768 return nullptr; |
716 // We have different subregisters, so we can continue looking. | 769 // We have different subregisters, so we can continue looking. |
717 } | 770 } |
718 } while (I != S); | 771 } while (I != S); |
719 | 772 |
720 return 0; | 773 return nullptr; |
721 } | 774 } |
722 | |
723 | 775 |
724 /// Check if the instruction MI can be safely moved over a set of instructions | 776 /// Check if the instruction MI can be safely moved over a set of instructions |
725 /// whose side-effects (in terms of register defs and uses) are expressed in | 777 /// whose side-effects (in terms of register defs and uses) are expressed in |
726 /// the maps Defs and Uses. These maps reflect the conditional defs and uses | 778 /// the maps Defs and Uses. These maps reflect the conditional defs and uses |
727 /// that depend on the same predicate register to allow moving instructions | 779 /// that depend on the same predicate register to allow moving instructions |
748 return false; | 800 return false; |
749 } | 801 } |
750 return true; | 802 return true; |
751 } | 803 } |
752 | 804 |
753 | |
754 /// Check if the instruction accessing memory (TheI) can be moved to the | 805 /// Check if the instruction accessing memory (TheI) can be moved to the |
755 /// location ToI. | 806 /// location ToI. |
756 bool HexagonExpandCondsets::canMoveMemTo(MachineInstr &TheI, MachineInstr &ToI, | 807 bool HexagonExpandCondsets::canMoveMemTo(MachineInstr &TheI, MachineInstr &ToI, |
757 bool IsDown) { | 808 bool IsDown) { |
758 bool IsLoad = TheI.mayLoad(), IsStore = TheI.mayStore(); | 809 bool IsLoad = TheI.mayLoad(), IsStore = TheI.mayStore(); |
782 if (Conflict) | 833 if (Conflict) |
783 return false; | 834 return false; |
784 } | 835 } |
785 return true; | 836 return true; |
786 } | 837 } |
787 | |
788 | 838 |
789 /// Generate a predicated version of MI (where the condition is given via | 839 /// Generate a predicated version of MI (where the condition is given via |
790 /// PredR and Cond) at the point indicated by Where. | 840 /// PredR and Cond) at the point indicated by Where. |
791 void HexagonExpandCondsets::predicateAt(const MachineOperand &DefOp, | 841 void HexagonExpandCondsets::predicateAt(const MachineOperand &DefOp, |
792 MachineInstr &MI, | 842 MachineInstr &MI, |
823 MB.addReg(PredOp.getReg(), PredOp.isUndef() ? RegState::Undef : 0, | 873 MB.addReg(PredOp.getReg(), PredOp.isUndef() ? RegState::Undef : 0, |
824 PredOp.getSubReg()); | 874 PredOp.getSubReg()); |
825 while (Ox < NP) { | 875 while (Ox < NP) { |
826 MachineOperand &MO = MI.getOperand(Ox); | 876 MachineOperand &MO = MI.getOperand(Ox); |
827 if (!MO.isReg() || !MO.isImplicit()) | 877 if (!MO.isReg() || !MO.isImplicit()) |
828 MB.addOperand(MO); | 878 MB.add(MO); |
829 Ox++; | 879 Ox++; |
830 } | 880 } |
831 | 881 |
832 MachineFunction &MF = *B.getParent(); | 882 MachineFunction &MF = *B.getParent(); |
833 MachineInstr::mmo_iterator I = MI.memoperands_begin(); | 883 MachineInstr::mmo_iterator I = MI.memoperands_begin(); |
843 | 893 |
844 for (auto &Op : NewI->operands()) | 894 for (auto &Op : NewI->operands()) |
845 if (Op.isReg()) | 895 if (Op.isReg()) |
846 UpdRegs.insert(Op.getReg()); | 896 UpdRegs.insert(Op.getReg()); |
847 } | 897 } |
848 | |
849 | 898 |
850 /// In the range [First, Last], rename all references to the "old" register RO | 899 /// In the range [First, Last], rename all references to the "old" register RO |
851 /// to the "new" register RN, but only in instructions predicated on the given | 900 /// to the "new" register RN, but only in instructions predicated on the given |
852 /// condition. | 901 /// condition. |
853 void HexagonExpandCondsets::renameInRange(RegisterRef RO, RegisterRef RN, | 902 void HexagonExpandCondsets::renameInRange(RegisterRef RO, RegisterRef RN, |
872 assert(!Op.isDef() && "Not expecting a def"); | 921 assert(!Op.isDef() && "Not expecting a def"); |
873 } | 922 } |
874 } | 923 } |
875 } | 924 } |
876 | 925 |
877 | |
878 /// For a given conditional copy, predicate the definition of the source of | 926 /// For a given conditional copy, predicate the definition of the source of |
879 /// the copy under the given condition (using the same predicate register as | 927 /// the copy under the given condition (using the same predicate register as |
880 /// the copy). | 928 /// the copy). |
881 bool HexagonExpandCondsets::predicate(MachineInstr &TfrI, bool Cond, | 929 bool HexagonExpandCondsets::predicate(MachineInstr &TfrI, bool Cond, |
882 std::set<unsigned> &UpdRegs) { | 930 std::set<unsigned> &UpdRegs) { |
917 // Check if the predicate register is valid between DefI and TfrI. | 965 // Check if the predicate register is valid between DefI and TfrI. |
918 // If it is, we can then ignore instructions predicated on the negated | 966 // If it is, we can then ignore instructions predicated on the negated |
919 // conditions when collecting def and use information. | 967 // conditions when collecting def and use information. |
920 bool PredValid = true; | 968 bool PredValid = true; |
921 for (MachineBasicBlock::iterator I = std::next(DefIt); I != TfrIt; ++I) { | 969 for (MachineBasicBlock::iterator I = std::next(DefIt); I != TfrIt; ++I) { |
922 if (!I->modifiesRegister(PredR, 0)) | 970 if (!I->modifiesRegister(PredR, nullptr)) |
923 continue; | 971 continue; |
924 PredValid = false; | 972 PredValid = false; |
925 break; | 973 break; |
926 } | 974 } |
927 | 975 |
1008 | 1056 |
1009 removeInstr(TfrI); | 1057 removeInstr(TfrI); |
1010 removeInstr(*DefI); | 1058 removeInstr(*DefI); |
1011 return true; | 1059 return true; |
1012 } | 1060 } |
1013 | |
1014 | 1061 |
1015 /// Predicate all cases of conditional copies in the specified block. | 1062 /// Predicate all cases of conditional copies in the specified block. |
1016 bool HexagonExpandCondsets::predicateInBlock(MachineBasicBlock &B, | 1063 bool HexagonExpandCondsets::predicateInBlock(MachineBasicBlock &B, |
1017 std::set<unsigned> &UpdRegs) { | 1064 std::set<unsigned> &UpdRegs) { |
1018 bool Changed = false; | 1065 bool Changed = false; |
1036 } | 1083 } |
1037 } | 1084 } |
1038 return Changed; | 1085 return Changed; |
1039 } | 1086 } |
1040 | 1087 |
1041 | |
1042 bool HexagonExpandCondsets::isIntReg(RegisterRef RR, unsigned &BW) { | 1088 bool HexagonExpandCondsets::isIntReg(RegisterRef RR, unsigned &BW) { |
1043 if (!TargetRegisterInfo::isVirtualRegister(RR.Reg)) | 1089 if (!TargetRegisterInfo::isVirtualRegister(RR.Reg)) |
1044 return false; | 1090 return false; |
1045 const TargetRegisterClass *RC = MRI->getRegClass(RR.Reg); | 1091 const TargetRegisterClass *RC = MRI->getRegClass(RR.Reg); |
1046 if (RC == &Hexagon::IntRegsRegClass) { | 1092 if (RC == &Hexagon::IntRegsRegClass) { |
1051 BW = (RR.Sub != 0) ? 32 : 64; | 1097 BW = (RR.Sub != 0) ? 32 : 64; |
1052 return true; | 1098 return true; |
1053 } | 1099 } |
1054 return false; | 1100 return false; |
1055 } | 1101 } |
1056 | |
1057 | 1102 |
1058 bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) { | 1103 bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) { |
1059 for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { | 1104 for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { |
1060 LiveRange::Segment &LR = *I; | 1105 LiveRange::Segment &LR = *I; |
1061 // Range must start at a register... | 1106 // Range must start at a register... |
1066 return false; | 1111 return false; |
1067 } | 1112 } |
1068 return true; | 1113 return true; |
1069 } | 1114 } |
1070 | 1115 |
1071 | |
1072 bool HexagonExpandCondsets::coalesceRegisters(RegisterRef R1, RegisterRef R2) { | 1116 bool HexagonExpandCondsets::coalesceRegisters(RegisterRef R1, RegisterRef R2) { |
1073 if (CoaLimitActive) { | 1117 if (CoaLimitActive) { |
1074 if (CoaCounter >= CoaLimit) | 1118 if (CoaCounter >= CoaLimit) |
1075 return false; | 1119 return false; |
1076 CoaCounter++; | 1120 CoaCounter++; |
1107 return false; | 1151 return false; |
1108 | 1152 |
1109 MRI->replaceRegWith(R2.Reg, R1.Reg); | 1153 MRI->replaceRegWith(R2.Reg, R1.Reg); |
1110 | 1154 |
1111 // Move all live segments from L2 to L1. | 1155 // Move all live segments from L2 to L1. |
1112 typedef DenseMap<VNInfo*,VNInfo*> ValueInfoMap; | 1156 using ValueInfoMap = DenseMap<VNInfo *, VNInfo *>; |
1113 ValueInfoMap VM; | 1157 ValueInfoMap VM; |
1114 for (LiveInterval::iterator I = L2.begin(), E = L2.end(); I != E; ++I) { | 1158 for (LiveInterval::iterator I = L2.begin(), E = L2.end(); I != E; ++I) { |
1115 VNInfo *NewVN, *OldVN = I->valno; | 1159 VNInfo *NewVN, *OldVN = I->valno; |
1116 ValueInfoMap::iterator F = VM.find(OldVN); | 1160 ValueInfoMap::iterator F = VM.find(OldVN); |
1117 if (F == VM.end()) { | 1161 if (F == VM.end()) { |
1130 DEBUG(dbgs() << "coalesced: " << L1 << "\n"); | 1174 DEBUG(dbgs() << "coalesced: " << L1 << "\n"); |
1131 L1.verify(); | 1175 L1.verify(); |
1132 | 1176 |
1133 return true; | 1177 return true; |
1134 } | 1178 } |
1135 | |
1136 | 1179 |
1137 /// Attempt to coalesce one of the source registers to a MUX instruction with | 1180 /// Attempt to coalesce one of the source registers to a MUX instruction with |
1138 /// the destination register. This could lead to having only one predicated | 1181 /// the destination register. This could lead to having only one predicated |
1139 /// instruction in the end instead of two. | 1182 /// instruction in the end instead of two. |
1140 bool HexagonExpandCondsets::coalesceSegments( | 1183 bool HexagonExpandCondsets::coalesceSegments( |
1197 Changed |= Done; | 1240 Changed |= Done; |
1198 } | 1241 } |
1199 return Changed; | 1242 return Changed; |
1200 } | 1243 } |
1201 | 1244 |
1202 | |
1203 bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) { | 1245 bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) { |
1204 if (skipFunction(*MF.getFunction())) | 1246 if (skipFunction(*MF.getFunction())) |
1205 return false; | 1247 return false; |
1206 | 1248 |
1207 HII = static_cast<const HexagonInstrInfo*>(MF.getSubtarget().getInstrInfo()); | 1249 HII = static_cast<const HexagonInstrInfo*>(MF.getSubtarget().getInstrInfo()); |
1277 }); | 1319 }); |
1278 | 1320 |
1279 return Changed; | 1321 return Changed; |
1280 } | 1322 } |
1281 | 1323 |
1282 | |
1283 //===----------------------------------------------------------------------===// | 1324 //===----------------------------------------------------------------------===// |
1284 // Public Constructor Functions | 1325 // Public Constructor Functions |
1285 //===----------------------------------------------------------------------===// | 1326 //===----------------------------------------------------------------------===// |
1286 | 1327 |
1287 FunctionPass *llvm::createHexagonExpandCondsets() { | 1328 FunctionPass *llvm::createHexagonExpandCondsets() { |