[SDAG] Use BatchAAResults for querying alias analysis (AA) results (#123934)

Once we get to SelectionDAG the IR should not be changing anymore, so we
can use BatchAAResults rather than AAResults to cache AA queries.

This should be a NFC change for targets that enable AA during codegen
(such as AArch64), but also give a nice compile-time improvement in some
cases. See:
https://github.com/llvm/llvm-project/pull/123787#issuecomment-2606797041

Note: This follows Nikita's suggestion on #123787.
This commit is contained in:
Benjamin Maxwell 2025-01-23 09:16:09 +00:00 committed by GitHub
parent 4b0df28a68
commit 778138114e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 112 additions and 76 deletions

View File

@ -643,6 +643,9 @@ public:
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) { bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) {
return isNoModRef(AA.getModRefInfoMask(Loc, AAQI, OrLocal)); return isNoModRef(AA.getModRefInfoMask(Loc, AAQI, OrLocal));
} }
bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
return pointsToConstantMemory(MemoryLocation::getBeforeOrAfter(P), OrLocal);
}
ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
bool IgnoreLocals = false) { bool IgnoreLocals = false) {
return AA.getModRefInfoMask(Loc, AAQI, IgnoreLocals); return AA.getModRefInfoMask(Loc, AAQI, IgnoreLocals);
@ -668,6 +671,9 @@ public:
MemoryLocation(V2, LocationSize::precise(1))) == MemoryLocation(V2, LocationSize::precise(1))) ==
AliasResult::MustAlias; AliasResult::MustAlias;
} }
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
return alias(LocA, LocB) == AliasResult::NoAlias;
}
ModRefInfo callCapturesBefore(const Instruction *I, ModRefInfo callCapturesBefore(const Instruction *I,
const MemoryLocation &MemLoc, const MemoryLocation &MemLoc,
DominatorTree *DT) { DominatorTree *DT) {

View File

@ -42,6 +42,7 @@ class DILabel;
class Instruction; class Instruction;
class MDNode; class MDNode;
class AAResults; class AAResults;
class BatchAAResults;
template <typename T> class ArrayRef; template <typename T> class ArrayRef;
class DIExpression; class DIExpression;
class DILocalVariable; class DILocalVariable;
@ -1753,6 +1754,8 @@ public:
/// @param AA Optional alias analysis, used to compare memory operands. /// @param AA Optional alias analysis, used to compare memory operands.
/// @param Other MachineInstr to check aliasing against. /// @param Other MachineInstr to check aliasing against.
/// @param UseTBAA Whether to pass TBAA information to alias analysis. /// @param UseTBAA Whether to pass TBAA information to alias analysis.
bool mayAlias(BatchAAResults *AA, const MachineInstr &Other,
bool UseTBAA) const;
bool mayAlias(AAResults *AA, const MachineInstr &Other, bool UseTBAA) const; bool mayAlias(AAResults *AA, const MachineInstr &Other, bool UseTBAA) const;
/// Return true if this instruction may have an ordered /// Return true if this instruction may have an ordered

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseMultiSet.h" #include "llvm/ADT/SparseMultiSet.h"
#include "llvm/ADT/identity.h" #include "llvm/ADT/identity.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveRegUnits.h" #include "llvm/CodeGen/LiveRegUnits.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/ScheduleDAG.h"
@ -169,7 +170,7 @@ namespace llvm {
/// Tracks the last instructions in this region using each virtual register. /// Tracks the last instructions in this region using each virtual register.
VReg2SUnitOperIdxMultiMap CurrentVRegUses; VReg2SUnitOperIdxMultiMap CurrentVRegUses;
AAResults *AAForDep = nullptr; mutable std::optional<BatchAAResults> AAForDep;
/// Remember a generic side-effecting instruction as we proceed. /// Remember a generic side-effecting instruction as we proceed.
/// No other SU ever gets scheduled around it (except in the special /// No other SU ever gets scheduled around it (except in the special
@ -201,6 +202,13 @@ namespace llvm {
/// a means of remembering which SUs depend on which memory locations. /// a means of remembering which SUs depend on which memory locations.
class Value2SUsMap; class Value2SUsMap;
/// Returns a (possibly null) pointer to the current BatchAAResults.
BatchAAResults *getAAForDep() const {
if (AAForDep.has_value())
return &AAForDep.value();
return nullptr;
}
/// Reduces maps in FIFO order, by N SUs. This is better than turning /// Reduces maps in FIFO order, by N SUs. This is better than turning
/// every Nth memory SU into BarrierChain in buildSchedGraph(), since /// every Nth memory SU into BarrierChain in buildSchedGraph(), since
/// it avoids unnecessary edges between seen SUs above the new BarrierChain, /// it avoids unnecessary edges between seen SUs above the new BarrierChain,

View File

@ -61,7 +61,7 @@ class Type;
template <class GraphType> struct GraphTraits; template <class GraphType> struct GraphTraits;
template <typename T, unsigned int N> class SmallSetVector; template <typename T, unsigned int N> class SmallSetVector;
template <typename T, typename Enable> struct FoldingSetTrait; template <typename T, typename Enable> struct FoldingSetTrait;
class AAResults; class BatchAAResults;
class BlockAddress; class BlockAddress;
class BlockFrequencyInfo; class BlockFrequencyInfo;
class Constant; class Constant;
@ -602,7 +602,8 @@ public:
/// certain types of nodes together, or eliminating superfluous nodes. The /// certain types of nodes together, or eliminating superfluous nodes. The
/// Level argument controls whether Combine is allowed to produce nodes and /// Level argument controls whether Combine is allowed to produce nodes and
/// types that are illegal on the target. /// types that are illegal on the target.
void Combine(CombineLevel Level, AAResults *AA, CodeGenOptLevel OptLevel); void Combine(CombineLevel Level, BatchAAResults *BatchAA,
CodeGenOptLevel OptLevel);
/// This transforms the SelectionDAG into a SelectionDAG that /// This transforms the SelectionDAG into a SelectionDAG that
/// only uses types natively supported by the target. /// only uses types natively supported by the target.
@ -1202,12 +1203,14 @@ public:
/* \p CI if not null is the memset call being lowered. /* \p CI if not null is the memset call being lowered.
* \p OverrideTailCall is an optional parameter that can be used to override * \p OverrideTailCall is an optional parameter that can be used to override
* the tail call optimization decision. */ * the tail call optimization decision. */
SDValue SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src,
getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol,
SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool AlwaysInline, const CallInst *CI,
const CallInst *CI, std::optional<bool> OverrideTailCall, std::optional<bool> OverrideTailCall,
MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, MachinePointerInfo DstPtrInfo,
const AAMDNodes &AAInfo = AAMDNodes(), AAResults *AA = nullptr); MachinePointerInfo SrcPtrInfo,
const AAMDNodes &AAInfo = AAMDNodes(),
BatchAAResults *BatchAA = nullptr);
/* \p CI if not null is the memset call being lowered. /* \p CI if not null is the memset call being lowered.
* \p OverrideTailCall is an optional parameter that can be used to override * \p OverrideTailCall is an optional parameter that can be used to override
@ -1218,7 +1221,7 @@ public:
MachinePointerInfo DstPtrInfo, MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo, MachinePointerInfo SrcPtrInfo,
const AAMDNodes &AAInfo = AAMDNodes(), const AAMDNodes &AAInfo = AAMDNodes(),
AAResults *AA = nullptr); BatchAAResults *BatchAA = nullptr);
SDValue getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src,
SDValue Size, Align Alignment, bool isVol, SDValue Size, Align Alignment, bool isVol,

View File

@ -14,6 +14,7 @@
#ifndef LLVM_CODEGEN_SELECTIONDAGISEL_H #ifndef LLVM_CODEGEN_SELECTIONDAGISEL_H
#define LLVM_CODEGEN_SELECTIONDAGISEL_H #define LLVM_CODEGEN_SELECTIONDAGISEL_H
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachinePassManager.h" #include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAG.h"
@ -52,7 +53,7 @@ public:
MachineRegisterInfo *RegInfo; MachineRegisterInfo *RegInfo;
SelectionDAG *CurDAG; SelectionDAG *CurDAG;
std::unique_ptr<SelectionDAGBuilder> SDB; std::unique_ptr<SelectionDAGBuilder> SDB;
AAResults *AA = nullptr; mutable std::optional<BatchAAResults> BatchAA;
AssumptionCache *AC = nullptr; AssumptionCache *AC = nullptr;
GCFunctionInfo *GFI = nullptr; GCFunctionInfo *GFI = nullptr;
SSPLayoutInfo *SP = nullptr; SSPLayoutInfo *SP = nullptr;
@ -81,6 +82,13 @@ public:
CodeGenOptLevel OL = CodeGenOptLevel::Default); CodeGenOptLevel OL = CodeGenOptLevel::Default);
virtual ~SelectionDAGISel(); virtual ~SelectionDAGISel();
/// Returns a (possibly null) pointer to the current BatchAAResults.
BatchAAResults *getBatchAA() const {
if (BatchAA.has_value())
return &BatchAA.value();
return nullptr;
}
const TargetLowering *getTargetLowering() const { return TLI; } const TargetLowering *getTargetLowering() const { return TLI; }
void initializeAnalysisResults(MachineFunctionAnalysisManager &MFAM); void initializeAnalysisResults(MachineFunctionAnalysisManager &MFAM);

View File

@ -1350,8 +1350,9 @@ bool MachineInstr::wouldBeTriviallyDead() const {
return isPHI() || isSafeToMove(SawStore); return isPHI() || isSafeToMove(SawStore);
} }
static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA, static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI,
bool UseTBAA, const MachineMemOperand *MMOa, BatchAAResults *AA, bool UseTBAA,
const MachineMemOperand *MMOa,
const MachineMemOperand *MMOb) { const MachineMemOperand *MMOb) {
// The following interface to AA is fashioned after DAGCombiner::isAlias and // The following interface to AA is fashioned after DAGCombiner::isAlias and
// operates with MachineMemOperand offset with some important assumptions: // operates with MachineMemOperand offset with some important assumptions:
@ -1434,7 +1435,7 @@ static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
MemoryLocation(ValB, LocB, UseTBAA ? MMOb->getAAInfo() : AAMDNodes())); MemoryLocation(ValB, LocB, UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
} }
bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other, bool MachineInstr::mayAlias(BatchAAResults *AA, const MachineInstr &Other,
bool UseTBAA) const { bool UseTBAA) const {
const MachineFunction *MF = getMF(); const MachineFunction *MF = getMF();
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
@ -1478,6 +1479,15 @@ bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
return false; return false;
} }
bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
bool UseTBAA) const {
if (AA) {
BatchAAResults BAA(*AA);
return mayAlias(&BAA, Other, UseTBAA);
}
return mayAlias(static_cast<BatchAAResults *>(nullptr), Other, UseTBAA);
}
/// hasOrderedMemoryRef - Return true if this instruction may have an ordered /// hasOrderedMemoryRef - Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory /// or volatile memory reference, or if the information describing the memory
/// reference is not available. Return false if it is known to have no ordered /// reference is not available. Return false if it is known to have no ordered

View File

@ -551,7 +551,7 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
void ScheduleDAGInstrs::addChainDependency (SUnit *SUa, SUnit *SUb, void ScheduleDAGInstrs::addChainDependency (SUnit *SUa, SUnit *SUb,
unsigned Latency) { unsigned Latency) {
if (SUa->getInstr()->mayAlias(AAForDep, *SUb->getInstr(), UseTBAA)) { if (SUa->getInstr()->mayAlias(getAAForDep(), *SUb->getInstr(), UseTBAA)) {
SDep Dep(SUa, SDep::MayAliasMem); SDep Dep(SUa, SDep::MayAliasMem);
Dep.setLatency(Latency); Dep.setLatency(Latency);
SUb->addPred(Dep); SUb->addPred(Dep);
@ -740,7 +740,8 @@ void ScheduleDAGInstrs::buildSchedGraph(AAResults *AA,
const TargetSubtargetInfo &ST = MF.getSubtarget(); const TargetSubtargetInfo &ST = MF.getSubtarget();
bool UseAA = EnableAASchedMI.getNumOccurrences() > 0 ? EnableAASchedMI bool UseAA = EnableAASchedMI.getNumOccurrences() > 0 ? EnableAASchedMI
: ST.useAA(); : ST.useAA();
AAForDep = UseAA ? AA : nullptr; if (UseAA && AA)
AAForDep.emplace(*AA);
BarrierChain = nullptr; BarrierChain = nullptr;

View File

@ -191,8 +191,8 @@ namespace {
/// candidate again. /// candidate again.
DenseMap<SDNode *, std::pair<SDNode *, unsigned>> StoreRootCountMap; DenseMap<SDNode *, std::pair<SDNode *, unsigned>> StoreRootCountMap;
// AA - Used for DAG load/store alias analysis. // BatchAA - Used for DAG load/store alias analysis.
AliasAnalysis *AA; BatchAAResults *BatchAA;
/// This caches all chains that have already been processed in /// This caches all chains that have already been processed in
/// DAGCombiner::getStoreMergeCandidates() and found to have no mergeable /// DAGCombiner::getStoreMergeCandidates() and found to have no mergeable
@ -247,9 +247,10 @@ namespace {
SDValue visit(SDNode *N); SDValue visit(SDNode *N);
public: public:
DAGCombiner(SelectionDAG &D, AliasAnalysis *AA, CodeGenOptLevel OL) DAGCombiner(SelectionDAG &D, BatchAAResults *BatchAA, CodeGenOptLevel OL)
: DAG(D), TLI(D.getTargetLoweringInfo()), : DAG(D), TLI(D.getTargetLoweringInfo()),
STI(D.getSubtarget().getSelectionDAGInfo()), OptLevel(OL), AA(AA) { STI(D.getSubtarget().getSelectionDAGInfo()), OptLevel(OL),
BatchAA(BatchAA) {
ForCodeSize = DAG.shouldOptForSize(); ForCodeSize = DAG.shouldOptForSize();
DisableGenericCombines = STI && STI->disableGenericCombines(OptLevel); DisableGenericCombines = STI && STI->disableGenericCombines(OptLevel);
@ -28918,7 +28919,7 @@ bool DAGCombiner::mayAlias(SDNode *Op0, SDNode *Op1) const {
UseAA = false; UseAA = false;
#endif #endif
if (UseAA && AA && MUC0.MMO->getValue() && MUC1.MMO->getValue() && if (UseAA && BatchAA && MUC0.MMO->getValue() && MUC1.MMO->getValue() &&
Size0.hasValue() && Size1.hasValue() && Size0.hasValue() && Size1.hasValue() &&
// Can't represent a scalable size + fixed offset in LocationSize // Can't represent a scalable size + fixed offset in LocationSize
(!Size0.isScalable() || SrcValOffset0 == 0) && (!Size0.isScalable() || SrcValOffset0 == 0) &&
@ -28933,7 +28934,7 @@ bool DAGCombiner::mayAlias(SDNode *Op0, SDNode *Op1) const {
Size0.isScalable() ? Size0 : LocationSize::precise(Overlap0); Size0.isScalable() ? Size0 : LocationSize::precise(Overlap0);
LocationSize Loc1 = LocationSize Loc1 =
Size1.isScalable() ? Size1 : LocationSize::precise(Overlap1); Size1.isScalable() ? Size1 : LocationSize::precise(Overlap1);
if (AA->isNoAlias( if (BatchAA->isNoAlias(
MemoryLocation(MUC0.MMO->getValue(), Loc0, MemoryLocation(MUC0.MMO->getValue(), Loc0,
UseTBAA ? MUC0.MMO->getAAInfo() : AAMDNodes()), UseTBAA ? MUC0.MMO->getAAInfo() : AAMDNodes()),
MemoryLocation(MUC1.MMO->getValue(), Loc1, MemoryLocation(MUC1.MMO->getValue(), Loc1,
@ -29239,8 +29240,8 @@ bool DAGCombiner::findBetterNeighborChains(StoreSDNode *St) {
} }
/// This is the entry point for the file. /// This is the entry point for the file.
void SelectionDAG::Combine(CombineLevel Level, AliasAnalysis *AA, void SelectionDAG::Combine(CombineLevel Level, BatchAAResults *BatchAA,
CodeGenOptLevel OptLevel) { CodeGenOptLevel OptLevel) {
/// This is the main entry point to this class. /// This is the main entry point to this class.
DAGCombiner(*this, AA, OptLevel).Run(Level); DAGCombiner(*this, BatchAA, OptLevel).Run(Level);
} }

View File

@ -118,7 +118,7 @@ void ScheduleDAGFast::Schedule() {
LiveRegCycles.resize(TRI->getNumRegs(), 0); LiveRegCycles.resize(TRI->getNumRegs(), 0);
// Build the scheduling graph. // Build the scheduling graph.
BuildSchedGraph(nullptr); BuildSchedGraph();
LLVM_DEBUG(dump()); LLVM_DEBUG(dump());

View File

@ -370,7 +370,7 @@ void ScheduleDAGRRList::Schedule() {
assert(Interferences.empty() && LRegsMap.empty() && "stale Interferences"); assert(Interferences.empty() && LRegsMap.empty() && "stale Interferences");
// Build the scheduling graph. // Build the scheduling graph.
BuildSchedGraph(nullptr); BuildSchedGraph();
LLVM_DEBUG(dump()); LLVM_DEBUG(dump());
Topo.MarkDirty(); Topo.MarkDirty();

View File

@ -536,7 +536,7 @@ void ScheduleDAGSDNodes::AddSchedEdges() {
/// are input. This SUnit graph is similar to the SelectionDAG, but /// are input. This SUnit graph is similar to the SelectionDAG, but
/// excludes nodes that aren't interesting to scheduling, and represents /// excludes nodes that aren't interesting to scheduling, and represents
/// glued together nodes with a single SUnit. /// glued together nodes with a single SUnit.
void ScheduleDAGSDNodes::BuildSchedGraph(AAResults *AA) { void ScheduleDAGSDNodes::BuildSchedGraph() {
// Cluster certain nodes which should be scheduled together. // Cluster certain nodes which should be scheduled together.
ClusterNodes(); ClusterNodes();
// Populate the SUnits array. // Populate the SUnits array.

View File

@ -94,7 +94,7 @@ class InstrItineraryData;
/// are input. This SUnit graph is similar to the SelectionDAG, but /// are input. This SUnit graph is similar to the SelectionDAG, but
/// excludes nodes that aren't interesting to scheduling, and represents /// excludes nodes that aren't interesting to scheduling, and represents
/// flagged together nodes with a single SUnit. /// flagged together nodes with a single SUnit.
void BuildSchedGraph(AAResults *AA); void BuildSchedGraph();
/// InitNumRegDefsLeft - Determine the # of regs defined by this node. /// InitNumRegDefsLeft - Determine the # of regs defined by this node.
/// ///

View File

@ -59,14 +59,10 @@ private:
/// HazardRec - The hazard recognizer to use. /// HazardRec - The hazard recognizer to use.
ScheduleHazardRecognizer *HazardRec; ScheduleHazardRecognizer *HazardRec;
/// AA - AAResults for making memory reference queries.
AAResults *AA;
public: public:
ScheduleDAGVLIW(MachineFunction &mf, AAResults *aa, ScheduleDAGVLIW(MachineFunction &MF, SchedulingPriorityQueue *AvailableQueue)
SchedulingPriorityQueue *availqueue) : ScheduleDAGSDNodes(MF), AvailableQueue(AvailableQueue) {
: ScheduleDAGSDNodes(mf), AvailableQueue(availqueue), AA(aa) { const TargetSubtargetInfo &STI = MF.getSubtarget();
const TargetSubtargetInfo &STI = mf.getSubtarget();
HazardRec = STI.getInstrInfo()->CreateTargetHazardRecognizer(&STI, this); HazardRec = STI.getInstrInfo()->CreateTargetHazardRecognizer(&STI, this);
} }
@ -91,7 +87,7 @@ void ScheduleDAGVLIW::Schedule() {
<< " '" << BB->getName() << "' **********\n"); << " '" << BB->getName() << "' **********\n");
// Build the scheduling graph. // Build the scheduling graph.
BuildSchedGraph(AA); BuildSchedGraph();
AvailableQueue->initNodes(SUnits); AvailableQueue->initNodes(SUnits);
@ -267,5 +263,5 @@ void ScheduleDAGVLIW::listScheduleTopDown() {
/// createVLIWDAGScheduler - This creates a top-down list scheduler. /// createVLIWDAGScheduler - This creates a top-down list scheduler.
ScheduleDAGSDNodes *llvm::createVLIWDAGScheduler(SelectionDAGISel *IS, ScheduleDAGSDNodes *llvm::createVLIWDAGScheduler(SelectionDAGISel *IS,
CodeGenOptLevel) { CodeGenOptLevel) {
return new ScheduleDAGVLIW(*IS->MF, IS->AA, new ResourcePriorityQueue(IS)); return new ScheduleDAGVLIW(*IS->MF, new ResourcePriorityQueue(IS));
} }

View File

@ -8126,13 +8126,11 @@ static void chainLoadsAndStoresForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
} }
} }
static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, static SDValue getMemcpyLoadsAndStores(
SDValue Chain, SDValue Dst, SDValue Src, SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
uint64_t Size, Align Alignment, uint64_t Size, Align Alignment, bool isVol, bool AlwaysInline,
bool isVol, bool AlwaysInline, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo,
MachinePointerInfo DstPtrInfo, const AAMDNodes &AAInfo, BatchAAResults *BatchAA) {
MachinePointerInfo SrcPtrInfo,
const AAMDNodes &AAInfo, AAResults *AA) {
// Turn a memcpy of undef to nop. // Turn a memcpy of undef to nop.
// FIXME: We need to honor volatile even is Src is undef. // FIXME: We need to honor volatile even is Src is undef.
if (Src.isUndef()) if (Src.isUndef())
@ -8198,8 +8196,8 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
const Value *SrcVal = dyn_cast_if_present<const Value *>(SrcPtrInfo.V); const Value *SrcVal = dyn_cast_if_present<const Value *>(SrcPtrInfo.V);
bool isConstant = bool isConstant =
AA && SrcVal && BatchAA && SrcVal &&
AA->pointsToConstantMemory(MemoryLocation(SrcVal, Size, AAInfo)); BatchAA->pointsToConstantMemory(MemoryLocation(SrcVal, Size, AAInfo));
MachineMemOperand::Flags MMOFlags = MachineMemOperand::Flags MMOFlags =
isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone; isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone;
@ -8584,7 +8582,8 @@ SDValue SelectionDAG::getMemcpy(
SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size,
Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI,
std::optional<bool> OverrideTailCall, MachinePointerInfo DstPtrInfo, std::optional<bool> OverrideTailCall, MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo, AAResults *AA) { MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo,
BatchAAResults *BatchAA) {
// Check to see if we should lower the memcpy to loads and stores first. // Check to see if we should lower the memcpy to loads and stores first.
// For cases within the target-specified limits, this is the best choice. // For cases within the target-specified limits, this is the best choice.
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size); ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
@ -8595,7 +8594,7 @@ SDValue SelectionDAG::getMemcpy(
SDValue Result = getMemcpyLoadsAndStores( SDValue Result = getMemcpyLoadsAndStores(
*this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(), Alignment, *this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(), Alignment,
isVol, false, DstPtrInfo, SrcPtrInfo, AAInfo, AA); isVol, false, DstPtrInfo, SrcPtrInfo, AAInfo, BatchAA);
if (Result.getNode()) if (Result.getNode())
return Result; return Result;
} }
@ -8616,7 +8615,7 @@ SDValue SelectionDAG::getMemcpy(
assert(ConstantSize && "AlwaysInline requires a constant size!"); assert(ConstantSize && "AlwaysInline requires a constant size!");
return getMemcpyLoadsAndStores( return getMemcpyLoadsAndStores(
*this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(), Alignment, *this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(), Alignment,
isVol, true, DstPtrInfo, SrcPtrInfo, AAInfo, AA); isVol, true, DstPtrInfo, SrcPtrInfo, AAInfo, BatchAA);
} }
checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace()); checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace());
@ -8711,7 +8710,8 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst,
std::optional<bool> OverrideTailCall, std::optional<bool> OverrideTailCall,
MachinePointerInfo DstPtrInfo, MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo, MachinePointerInfo SrcPtrInfo,
const AAMDNodes &AAInfo, AAResults *AA) { const AAMDNodes &AAInfo,
BatchAAResults *BatchAA) {
// Check to see if we should lower the memmove to loads and stores first. // Check to see if we should lower the memmove to loads and stores first.
// For cases within the target-specified limits, this is the best choice. // For cases within the target-specified limits, this is the best choice.
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size); ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);

View File

@ -1082,10 +1082,10 @@ RegsForValue::getRegsAndSizes() const {
return OutVec; return OutVec;
} }
void SelectionDAGBuilder::init(GCFunctionInfo *gfi, AliasAnalysis *aa, void SelectionDAGBuilder::init(GCFunctionInfo *gfi, BatchAAResults *aa,
AssumptionCache *ac, AssumptionCache *ac,
const TargetLibraryInfo *li) { const TargetLibraryInfo *li) {
AA = aa; BatchAA = aa;
AC = ac; AC = ac;
GFI = gfi; GFI = gfi;
LibInfo = li; LibInfo = li;
@ -4585,8 +4585,8 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
Root = getRoot(); Root = getRoot();
else if (NumValues > MaxParallelChains) else if (NumValues > MaxParallelChains)
Root = getMemoryRoot(); Root = getMemoryRoot();
else if (AA && else if (BatchAA &&
AA->pointsToConstantMemory(MemoryLocation( BatchAA->pointsToConstantMemory(MemoryLocation(
SV, SV,
LocationSize::precise(DAG.getDataLayout().getTypeStoreSize(Ty)), LocationSize::precise(DAG.getDataLayout().getTypeStoreSize(Ty)),
AAInfo))) { AAInfo))) {
@ -4688,8 +4688,8 @@ void SelectionDAGBuilder::visitLoadFromSwiftError(const LoadInst &I) {
const Value *SV = I.getOperand(0); const Value *SV = I.getOperand(0);
Type *Ty = I.getType(); Type *Ty = I.getType();
assert( assert(
(!AA || (!BatchAA ||
!AA->pointsToConstantMemory(MemoryLocation( !BatchAA->pointsToConstantMemory(MemoryLocation(
SV, LocationSize::precise(DAG.getDataLayout().getTypeStoreSize(Ty)), SV, LocationSize::precise(DAG.getDataLayout().getTypeStoreSize(Ty)),
I.getAAMetadata()))) && I.getAAMetadata()))) &&
"load_from_swift_error should not be constant memory"); "load_from_swift_error should not be constant memory");
@ -4998,7 +4998,7 @@ void SelectionDAGBuilder::visitMaskedLoad(const CallInst &I, bool IsExpanding) {
// Do not serialize masked loads of constant memory with anything. // Do not serialize masked loads of constant memory with anything.
MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo); MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo);
bool AddToChain = !AA || !AA->pointsToConstantMemory(ML); bool AddToChain = !BatchAA || !BatchAA->pointsToConstantMemory(ML);
SDValue InChain = AddToChain ? DAG.getRoot() : DAG.getEntryNode(); SDValue InChain = AddToChain ? DAG.getRoot() : DAG.getEntryNode();
@ -6534,7 +6534,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
/* AlwaysInline */ false, &I, std::nullopt, /* AlwaysInline */ false, &I, std::nullopt,
MachinePointerInfo(I.getArgOperand(0)), MachinePointerInfo(I.getArgOperand(0)),
MachinePointerInfo(I.getArgOperand(1)), MachinePointerInfo(I.getArgOperand(1)),
I.getAAMetadata(), AA); I.getAAMetadata(), BatchAA);
updateDAGForMaybeTailCall(MC); updateDAGForMaybeTailCall(MC);
return; return;
} }
@ -6555,7 +6555,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
/* AlwaysInline */ true, &I, std::nullopt, /* AlwaysInline */ true, &I, std::nullopt,
MachinePointerInfo(I.getArgOperand(0)), MachinePointerInfo(I.getArgOperand(0)),
MachinePointerInfo(I.getArgOperand(1)), MachinePointerInfo(I.getArgOperand(1)),
I.getAAMetadata(), AA); I.getAAMetadata(), BatchAA);
updateDAGForMaybeTailCall(MC); updateDAGForMaybeTailCall(MC);
return; return;
} }
@ -6608,7 +6608,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
/* OverrideTailCall */ std::nullopt, /* OverrideTailCall */ std::nullopt,
MachinePointerInfo(I.getArgOperand(0)), MachinePointerInfo(I.getArgOperand(0)),
MachinePointerInfo(I.getArgOperand(1)), MachinePointerInfo(I.getArgOperand(1)),
I.getAAMetadata(), AA); I.getAAMetadata(), BatchAA);
updateDAGForMaybeTailCall(MM); updateDAGForMaybeTailCall(MM);
return; return;
} }
@ -8435,7 +8435,7 @@ void SelectionDAGBuilder::visitVPLoad(
if (!Alignment) if (!Alignment)
Alignment = DAG.getEVTAlign(VT); Alignment = DAG.getEVTAlign(VT);
MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo); MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo);
bool AddToChain = !AA || !AA->pointsToConstantMemory(ML); bool AddToChain = !BatchAA || !BatchAA->pointsToConstantMemory(ML);
SDValue InChain = AddToChain ? DAG.getRoot() : DAG.getEntryNode(); SDValue InChain = AddToChain ? DAG.getRoot() : DAG.getEntryNode();
MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand( MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
MachinePointerInfo(PtrOperand), MachineMemOperand::MOLoad, MachinePointerInfo(PtrOperand), MachineMemOperand::MOLoad,
@ -8564,7 +8564,7 @@ void SelectionDAGBuilder::visitVPStridedLoad(
AAMDNodes AAInfo = VPIntrin.getAAMetadata(); AAMDNodes AAInfo = VPIntrin.getAAMetadata();
const MDNode *Ranges = getRangeMetadata(VPIntrin); const MDNode *Ranges = getRangeMetadata(VPIntrin);
MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo); MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo);
bool AddToChain = !AA || !AA->pointsToConstantMemory(ML); bool AddToChain = !BatchAA || !BatchAA->pointsToConstantMemory(ML);
SDValue InChain = AddToChain ? DAG.getRoot() : DAG.getEntryNode(); SDValue InChain = AddToChain ? DAG.getRoot() : DAG.getEntryNode();
unsigned AS = PtrOperand->getType()->getPointerAddressSpace(); unsigned AS = PtrOperand->getType()->getPointerAddressSpace();
MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand( MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
@ -9021,7 +9021,7 @@ static SDValue getMemCmpLoad(const Value *PtrVal, MVT LoadVT,
bool ConstantMemory = false; bool ConstantMemory = false;
// Do not serialize (non-volatile) loads of constant memory with anything. // Do not serialize (non-volatile) loads of constant memory with anything.
if (Builder.AA && Builder.AA->pointsToConstantMemory(PtrVal)) { if (Builder.BatchAA && Builder.BatchAA->pointsToConstantMemory(PtrVal)) {
Root = Builder.DAG.getEntryNode(); Root = Builder.DAG.getEntryNode();
ConstantMemory = true; ConstantMemory = true;
} else { } else {

View File

@ -225,7 +225,7 @@ public:
static const unsigned LowestSDNodeOrder = 1; static const unsigned LowestSDNodeOrder = 1;
SelectionDAG &DAG; SelectionDAG &DAG;
AAResults *AA = nullptr; BatchAAResults *BatchAA = nullptr;
AssumptionCache *AC = nullptr; AssumptionCache *AC = nullptr;
const TargetLibraryInfo *LibInfo = nullptr; const TargetLibraryInfo *LibInfo = nullptr;
@ -280,7 +280,7 @@ public:
SL(std::make_unique<SDAGSwitchLowering>(this, funcinfo)), SL(std::make_unique<SDAGSwitchLowering>(this, funcinfo)),
FuncInfo(funcinfo), SwiftError(swifterror) {} FuncInfo(funcinfo), SwiftError(swifterror) {}
void init(GCFunctionInfo *gfi, AAResults *AA, AssumptionCache *AC, void init(GCFunctionInfo *gfi, BatchAAResults *BatchAA, AssumptionCache *AC,
const TargetLibraryInfo *li); const TargetLibraryInfo *li);
/// Clear out the current SelectionDAG and the associated state and prepare /// Clear out the current SelectionDAG and the associated state and prepare

View File

@ -502,9 +502,9 @@ void SelectionDAGISel::initializeAnalysisResults(
FuncInfo->BPI = nullptr; FuncInfo->BPI = nullptr;
if (OptLevel != CodeGenOptLevel::None) if (OptLevel != CodeGenOptLevel::None)
AA = &FAM.getResult<AAManager>(Fn); BatchAA.emplace(FAM.getResult<AAManager>(Fn));
else else
AA = nullptr; BatchAA = std::nullopt;
SP = &FAM.getResult<SSPLayoutAnalysis>(Fn); SP = &FAM.getResult<SSPLayoutAnalysis>(Fn);
@ -560,9 +560,9 @@ void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) {
FuncInfo->BPI = nullptr; FuncInfo->BPI = nullptr;
if (OptLevel != CodeGenOptLevel::None) if (OptLevel != CodeGenOptLevel::None)
AA = &MFP.getAnalysis<AAResultsWrapperPass>().getAAResults(); BatchAA.emplace(MFP.getAnalysis<AAResultsWrapperPass>().getAAResults());
else else
AA = nullptr; BatchAA = std::nullopt;
SP = &MFP.getAnalysis<StackProtector>().getLayoutInfo(); SP = &MFP.getAnalysis<StackProtector>().getLayoutInfo();
@ -581,7 +581,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << '\n'); ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << '\n');
SDB->init(GFI, AA, AC, LibInfo); SDB->init(GFI, getBatchAA(), AC, LibInfo);
MF->setHasInlineAsm(false); MF->setHasInlineAsm(false);
@ -955,7 +955,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
{ {
NamedRegionTimer T("combine1", "DAG Combining 1", GroupName, NamedRegionTimer T("combine1", "DAG Combining 1", GroupName,
GroupDescription, TimePassesIsEnabled); GroupDescription, TimePassesIsEnabled);
CurDAG->Combine(BeforeLegalizeTypes, AA, OptLevel); CurDAG->Combine(BeforeLegalizeTypes, getBatchAA(), OptLevel);
} }
ISEL_DUMP(dbgs() << "\nOptimized lowered selection DAG: " ISEL_DUMP(dbgs() << "\nOptimized lowered selection DAG: "
@ -1001,7 +1001,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
{ {
NamedRegionTimer T("combine_lt", "DAG Combining after legalize types", NamedRegionTimer T("combine_lt", "DAG Combining after legalize types",
GroupName, GroupDescription, TimePassesIsEnabled); GroupName, GroupDescription, TimePassesIsEnabled);
CurDAG->Combine(AfterLegalizeTypes, AA, OptLevel); CurDAG->Combine(AfterLegalizeTypes, getBatchAA(), OptLevel);
} }
ISEL_DUMP(dbgs() << "\nOptimized type-legalized selection DAG: " ISEL_DUMP(dbgs() << "\nOptimized type-legalized selection DAG: "
@ -1055,7 +1055,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
{ {
NamedRegionTimer T("combine_lv", "DAG Combining after legalize vectors", NamedRegionTimer T("combine_lv", "DAG Combining after legalize vectors",
GroupName, GroupDescription, TimePassesIsEnabled); GroupName, GroupDescription, TimePassesIsEnabled);
CurDAG->Combine(AfterLegalizeVectorOps, AA, OptLevel); CurDAG->Combine(AfterLegalizeVectorOps, getBatchAA(), OptLevel);
} }
ISEL_DUMP(dbgs() << "\nOptimized vector-legalized selection DAG: " ISEL_DUMP(dbgs() << "\nOptimized vector-legalized selection DAG: "
@ -1095,7 +1095,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
{ {
NamedRegionTimer T("combine2", "DAG Combining 2", GroupName, NamedRegionTimer T("combine2", "DAG Combining 2", GroupName,
GroupDescription, TimePassesIsEnabled); GroupDescription, TimePassesIsEnabled);
CurDAG->Combine(AfterLegalizeDAG, AA, OptLevel); CurDAG->Combine(AfterLegalizeDAG, getBatchAA(), OptLevel);
} }
ISEL_DUMP(dbgs() << "\nOptimized legalized selection DAG: " ISEL_DUMP(dbgs() << "\nOptimized legalized selection DAG: "

View File

@ -1498,8 +1498,8 @@ bool SystemZDAGToDAGISel::canUseBlockOperation(StoreSDNode *Store,
if (V1 == V2 && End1 == End2) if (V1 == V2 && End1 == End2)
return false; return false;
return AA->isNoAlias(MemoryLocation(V1, End1, Load->getAAInfo()), return BatchAA->isNoAlias(MemoryLocation(V1, End1, Load->getAAInfo()),
MemoryLocation(V2, End2, Store->getAAInfo())); MemoryLocation(V2, End2, Store->getAAInfo()));
} }
bool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *N) const { bool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *N) const {