LLVM  4.0.0
HexagonStoreWidening.cpp
Go to the documentation of this file.
1 //===--- HexagonStoreWidening.cpp------------------------------------------===//
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 // Replace sequences of "narrow" stores to adjacent memory locations with
10 // a fewer "wide" stores that have the same effect.
11 // For example, replace:
12 // S4_storeirb_io %vreg100, 0, 0 ; store-immediate-byte
13 // S4_storeirb_io %vreg100, 1, 0 ; store-immediate-byte
14 // with
15 // S4_storeirh_io %vreg100, 0, 0 ; store-immediate-halfword
16 // The above is the general idea. The actual cases handled by the code
17 // may be a bit more complex.
18 // The purpose of this pass is to reduce the number of outstanding stores,
19 // or as one could say, "reduce store queue pressure". Also, wide stores
20 // mean fewer stores, and since there are only two memory instructions allowed
21 // per packet, it also means fewer packets, and ultimately fewer cycles.
22 //===---------------------------------------------------------------------===//
23 
24 #define DEBUG_TYPE "hexagon-widen-stores"
25 
26 #include "HexagonInstrInfo.h"
27 #include "HexagonRegisterInfo.h"
28 #include "HexagonSubtarget.h"
29 #include "llvm/ADT/SmallPtrSet.h"
30 #include "llvm/ADT/StringRef.h"
41 #include "llvm/IR/DebugLoc.h"
42 #include "llvm/MC/MCInstrDesc.h"
43 #include "llvm/Pass.h"
44 #include "llvm/Support/Debug.h"
48 #include <algorithm>
49 #include <cassert>
50 #include <cstdint>
51 #include <iterator>
52 #include <vector>
53 
54 using namespace llvm;
55 
56 namespace llvm {
57 
60 
61 } // end namespace llvm
62 
63 namespace {
64 
65  struct HexagonStoreWidening : public MachineFunctionPass {
66  const HexagonInstrInfo *TII;
67  const HexagonRegisterInfo *TRI;
68  const MachineRegisterInfo *MRI;
69  AliasAnalysis *AA;
70  MachineFunction *MF;
71 
72  public:
73  static char ID;
74 
75  HexagonStoreWidening() : MachineFunctionPass(ID) {
77  }
78 
79  bool runOnMachineFunction(MachineFunction &MF) override;
80 
81  StringRef getPassName() const override { return "Hexagon Store Widening"; }
82 
83  void getAnalysisUsage(AnalysisUsage &AU) const override {
87  }
88 
89  static bool handledStoreType(const MachineInstr *MI);
90 
91  private:
92  static const int MaxWideSize = 4;
93 
94  typedef std::vector<MachineInstr*> InstrGroup;
95  typedef std::vector<InstrGroup> InstrGroupList;
96 
97  bool instrAliased(InstrGroup &Stores, const MachineMemOperand &MMO);
98  bool instrAliased(InstrGroup &Stores, const MachineInstr *MI);
99  void createStoreGroup(MachineInstr *BaseStore, InstrGroup::iterator Begin,
100  InstrGroup::iterator End, InstrGroup &Group);
101  void createStoreGroups(MachineBasicBlock &MBB,
102  InstrGroupList &StoreGroups);
103  bool processBasicBlock(MachineBasicBlock &MBB);
104  bool processStoreGroup(InstrGroup &Group);
105  bool selectStores(InstrGroup::iterator Begin, InstrGroup::iterator End,
106  InstrGroup &OG, unsigned &TotalSize, unsigned MaxSize);
107  bool createWideStores(InstrGroup &OG, InstrGroup &NG, unsigned TotalSize);
108  bool replaceStores(InstrGroup &OG, InstrGroup &NG);
109  bool storesAreAdjacent(const MachineInstr *S1, const MachineInstr *S2);
110  };
111 
112 char HexagonStoreWidening::ID = 0;
113 
114 } // end anonymous namespace
115 
116 // Some local helper functions...
117 static unsigned getBaseAddressRegister(const MachineInstr *MI) {
118  const MachineOperand &MO = MI->getOperand(0);
119  assert(MO.isReg() && "Expecting register operand");
120  return MO.getReg();
121 }
122 
123 static int64_t getStoreOffset(const MachineInstr *MI) {
124  unsigned OpC = MI->getOpcode();
125  assert(HexagonStoreWidening::handledStoreType(MI) && "Unhandled opcode");
126 
127  switch (OpC) {
128  case Hexagon::S4_storeirb_io:
129  case Hexagon::S4_storeirh_io:
130  case Hexagon::S4_storeiri_io: {
131  const MachineOperand &MO = MI->getOperand(1);
132  assert(MO.isImm() && "Expecting immediate offset");
133  return MO.getImm();
134  }
135  }
136  dbgs() << *MI;
137  llvm_unreachable("Store offset calculation missing for a handled opcode");
138  return 0;
139 }
140 
142  assert(!MI->memoperands_empty() && "Expecting memory operands");
143  return **MI->memoperands_begin();
144 }
145 
146 INITIALIZE_PASS_BEGIN(HexagonStoreWidening, "hexagon-widen-stores",
147  "Hexason Store Widening", false, false)
149 INITIALIZE_PASS_END(HexagonStoreWidening, "hexagon-widen-stores",
150  "Hexagon Store Widening", false, false)
151 
152 // Filtering function: any stores whose opcodes are not "approved" of by
153 // this function will not be subjected to widening.
154 inline bool HexagonStoreWidening::handledStoreType(const MachineInstr *MI) {
155  // For now, only handle stores of immediate values.
156  // Also, reject stores to stack slots.
157  unsigned Opc = MI->getOpcode();
158  switch (Opc) {
159  case Hexagon::S4_storeirb_io:
160  case Hexagon::S4_storeirh_io:
161  case Hexagon::S4_storeiri_io:
162  // Base address must be a register. (Implement FI later.)
163  return MI->getOperand(0).isReg();
164  default:
165  return false;
166  }
167 }
168 
169 // Check if the machine memory operand MMO is aliased with any of the
170 // stores in the store group Stores.
171 bool HexagonStoreWidening::instrAliased(InstrGroup &Stores,
172  const MachineMemOperand &MMO) {
173  if (!MMO.getValue())
174  return true;
175 
176  MemoryLocation L(MMO.getValue(), MMO.getSize(), MMO.getAAInfo());
177 
178  for (auto SI : Stores) {
179  const MachineMemOperand &SMO = getStoreTarget(SI);
180  if (!SMO.getValue())
181  return true;
182 
183  MemoryLocation SL(SMO.getValue(), SMO.getSize(), SMO.getAAInfo());
184  if (AA->alias(L, SL))
185  return true;
186  }
187 
188  return false;
189 }
190 
191 // Check if the machine instruction MI accesses any storage aliased with
192 // any store in the group Stores.
193 bool HexagonStoreWidening::instrAliased(InstrGroup &Stores,
194  const MachineInstr *MI) {
195  for (auto &I : MI->memoperands())
196  if (instrAliased(Stores, *I))
197  return true;
198  return false;
199 }
200 
201 // Inspect a machine basic block, and generate store groups out of stores
202 // encountered in the block.
203 //
204 // A store group is a group of stores that use the same base register,
205 // and which can be reordered within that group without altering the
206 // semantics of the program. A single store group could be widened as
207 // a whole, if there existed a single store instruction with the same
208 // semantics as the entire group. In many cases, a single store group
209 // may need more than one wide store.
210 void HexagonStoreWidening::createStoreGroups(MachineBasicBlock &MBB,
211  InstrGroupList &StoreGroups) {
212  InstrGroup AllInsns;
213 
214  // Copy all instruction pointers from the basic block to a temporary
215  // list. This will allow operating on the list, and modifying its
216  // elements without affecting the basic block.
217  for (auto &I : MBB)
218  AllInsns.push_back(&I);
219 
220  // Traverse all instructions in the AllInsns list, and if we encounter
221  // a store, then try to create a store group starting at that instruction
222  // i.e. a sequence of independent stores that can be widened.
223  for (auto I = AllInsns.begin(), E = AllInsns.end(); I != E; ++I) {
224  MachineInstr *MI = *I;
225  // Skip null pointers (processed instructions).
226  if (!MI || !handledStoreType(MI))
227  continue;
228 
229  // Found a store. Try to create a store group.
230  InstrGroup G;
231  createStoreGroup(MI, I+1, E, G);
232  if (G.size() > 1)
233  StoreGroups.push_back(G);
234  }
235 }
236 
237 // Create a single store group. The stores need to be independent between
238 // themselves, and also there cannot be other instructions between them
239 // that could read or modify storage being stored into.
240 void HexagonStoreWidening::createStoreGroup(MachineInstr *BaseStore,
241  InstrGroup::iterator Begin, InstrGroup::iterator End, InstrGroup &Group) {
242  assert(handledStoreType(BaseStore) && "Unexpected instruction");
243  unsigned BaseReg = getBaseAddressRegister(BaseStore);
244  InstrGroup Other;
245 
246  Group.push_back(BaseStore);
247 
248  for (auto I = Begin; I != End; ++I) {
249  MachineInstr *MI = *I;
250  if (!MI)
251  continue;
252 
253  if (handledStoreType(MI)) {
254  // If this store instruction is aliased with anything already in the
255  // group, terminate the group now.
256  if (instrAliased(Group, getStoreTarget(MI)))
257  return;
258  // If this store is aliased to any of the memory instructions we have
259  // seen so far (that are not a part of this group), terminate the group.
260  if (instrAliased(Other, getStoreTarget(MI)))
261  return;
262 
263  unsigned BR = getBaseAddressRegister(MI);
264  if (BR == BaseReg) {
265  Group.push_back(MI);
266  *I = nullptr;
267  continue;
268  }
269  }
270 
271  // Assume calls are aliased to everything.
272  if (MI->isCall() || MI->hasUnmodeledSideEffects())
273  return;
274 
275  if (MI->mayLoad() || MI->mayStore()) {
276  if (MI->hasOrderedMemoryRef() || instrAliased(Group, MI))
277  return;
278  Other.push_back(MI);
279  }
280  } // for
281 }
282 
283 // Check if store instructions S1 and S2 are adjacent. More precisely,
284 // S2 has to access memory immediately following that accessed by S1.
285 bool HexagonStoreWidening::storesAreAdjacent(const MachineInstr *S1,
286  const MachineInstr *S2) {
287  if (!handledStoreType(S1) || !handledStoreType(S2))
288  return false;
289 
290  const MachineMemOperand &S1MO = getStoreTarget(S1);
291 
292  // Currently only handling immediate stores.
293  int Off1 = S1->getOperand(1).getImm();
294  int Off2 = S2->getOperand(1).getImm();
295 
296  return (Off1 >= 0) ? Off1+S1MO.getSize() == unsigned(Off2)
297  : int(Off1+S1MO.getSize()) == Off2;
298 }
299 
300 /// Given a sequence of adjacent stores, and a maximum size of a single wide
301 /// store, pick a group of stores that can be replaced by a single store
302 /// of size not exceeding MaxSize. The selected sequence will be recorded
303 /// in OG ("old group" of instructions).
304 /// OG should be empty on entry, and should be left empty if the function
305 /// fails.
306 bool HexagonStoreWidening::selectStores(InstrGroup::iterator Begin,
307  InstrGroup::iterator End, InstrGroup &OG, unsigned &TotalSize,
308  unsigned MaxSize) {
309  assert(Begin != End && "No instructions to analyze");
310  assert(OG.empty() && "Old group not empty on entry");
311 
312  if (std::distance(Begin, End) <= 1)
313  return false;
314 
315  MachineInstr *FirstMI = *Begin;
316  assert(!FirstMI->memoperands_empty() && "Expecting some memory operands");
317  const MachineMemOperand &FirstMMO = getStoreTarget(FirstMI);
318  unsigned Alignment = FirstMMO.getAlignment();
319  unsigned SizeAccum = FirstMMO.getSize();
320  unsigned FirstOffset = getStoreOffset(FirstMI);
321 
322  // The initial value of SizeAccum should always be a power of 2.
323  assert(isPowerOf2_32(SizeAccum) && "First store size not a power of 2");
324 
325  // If the size of the first store equals to or exceeds the limit, do nothing.
326  if (SizeAccum >= MaxSize)
327  return false;
328 
329  // If the size of the first store is greater than or equal to the address
330  // stored to, then the store cannot be made any wider.
331  if (SizeAccum >= Alignment)
332  return false;
333 
334  // The offset of a store will put restrictions on how wide the store can be.
335  // Offsets in stores of size 2^n bytes need to have the n lowest bits be 0.
336  // If the first store already exhausts the offset limits, quit. Test this
337  // by checking if the next wider size would exceed the limit.
338  if ((2*SizeAccum-1) & FirstOffset)
339  return false;
340 
341  OG.push_back(FirstMI);
342  MachineInstr *S1 = FirstMI, *S2 = *(Begin+1);
343  InstrGroup::iterator I = Begin+1;
344 
345  // Pow2Num will be the largest number of elements in OG such that the sum
346  // of sizes of stores 0...Pow2Num-1 will be a power of 2.
347  unsigned Pow2Num = 1;
348  unsigned Pow2Size = SizeAccum;
349 
350  // Be greedy: keep accumulating stores as long as they are to adjacent
351  // memory locations, and as long as the total number of bytes stored
352  // does not exceed the limit (MaxSize).
353  // Keep track of when the total size covered is a power of 2, since
354  // this is a size a single store can cover.
355  while (I != End) {
356  S2 = *I;
357  // Stores are sorted, so if S1 and S2 are not adjacent, there won't be
358  // any other store to fill the "hole".
359  if (!storesAreAdjacent(S1, S2))
360  break;
361 
362  unsigned S2Size = getStoreTarget(S2).getSize();
363  if (SizeAccum + S2Size > std::min(MaxSize, Alignment))
364  break;
365 
366  OG.push_back(S2);
367  SizeAccum += S2Size;
368  if (isPowerOf2_32(SizeAccum)) {
369  Pow2Num = OG.size();
370  Pow2Size = SizeAccum;
371  }
372  if ((2*Pow2Size-1) & FirstOffset)
373  break;
374 
375  S1 = S2;
376  ++I;
377  }
378 
379  // The stores don't add up to anything that can be widened. Clean up.
380  if (Pow2Num <= 1) {
381  OG.clear();
382  return false;
383  }
384 
385  // Only leave the stored being widened.
386  OG.resize(Pow2Num);
387  TotalSize = Pow2Size;
388  return true;
389 }
390 
391 /// Given an "old group" OG of stores, create a "new group" NG of instructions
392 /// to replace them. Ideally, NG would only have a single instruction in it,
393 /// but that may only be possible for store-immediate.
394 bool HexagonStoreWidening::createWideStores(InstrGroup &OG, InstrGroup &NG,
395  unsigned TotalSize) {
396  // XXX Current limitations:
397  // - only expect stores of immediate values in OG,
398  // - only handle a TotalSize of up to 4.
399 
400  if (TotalSize > 4)
401  return false;
402 
403  unsigned Acc = 0; // Value accumulator.
404  unsigned Shift = 0;
405 
406  for (InstrGroup::iterator I = OG.begin(), E = OG.end(); I != E; ++I) {
407  MachineInstr *MI = *I;
408  const MachineMemOperand &MMO = getStoreTarget(MI);
409  MachineOperand &SO = MI->getOperand(2); // Source.
410  assert(SO.isImm() && "Expecting an immediate operand");
411 
412  unsigned NBits = MMO.getSize()*8;
413  unsigned Mask = (0xFFFFFFFFU >> (32-NBits));
414  unsigned Val = (SO.getImm() & Mask) << Shift;
415  Acc |= Val;
416  Shift += NBits;
417  }
418 
419  MachineInstr *FirstSt = OG.front();
420  DebugLoc DL = OG.back()->getDebugLoc();
421  const MachineMemOperand &OldM = getStoreTarget(FirstSt);
422  MachineMemOperand *NewM =
423  MF->getMachineMemOperand(OldM.getPointerInfo(), OldM.getFlags(),
424  TotalSize, OldM.getAlignment(),
425  OldM.getAAInfo());
426 
427  if (Acc < 0x10000) {
428  // Create mem[hw] = #Acc
429  unsigned WOpc = (TotalSize == 2) ? Hexagon::S4_storeirh_io :
430  (TotalSize == 4) ? Hexagon::S4_storeiri_io : 0;
431  assert(WOpc && "Unexpected size");
432 
433  int Val = (TotalSize == 2) ? int16_t(Acc) : int(Acc);
434  const MCInstrDesc &StD = TII->get(WOpc);
435  MachineOperand &MR = FirstSt->getOperand(0);
436  int64_t Off = FirstSt->getOperand(1).getImm();
437  MachineInstr *StI = BuildMI(*MF, DL, StD)
438  .addReg(MR.getReg(), getKillRegState(MR.isKill()))
439  .addImm(Off)
440  .addImm(Val);
441  StI->addMemOperand(*MF, NewM);
442  NG.push_back(StI);
443  } else {
444  // Create vreg = A2_tfrsi #Acc; mem[hw] = vreg
445  const MCInstrDesc &TfrD = TII->get(Hexagon::A2_tfrsi);
446  const TargetRegisterClass *RC = TII->getRegClass(TfrD, 0, TRI, *MF);
447  unsigned VReg = MF->getRegInfo().createVirtualRegister(RC);
448  MachineInstr *TfrI = BuildMI(*MF, DL, TfrD, VReg)
449  .addImm(int(Acc));
450  NG.push_back(TfrI);
451 
452  unsigned WOpc = (TotalSize == 2) ? Hexagon::S2_storerh_io :
453  (TotalSize == 4) ? Hexagon::S2_storeri_io : 0;
454  assert(WOpc && "Unexpected size");
455 
456  const MCInstrDesc &StD = TII->get(WOpc);
457  MachineOperand &MR = FirstSt->getOperand(0);
458  int64_t Off = FirstSt->getOperand(1).getImm();
459  MachineInstr *StI = BuildMI(*MF, DL, StD)
460  .addReg(MR.getReg(), getKillRegState(MR.isKill()))
461  .addImm(Off)
462  .addReg(VReg, RegState::Kill);
463  StI->addMemOperand(*MF, NewM);
464  NG.push_back(StI);
465  }
466 
467  return true;
468 }
469 
470 // Replace instructions from the old group OG with instructions from the
471 // new group NG. Conceptually, remove all instructions in OG, and then
472 // insert all instructions in NG, starting at where the first instruction
473 // from OG was (in the order in which they appeared in the basic block).
474 // (The ordering in OG does not have to match the order in the basic block.)
475 bool HexagonStoreWidening::replaceStores(InstrGroup &OG, InstrGroup &NG) {
476  DEBUG({
477  dbgs() << "Replacing:\n";
478  for (auto I : OG)
479  dbgs() << " " << *I;
480  dbgs() << "with\n";
481  for (auto I : NG)
482  dbgs() << " " << *I;
483  });
484 
485  MachineBasicBlock *MBB = OG.back()->getParent();
486  MachineBasicBlock::iterator InsertAt = MBB->end();
487 
488  // Need to establish the insertion point. The best one is right before
489  // the first store in the OG, but in the order in which the stores occur
490  // in the program list. Since the ordering in OG does not correspond
491  // to the order in the program list, we need to do some work to find
492  // the insertion point.
493 
494  // Create a set of all instructions in OG (for quick lookup).
496  for (auto I : OG)
497  InstrSet.insert(I);
498 
499  // Traverse the block, until we hit an instruction from OG.
500  for (auto &I : *MBB) {
501  if (InstrSet.count(&I)) {
502  InsertAt = I;
503  break;
504  }
505  }
506 
507  assert((InsertAt != MBB->end()) && "Cannot locate any store from the group");
508 
509  bool AtBBStart = false;
510 
511  // InsertAt points at the first instruction that will be removed. We need
512  // to move it out of the way, so it remains valid after removing all the
513  // old stores, and so we are able to recover it back to the proper insertion
514  // position.
515  if (InsertAt != MBB->begin())
516  --InsertAt;
517  else
518  AtBBStart = true;
519 
520  for (auto I : OG)
521  I->eraseFromParent();
522 
523  if (!AtBBStart)
524  ++InsertAt;
525  else
526  InsertAt = MBB->begin();
527 
528  for (auto I : NG)
529  MBB->insert(InsertAt, I);
530 
531  return true;
532 }
533 
534 // Break up the group into smaller groups, each of which can be replaced by
535 // a single wide store. Widen each such smaller group and replace the old
536 // instructions with the widened ones.
537 bool HexagonStoreWidening::processStoreGroup(InstrGroup &Group) {
538  bool Changed = false;
539  InstrGroup::iterator I = Group.begin(), E = Group.end();
540  InstrGroup OG, NG; // Old and new groups.
541  unsigned CollectedSize;
542 
543  while (I != E) {
544  OG.clear();
545  NG.clear();
546 
547  bool Succ = selectStores(I++, E, OG, CollectedSize, MaxWideSize) &&
548  createWideStores(OG, NG, CollectedSize) &&
549  replaceStores(OG, NG);
550  if (!Succ)
551  continue;
552 
553  assert(OG.size() > 1 && "Created invalid group");
554  assert(distance(I, E)+1 >= int(OG.size()) && "Too many elements");
555  I += OG.size()-1;
556 
557  Changed = true;
558  }
559 
560  return Changed;
561 }
562 
563 // Process a single basic block: create the store groups, and replace them
564 // with the widened stores, if possible. Processing of each basic block
565 // is independent from processing of any other basic block. This transfor-
566 // mation could be stopped after having processed any basic block without
567 // any ill effects (other than not having performed widening in the unpro-
568 // cessed blocks). Also, the basic blocks can be processed in any order.
569 bool HexagonStoreWidening::processBasicBlock(MachineBasicBlock &MBB) {
570  InstrGroupList SGs;
571  bool Changed = false;
572 
573  createStoreGroups(MBB, SGs);
574 
575  auto Less = [] (const MachineInstr *A, const MachineInstr *B) -> bool {
576  return getStoreOffset(A) < getStoreOffset(B);
577  };
578  for (auto &G : SGs) {
579  assert(G.size() > 1 && "Store group with fewer than 2 elements");
580  std::sort(G.begin(), G.end(), Less);
581 
582  Changed |= processStoreGroup(G);
583  }
584 
585  return Changed;
586 }
587 
588 bool HexagonStoreWidening::runOnMachineFunction(MachineFunction &MFn) {
589  if (skipFunction(*MFn.getFunction()))
590  return false;
591 
592  MF = &MFn;
593  auto &ST = MFn.getSubtarget<HexagonSubtarget>();
594  TII = ST.getInstrInfo();
595  TRI = ST.getRegisterInfo();
596  MRI = &MFn.getRegInfo();
597  AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
598 
599  bool Changed = false;
600 
601  for (auto &B : MFn)
602  Changed |= processBasicBlock(B);
603 
604  return Changed;
605 }
606 
608  return new HexagonStoreWidening();
609 }
MachineLoop * L
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Flags getFlags() const
Return the raw flags of the source value,.
static const MachineMemOperand & getStoreTarget(const MachineInstr *MI)
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Definition: MachineInstr.h:605
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:380
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
A debug info location.
Definition: DebugLoc.h:34
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mmo_iterator > memoperands()
Definition: MachineInstr.h:365
const MachinePointerInfo & getPointerInfo() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:53
A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:592
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:662
bool isKill() const
MachineBasicBlock * MBB
uint64_t getAlignment() const
Return the minimum known alignment in bytes of the actual memory reference.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
int64_t getImm() const
void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
hexagon widen Hexagon Store Widening
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
unsigned getKillRegState(bool B)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:131
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:551
unsigned const MachineRegisterInfo * MRI
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
Definition: MathExtras.h:399
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
static int64_t getStoreOffset(const MachineInstr *MI)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:368
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static const unsigned End
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
FunctionPass * createHexagonStoreWidening()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Representation for a specific memory location.
bool memoperands_empty() const
Return true if we don't have any memory operands which described the the memory access done by this i...
Definition: MachineInstr.h:363
static unsigned getBaseAddressRegister(const MachineInstr *MI)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:425
hexagon widen Hexagon Store false
MachineOperand class - Representation of each machine instruction operand.
void initializeHexagonStoreWideningPass(PassRegistry &)
const DataFlowGraph & G
Definition: RDFGraph.cpp:206
always inline
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
INITIALIZE_PASS_BEGIN(HexagonStoreWidening,"hexagon-widen-stores","Hexason Store Widening", false, false) INITIALIZE_PASS_END(HexagonStoreWidening
const Value * getValue() const
Return the base address of the memory access.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:52
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
This file provides utility analysis objects describing memory locations.
#define I(x, y, z)
Definition: MD5.cpp:54
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:424
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
aarch64 promote const
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:81
uint64_t getSize() const
Return the size in bytes of the memory reference.
#define DEBUG(X)
Definition: Debug.h:100
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:40
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
hexagon widen stores
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:358