15 #define DEBUG_TYPE "misched"
45 cl::desc(
"Enable use of AA during MI GAD construction"));
52 :
ScheduleDAG(mf), MLI(mli), MDT(mdt), MFI(mf.getFrameInfo()), LIS(lis),
53 IsPostRA(IsPostRAFlag), CanHandleTerminators(
false), FirstDbgValue(0) {
54 assert((
IsPostRA ||
LIS) &&
"PreRA scheduling requires LiveIntervals");
57 "Virtual registers must be removed prior to PostRA scheduling");
67 if (
const Operator *U = dyn_cast<Operator>(V)) {
70 if (U->getOpcode() == Instruction::PtrToInt)
71 return U->getOperand(0);
78 if (U->getOpcode() != Instruction::Add ||
79 (!isa<ConstantInt>(U->getOperand(1)) &&
81 !isa<PHINode>(U->getOperand(1))))
116 Objects.
push_back(const_cast<Value *>(V));
118 }
while (!Working.
empty());
144 bool MayAlias =
true;
152 if (PSV->isAliased(MFI)) {
157 MayAlias = PSV->mayAlias(MFI);
183 unsigned regioninstrs) {
184 assert(bb ==
BB &&
"startBlock should set BB");
207 bool AllDepKnown = ExitMI &&
209 if (ExitMI && AllDepKnown) {
216 if (Reg == 0)
continue;
221 assert(!
IsPostRA &&
"Virtual register encountered after regalloc.");
229 assert(
Uses.
empty() &&
"Uses in set before adding deps?");
233 E = (*SI)->livein_end();
I != E; ++
I) {
245 assert(MO.
isDef() &&
"expect physreg def");
261 int UseOp =
I->OpIdx;
277 ST.adjustSchedDependency(SU, UseSU, Dep);
311 SDep Dep(SU, Kind, *Alias);
346 for (
bool isBegin = I == B; !isBegin; ) {
347 isBegin = (--
I) == B;
386 SUnit *DefSU = DefI->SU;
387 if (DefSU != SU && DefSU != &
ExitSU) {
417 assert(
LIS &&
"vreg dependencies requires LiveIntervals");
423 assert(VNI &&
"No value to read by operand");
486 if (PSV->isAliased(MFI))
545 assert ((MMOa->
getOffset() >= 0) &&
"Negative MachineMemOperand offset");
546 assert ((MMOb->
getOffset() >= 0) &&
"Negative MachineMemOperand offset");
567 if (!SUa || !SUb || SUb == ExitSU)
610 SUnit *SU,
SUnit *ExitSU, std::set<SUnit *> &CheckList,
611 unsigned LatencyToLoad) {
618 for (std::set<SUnit *>::iterator
I = CheckList.begin(),
IE = CheckList.end();
624 Dep.
setLatency(((*I)->getInstr()->mayLoad()) ? LatencyToLoad : 0);
630 JE = (*I)->Succs.end(); J != JE; ++J)
633 ExitSU, &Depth, Visited);
642 std::set<SUnit *> &RejectList,
643 unsigned TrueMemOrderLatency = 0,
644 bool isNormalMemory =
false) {
654 RejectList.insert(SUb);
655 DEBUG(
dbgs() <<
"\tReject chain dep between SU("
717 SUnit *BarrierChain = 0, *AliasChain = 0;
725 std::set<SUnit*> RejectMemNodes;
733 "Only BuildGraph should update Defs/Uses");
737 assert(
VRegDefs.
empty() &&
"Only BuildSchedGraph may access VRegDefs");
752 DbgValues.push_back(std::make_pair(DbgMI, MI));
761 assert(SU &&
"No SUnit mapped to this MI");
765 RPTracker->
recede(0, PDiff);
766 assert(RPTracker->
getPos() ==
prior(
MII) &&
"RPTracker can't find MI");
770 "Cannot schedule terminators or labels!");
773 bool HasVRegDef =
false;
776 if (!MO.
isReg())
continue;
778 if (Reg == 0)
continue;
783 assert(!
IsPostRA &&
"Virtual register encountered!");
799 && (HasVRegDef || MI->
mayLoad())) {
814 unsigned TrueMemOrderLatency = MI->
mayStore() ? 1 : 0;
819 NonAliasMemDefs.
begin(), E = NonAliasMemDefs.
end();
I != E; ++
I) {
823 NonAliasMemUses.
begin(), E = NonAliasMemUses.
end();
I != E; ++
I) {
824 for (
unsigned i = 0, e =
I->second.size(); i != e; ++i) {
827 I->second[i]->addPred(Dep);
837 TrueMemOrderLatency);
838 RejectMemNodes.clear();
839 NonAliasMemDefs.
clear();
840 NonAliasMemUses.
clear();
846 unsigned ChainLatency = 0;
847 if (AliasChain->getInstr()->mayLoad())
848 ChainLatency = TrueMemOrderLatency;
853 for (
unsigned k = 0, m =
PendingLoads.size(); k != m; ++k)
855 TrueMemOrderLatency);
857 E = AliasMemDefs.
end();
I != E; ++
I)
860 AliasMemUses.
begin(), E = AliasMemUses.
end();
I != E; ++
I) {
861 for (
unsigned i = 0, e =
I->second.size(); i != e; ++i)
863 TrueMemOrderLatency);
866 TrueMemOrderLatency);
868 AliasMemDefs.
clear();
869 AliasMemUses.
clear();
876 goto new_alias_chain;
879 bool MayAlias =
false;
882 const Value *V = K->getPointer();
883 bool ThisMayAlias = K->getInt();
891 ((ThisMayAlias) ? AliasMemDefs.
find(V) : NonAliasMemDefs.
find(V));
893 ((ThisMayAlias) ? AliasMemDefs.
end() : NonAliasMemDefs.
end());
900 AliasMemDefs[V] = SU;
902 NonAliasMemDefs[V] = SU;
906 ((ThisMayAlias) ? AliasMemUses.
find(V) : NonAliasMemUses.
find(V));
908 ((ThisMayAlias) ? AliasMemUses.
end() : NonAliasMemUses.
end());
910 for (
unsigned i = 0, e = J->second.
size(); i != e; ++i)
912 TrueMemOrderLatency,
true);
919 for (
unsigned k = 0, m =
PendingLoads.size(); k != m; ++k)
921 TrueMemOrderLatency);
928 TrueMemOrderLatency);
942 bool MayAlias =
true;
953 AliasMemDefs.
begin(), E = AliasMemDefs.
end();
I != E; ++
I)
963 J = Objs.
begin(), JE = Objs.
end(); J != JE; ++J) {
964 const Value *V = J->getPointer();
965 bool ThisMayAlias = J->getInt();
972 ((ThisMayAlias) ? AliasMemDefs.
find(V) : NonAliasMemDefs.
find(V));
974 ((ThisMayAlias) ? AliasMemDefs.
end() : NonAliasMemDefs.
end());
979 AliasMemUses[V].push_back(SU);
981 NonAliasMemUses[V].push_back(SU);
986 if (MayAlias && AliasChain)
1003 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1038 std::vector<std::pair<const SUnit*, const SUnit*> > ConnectionPairs;
1042 unsigned ParentNodeID;
1043 unsigned SubInstrCount;
1045 RootData(
unsigned id): NodeID(
id),
1046 ParentNodeID(SchedDFSResult::InvalidSubtreeID),
1049 unsigned getSparseSetIndex()
const {
return NodeID; }
1064 return R.DFSNodeData[SU->
NodeNum].SubtreeID
1065 != SchedDFSResult::InvalidSubtreeID;
1071 R.DFSNodeData[SU->
NodeNum].InstrCount =
1090 unsigned InstrCount = R.DFSNodeData[SU->
NodeNum].InstrCount;
1092 PI = SU->
Preds.begin(), PE = SU->
Preds.end(); PI != PE; ++PI) {
1095 unsigned PredNum = PI->getSUnit()->NodeNum;
1096 if ((InstrCount - R.DFSNodeData[PredNum].InstrCount) < R.SubtreeLimit)
1100 if (R.DFSNodeData[PredNum].SubtreeID == PredNum) {
1103 if (RootSet[PredNum].ParentNodeID == SchedDFSResult::InvalidSubtreeID)
1104 RootSet[PredNum].ParentNodeID = SU->
NodeNum;
1106 else if (RootSet.
count(PredNum)) {
1111 RData.SubInstrCount += RootSet[PredNum].SubInstrCount;
1112 RootSet.
erase(PredNum);
1122 R.DFSNodeData[Succ->
NodeNum].InstrCount
1129 ConnectionPairs.push_back(std::make_pair(PredDep.
getSUnit(), Succ));
1138 &&
"number of roots should match trees");
1140 RI = RootSet.
begin(), RE = RootSet.
end(); RI != RE; ++RI) {
1141 unsigned TreeID = SubtreeClasses[RI->NodeID];
1142 if (RI->ParentNodeID != SchedDFSResult::InvalidSubtreeID)
1143 R.DFSTreeData[TreeID].ParentTreeID = SubtreeClasses[RI->ParentNodeID];
1144 R.DFSTreeData[TreeID].SubInstrCount = RI->SubInstrCount;
1150 R.SubtreeConnections.resize(SubtreeClasses.
getNumClasses());
1151 R.SubtreeConnectLevels.resize(SubtreeClasses.
getNumClasses());
1153 for (
unsigned Idx = 0, End = R.DFSNodeData.size(); Idx != End; ++Idx) {
1154 R.DFSNodeData[Idx].SubtreeID = SubtreeClasses[Idx];
1155 DEBUG(
dbgs() <<
" SU(" << Idx <<
") in tree "
1156 << R.DFSNodeData[Idx].SubtreeID <<
'\n');
1158 for (std::vector<std::pair<const SUnit*, const SUnit*> >::const_iterator
1159 I = ConnectionPairs.begin(), E = ConnectionPairs.end();
1161 unsigned PredTree = SubtreeClasses[
I->first->NodeNum];
1162 unsigned SuccTree = SubtreeClasses[
I->second->NodeNum];
1163 if (PredTree == SuccTree)
1165 unsigned Depth =
I->first->getDepth();
1175 bool CheckLimit =
true) {
1180 unsigned PredNum = PredSU->
NodeNum;
1181 if (R.DFSNodeData[PredNum].SubtreeID != PredNum)
1186 unsigned NumDataSucs = 0;
1188 SE = PredSU->Succs.end(); SI != SE; ++SI) {
1190 if (++NumDataSucs >= 4)
1194 if (CheckLimit && R.DFSNodeData[PredNum].InstrCount > R.SubtreeLimit)
1196 R.DFSNodeData[PredNum].SubtreeID = Succ->
NodeNum;
1208 R.SubtreeConnections[FromTree];
1210 I = Connections.
begin(), E = Connections.
end();
I != E; ++
I) {
1211 if (
I->TreeID == ToTree) {
1212 I->Level = std::max(
I->Level, Depth);
1216 Connections.
push_back(SchedDFSResult::Connection(ToTree, Depth));
1217 FromTree = R.DFSTreeData[FromTree].ParentTreeID;
1218 }
while (FromTree != SchedDFSResult::InvalidSubtreeID);
1225 class SchedDAGReverseDFS {
1226 std::vector<std::pair<const SUnit*, SUnit::const_pred_iterator> >
DFSStack;
1228 bool isComplete()
const {
return DFSStack.empty(); }
1230 void follow(
const SUnit *SU) {
1235 const SDep *backtrack() {
1240 const SUnit *getCurr()
const {
return DFSStack.back().first; }
1245 return getCurr()->Preds.end();
1252 SI = SU->
Succs.begin(), SE = SU->
Succs.end(); SI != SE; ++SI) {
1253 if (SI->getKind() ==
SDep::Data && !SI->getSUnit()->isBoundaryNode())
1267 SI = SUnits.
begin(), SE = SUnits.
end(); SI != SE; ++SI) {
1268 const SUnit *SU = &*SI;
1272 SchedDAGReverseDFS DFS;
1277 while (DFS.getPred() != DFS.getPredEnd()) {
1278 const SDep &PredDep = *DFS.getPred();
1294 const SUnit *Child = DFS.getCurr();
1295 const SDep *PredDep = DFS.backtrack();
1299 if (DFS.isComplete())
1311 I = SubtreeConnections[SubtreeID].
begin(),
1312 E = SubtreeConnections[SubtreeID].
end();
I != E; ++
I) {
1313 SubtreeConnectLevels[
I->TreeID] =
1314 std::max(SubtreeConnectLevels[
I->TreeID],
I->Level);
1316 <<
" @" << SubtreeConnectLevels[
I->TreeID] <<
'\n');
1320 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1330 dbgs() << *
this <<
'\n';
1341 #endif // !NDEBUG || LLVM_ENABLE_DUMP
VectorType::iterator iterator
SmallVector< PointerIntPair< const Value *, 1, bool >, 4 > UnderlyingObjectsVector
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
virtual void finishBlock()
finishBlock - Clean up after scheduling in the given block.
bool joinPredSubtree(const SDep &PredDep, const SUnit *Succ, bool CheckLimit=true)
SlotIndex def
The index of the defining instruction.
void GetUnderlyingObjects(Value *V, SmallVectorImpl< Value * > &Objects, const DataLayout *TD=0, unsigned MaxLookup=6)
iterator insert(const ValueT &Val)
bool isSucc(SUnit *N)
isSucc - Test if node N is a successor of this node.
bool contains(const KeyT &Key) const
Returns true if this set contains an element identified by Key.
void init(unsigned N)
Initialize an array of N PressureDiffs.
std::pair< iterator, bool > insert(const ValueT &Val)
void addVRegDefDeps(SUnit *SU, unsigned OperIdx)
unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx, const MachineInstr *DepMI) const
Output dependency latency of a pair of defs of the same register.
std::vector< unsigned >::const_iterator livein_iterator
bool mayStore(QueryType Type=AnyInBundle) const
MachineInstr * getInstr() const
SlotIndex getInstructionIndex(const MachineInstr *instr) const
Returns the base index of the given instruction.
Represent the ILP of the subDAG rooted at a DAG node.
TargetSchedModel SchedModel
TargetSchedModel provides an interface to the machine model.
void init(const MCSchedModel &sm, const TargetSubtargetInfo *sti, const TargetInstrInfo *tii)
Initialize the machine model for instruction scheduling.
bool hasOrderedMemoryRef() const
bool CanHandleTerminators
MachineBasicBlock::iterator begin() const
begin - Return an iterator to the top of the current scheduling region.
const_iterator begin(StringRef path)
Get begin iterator over path.
const MCSchedModel * getSchedModel() const
bool registerDefIsDead(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const
virtual std::string getDAGName() const
Return a label for the region of code covered by the DAG.
Kind
Kind - These are the different kinds of scheduling dependencies.
unsigned NumRegionInstrs
Instructions in this region (distance(RegionBegin, RegionEnd)).
void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx)
RangePair equal_range(const KeyT &K)
bool isTerminator(QueryType Type=AnyInBundle) const
SmallVector< SDep, 4 > Preds
virtual void startBlock(MachineBasicBlock *BB)
startBlock - Prepare to perform scheduling in the given block.
static unsigned iterateChainSucc(AliasAnalysis *AA, const MachineFrameInfo *MFI, SUnit *SUa, SUnit *SUb, SUnit *ExitSU, unsigned *Depth, SmallPtrSet< const SUnit *, 16 > &Visited)
MachineBasicBlock::const_iterator getPos() const
Get the MI position corresponding to this register pressure.
static void getUnderlyingObjects(const Value *V, SmallVectorImpl< Value * > &Objects)
A register anti-dependedence (aka WAR).
iterator_base< SparseMultiSet * > iterator
unsigned getNumSubtrees() const
The number of subtrees detected in this DAG.
std::vector< SUnit * > PendingLoads
unsigned getNumVirtRegs() const
static error_code advance(T &it, size_t Val)
MachineBasicBlock::iterator RegionEnd
The end of the range to be scheduled.
DenseMap< MachineInstr *, SUnit * > MISUnitMap
void addSchedBarrierDeps()
An individual mapping from virtual register number to SUnit.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
void setInstr(MachineInstr *MI)
#define llvm_unreachable(msg)
static bool hasDataSucc(const SUnit *SU)
virtual void dumpNode(const SUnit *SU) const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Regular data dependence (aka true-dependence).
const_iterator end() const
bool mayLoad(QueryType Type=AnyInBundle) const
std::vector< MachineBasicBlock * >::iterator succ_iterator
static bool isUnsafeMemoryObject(MachineInstr *MI, const MachineFrameInfo *MFI)
Abstract Stack Frame Information.
std::vector< std::pair< BlockT *, SuccIterTy > > DFSStack
const MachineFrameInfo * MFI
unsigned getNumOperands() const
bool isIdentifiedObject(const Value *V)
bool recede(SmallVectorImpl< unsigned > *LiveUses=0, PressureDiff *PDiff=0)
Recede across the previous instruction.
format_object1< T > format(const char *Fmt, const T &Val)
Compute the values of each DAG node for various metrics during DFS.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
A register output-dependence (aka WAW).
const MDNode * getTBAAInfo() const
getTBAAInfo - Return the TBAA tag for the memory reference.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
MachineBasicBlock::iterator RegionBegin
The beginning of the range to be scheduled.
void addVRegUseDeps(SUnit *SU, unsigned OperIdx)
bool isPred(SUnit *N)
isPred - Test if node N is a predecessor of this node.
virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const
bool IsPostRA
isPostRA flag indicates vregs cannot be present.
virtual void enterRegion(MachineBasicBlock *bb, MachineBasicBlock::iterator begin, MachineBasicBlock::iterator end, unsigned regioninstrs)
Initialize the scheduler state for the next scheduling region.
void visitPostorderNode(const SUnit *SU)
iterator find(const KeyT &Key)
void visitPreorder(const SUnit *SU)
iterator erase(iterator I)
static bool MIsNeedChainEdge(AliasAnalysis *AA, const MachineFrameInfo *MFI, MachineInstr *MIa, MachineInstr *MIb)
bool isDebugValue() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
LiveQueryResult Query(SlotIndex Idx) const
ScheduleDAGInstrs(MachineFunction &mf, const MachineLoopInfo &mli, const MachineDominatorTree &mdt, bool IsPostRAFlag, LiveIntervals *LIS=0)
void clearDAG()
clearDAG - clear the DAG state (between regions).
virtual AliasResult alias(const Location &LocA, const Location &LocB)
void visitCrossEdge(const SDep &PredDep, const SUnit *Succ)
Add a connection for cross edges.
Internal state used to compute SchedDFSResult.
static void getUnderlyingObjectsForInstr(const MachineInstr *MI, const MachineFrameInfo *MFI, UnderlyingObjectsVector &Objects)
const MachineOperand & getOperand(unsigned i) const
void addConnection(unsigned FromTree, unsigned ToTree, unsigned Depth)
Called by finalize() to record a connection between trees.
void setUniverse(unsigned U)
bool hasOneMemOperand() const
bool hasUnmodeledSideEffects() const
VReg2SUnitMap VRegDefs
Track the last instruction in this region defining each virtual register.
virtual void exitRegion()
Notify that the scheduler has finished scheduling the current region.
void setUniverse(unsigned U)
bool isInvariantLoad(AliasAnalysis *AA) const
Location - A description of a memory location.
succ_iterator succ_begin()
void join(unsigned a, unsigned b)
bool isVisited(const SUnit *SU) const
const_iterator begin() const
static void addChainDependency(AliasAnalysis *AA, const MachineFrameInfo *MFI, SUnit *SUa, SUnit *SUb, std::set< SUnit * > &RejectList, unsigned TrueMemOrderLatency=0, bool isNormalMemory=false)
iterator find(const KeyT &Key)
An unknown scheduling barrier.
std::string getFullName() const
Return a hopefully unique identifier for this block.
void addPhysRegDeps(SUnit *SU, unsigned OperIdx)
bool memoperands_empty() const
static ManagedStatic< LeakDetectorImpl< void > > Objects
static void adjustChainDeps(AliasAnalysis *AA, const MachineFrameInfo *MFI, SUnit *SU, SUnit *ExitSU, std::set< SUnit * > &CheckList, unsigned LatencyToLoad)
const STC & getSubtarget() const
void compute(ArrayRef< SUnit > SUnits)
Compute various metrics for the DAG with given roots.
void eraseAll(const KeyT &K)
Nonvolatile load/Store instructions that may alias.
LiveInterval & getInterval(unsigned Reg)
void print(raw_ostream &OS, const TargetMachine *TM=0, bool SkipOpers=false) const
bool count(const KeyT &Key) const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
const Value * getValue() const
MachineBasicBlock::iterator end() const
end - Return an iterator to the bottom of the current scheduling region.
bool isBoundaryNode() const
Boundary nodes are placeholders for the boundary of the scheduling region.
void visitPostorderEdge(const SDep &PredDep, const SUnit *Succ)
void setLatency(unsigned Lat)
setLatency - Set the latency for this edge.
**iterator erase(iterator I)
unsigned getOpcode() const
SUnit * getSUnit(MachineInstr *MI) const
getSUnit - Return an existing SUnit for this MI, or NULL.
static bool isPhysicalRegister(unsigned Reg)
bool hasOneDef(unsigned RegNo) const
const TargetRegisterInfo * TRI
void print(raw_ostream &OS) const
iterator find(const KeyT &Key)
bool isCall(QueryType Type=AnyInBundle) const
int findRegisterDefOperandIdx(unsigned Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=NULL) const
Kind getKind() const
getKind - Return an enum value representing the kind of the dependence.
const TargetInstrInfo * TII
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx, const MachineInstr *UseMI, unsigned UseOperIdx) const
Compute operand latency based on the available machine model.
unsigned computeInstrLatency(const MachineInstr *MI, bool UseDefaultDefLatency=true) const
Compute the instruction latency based on the available machine model.
unsigned getReg() const
getReg - Returns the register number.
SUnit * newSUnit(MachineInstr *MI)
newSUnit - Creates a new SUnit and return a ptr to it.
bool isCommutable(QueryType Type=IgnoreBundle) const
bool addPred(const SDep &D, bool Required=true)
LLVM Value Representation.
int64_t getOffset() const
virtual std::string getGraphNodeLabel(const SUnit *SU) const
Return a label for a DAG node that points to an instruction.
unsigned getNumClasses() const
SmallVector< SDep, 4 > Succs
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
Arbitrary strong DAG edge (no real dependence).
void scheduleTree(unsigned SubtreeID)
Scheduler callback to update SubtreeConnectLevels when a tree is initially scheduled.
uint64_t getSize() const
getSize - Return the size in bytes of the memory reference.
ItTy prior(ItTy it, Dist n)
MachineInstr * FirstDbgValue
static bool isGlobalMemoryObject(AliasAnalysis *AA, MachineInstr *MI)
MachineBasicBlock * BB
The block in which to insert instructions.
MachineRegisterInfo & MRI
std::vector< SUnit > SUnits
SchedDFSImpl(SchedDFSResult &r)
static const Value * getUnderlyingObjectFromInt(const Value *V)
std::pair< iterator, iterator > RangePair
void buildSchedGraph(AliasAnalysis *AA, RegPressureTracker *RPTracker=0, PressureDiffs *PDiffs=0)
bool isBarrier(QueryType Type=AnyInBundle) const
LiveIntervals * LIS
Live Intervals provides reaching defs in preRA scheduling.
SUnit - Scheduling unit. This is a node in the scheduling DAG.
static cl::opt< bool > EnableAASchedMI("enable-aa-sched-mi", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Enable use of AA during MI GAD construction"))
virtual bool useAA() const
Enable use of alias analysis during code generation (during MI scheduling, DAGCombine, etc.).
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.