Go to the documentation of this file.
51 #define DEBUG_TYPE "hexagon-widen-stores"
80 StringRef getPassName()
const override {
return "Hexagon Store Widening"; }
91 static const int MaxWideSize = 4;
93 using InstrGroup = std::vector<MachineInstr *>;
94 using InstrGroupList = std::vector<InstrGroup>;
98 void createStoreGroup(
MachineInstr *BaseStore, InstrGroup::iterator Begin,
99 InstrGroup::iterator End, InstrGroup &Group);
101 InstrGroupList &StoreGroups);
103 bool processStoreGroup(InstrGroup &Group);
104 bool selectStores(InstrGroup::iterator Begin, InstrGroup::iterator End,
105 InstrGroup &OG,
unsigned &TotalSize,
unsigned MaxSize);
106 bool createWideStores(InstrGroup &OG, InstrGroup &NG,
unsigned TotalSize);
107 bool replaceStores(InstrGroup &OG, InstrGroup &NG);
116 "Hexason Store Widening",
false,
false)
124 assert(MO.
isReg() &&
"Expecting register operand");
129 unsigned OpC =
MI->getOpcode();
130 assert(HexagonStoreWidening::handledStoreType(
MI) &&
"Unhandled opcode");
133 case Hexagon::S4_storeirb_io:
134 case Hexagon::S4_storeirh_io:
135 case Hexagon::S4_storeiri_io: {
137 assert(MO.
isImm() &&
"Expecting immediate offset");
147 assert(!
MI->memoperands_empty() &&
"Expecting memory operands");
148 return **
MI->memoperands_begin();
153 inline bool HexagonStoreWidening::handledStoreType(
const MachineInstr *
MI) {
156 unsigned Opc =
MI->getOpcode();
158 case Hexagon::S4_storeirb_io:
159 case Hexagon::S4_storeirh_io:
160 case Hexagon::S4_storeiri_io:
162 return MI->getOperand(0).isReg();
170 bool HexagonStoreWidening::instrAliased(InstrGroup &Stores,
177 for (
auto SI : Stores) {
183 if (!
AA->isNoAlias(L, SL))
192 bool HexagonStoreWidening::instrAliased(InstrGroup &Stores,
194 for (
auto &
I :
MI->memoperands())
195 if (instrAliased(Stores, *
I))
210 InstrGroupList &StoreGroups) {
217 AllInsns.push_back(&
I);
222 for (
auto I = AllInsns.begin(),
E = AllInsns.end();
I !=
E; ++
I) {
225 if (!
MI || !handledStoreType(
MI))
230 createStoreGroup(
MI,
I+1,
E,
G);
232 StoreGroups.push_back(
G);
239 void HexagonStoreWidening::createStoreGroup(
MachineInstr *BaseStore,
240 InstrGroup::iterator Begin, InstrGroup::iterator End, InstrGroup &Group) {
241 assert(handledStoreType(BaseStore) &&
"Unexpected instruction");
245 Group.push_back(BaseStore);
247 for (
auto I = Begin;
I != End; ++
I) {
252 if (handledStoreType(
MI)) {
271 if (
MI->isCall() ||
MI->hasUnmodeledSideEffects())
274 if (
MI->mayLoadOrStore()) {
275 if (
MI->hasOrderedMemoryRef() || instrAliased(Group,
MI))
284 bool HexagonStoreWidening::storesAreAdjacent(
const MachineInstr *S1,
286 if (!handledStoreType(S1) || !handledStoreType(S2))
295 return (Off1 >= 0) ? Off1+S1MO.
getSize() == unsigned(Off2)
296 :
int(Off1+S1MO.getSize()) == Off2;
305 bool HexagonStoreWidening::selectStores(InstrGroup::iterator Begin,
306 InstrGroup::iterator End, InstrGroup &OG,
unsigned &TotalSize,
308 assert(Begin != End &&
"No instructions to analyze");
309 assert(OG.empty() &&
"Old group not empty on entry");
311 if (std::distance(Begin, End) <= 1)
318 unsigned SizeAccum = FirstMMO.
getSize();
325 if (SizeAccum >= MaxSize)
330 if (SizeAccum >= Alignment)
337 if ((2*SizeAccum-1) & FirstOffset)
340 OG.push_back(FirstMI);
345 unsigned Pow2Num = 1;
346 unsigned Pow2Size = SizeAccum;
353 for (InstrGroup::iterator
I = Begin + 1;
I != End; ++
I) {
357 if (!storesAreAdjacent(S1, S2))
361 if (SizeAccum + S2Size >
std::min(MaxSize, Alignment))
368 Pow2Size = SizeAccum;
370 if ((2*Pow2Size-1) & FirstOffset)
384 TotalSize = Pow2Size;
391 bool HexagonStoreWidening::createWideStores(InstrGroup &OG, InstrGroup &NG,
392 unsigned TotalSize) {
406 assert(SO.
isImm() &&
"Expecting an immediate operand");
408 unsigned NBits = MMO.
getSize()*8;
409 unsigned Mask = (0xFFFFFFFFU >> (32-NBits));
424 unsigned WOpc = (TotalSize == 2) ? Hexagon::S4_storeirh_io :
425 (TotalSize == 4) ? Hexagon::S4_storeiri_io : 0;
426 assert(WOpc &&
"Unexpected size");
428 int Val = (TotalSize == 2) ? int16_t(Acc) :
int(Acc);
443 Register VReg = MF->getRegInfo().createVirtualRegister(RC);
448 unsigned WOpc = (TotalSize == 2) ? Hexagon::S2_storerh_io :
449 (TotalSize == 4) ? Hexagon::S2_storeri_io : 0;
450 assert(WOpc &&
"Unexpected size");
472 bool HexagonStoreWidening::replaceStores(InstrGroup &OG, InstrGroup &NG) {
474 dbgs() <<
"Replacing:\n";
497 for (
auto &
I : *
MBB) {
504 assert((InsertAt !=
MBB->
end()) &&
"Cannot locate any store from the group");
506 bool AtBBStart =
false;
518 I->eraseFromParent();
534 bool HexagonStoreWidening::processStoreGroup(InstrGroup &Group) {
535 bool Changed =
false;
536 InstrGroup::iterator
I = Group.begin(),
E = Group.end();
538 unsigned CollectedSize;
544 bool Succ = selectStores(
I++,
E, OG, CollectedSize, MaxWideSize) &&
545 createWideStores(OG, NG, CollectedSize) &&
546 replaceStores(OG, NG);
550 assert(OG.size() > 1 &&
"Created invalid group");
551 assert(distance(
I,
E)+1 >=
int(OG.size()) &&
"Too many elements");
568 bool Changed =
false;
570 createStoreGroups(
MBB, SGs);
575 for (
auto &
G : SGs) {
576 assert(
G.size() > 1 &&
"Store group with fewer than 2 elements");
579 Changed |= processStoreGroup(
G);
585 bool HexagonStoreWidening::runOnMachineFunction(
MachineFunction &MFn) {
591 TII =
ST.getInstrInfo();
592 TRI =
ST.getRegisterInfo();
594 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
596 bool Changed =
false;
599 Changed |= processBasicBlock(
B);
605 return new HexagonStoreWidening();
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
A description of a memory reference used in the backend.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
FunctionPass * createHexagonStoreWidening()
unsigned const TargetRegisterInfo * TRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const MachinePointerInfo & getPointerInfo() const
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static int64_t getStoreOffset(const MachineInstr *MI)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const Value * getValue() const
Return the base address of the memory access.
const MachineOperand & getOperand(unsigned i) const
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Represent the analysis usage information of a pass.
@ Kill
The last use of a register.
const HexagonInstrInfo * TII
Describe properties that are true of each instruction in the target description file.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
hexagon widen Hexagon Store static false unsigned getBaseAddressRegister(const MachineInstr *MI)
INITIALIZE_PASS_BEGIN(HexagonStoreWidening, "hexagon-widen-stores", "Hexason Store Widening", false, false) INITIALIZE_PASS_END(HexagonStoreWidening
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StandardInstrumentations SI(Debug, VerifyEach)
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Register getReg() const
getReg - Returns the register number.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const MachineBasicBlock * getParent() const
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
unsigned getSubReg() const
Function & getFunction()
Return the LLVM function that this machine code represents.
@ BR
Control flow instructions. These all have token chains.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
uint64_t value() const
This is a hole in the type system and should not be abused.
uint64_t getSize() const
Return the size in bytes of the memory reference.
void sort(IteratorTy Start, IteratorTy End)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool memoperands_empty() const
Return true if we don't have any memory operands which described the memory access done by this instr...
unsigned getKillRegState(bool B)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
FunctionPass class - This class is used to implement most global optimizations.
AnalysisUsage & addRequired()
hexagon widen Hexagon Store Widening
Flags getFlags() const
Return the raw flags of the source value,.
static const MachineMemOperand & getStoreTarget(const MachineInstr *MI)
Representation for a specific memory location.
Optional< std::vector< StOtherPiece > > Other
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void initializeHexagonStoreWideningPass(PassRegistry &)