37#define DEBUG_TYPE "legalizer"
43 cl::desc(
"Should enable CSE in Legalizer"),
48 "allow-ginsert-as-artifact",
49 cl::desc(
"Allow G_INSERT to be considered an artifact. Hack around AMDGPU "
50 "test infinite loops."),
60 "verify-legalizer-debug-locs",
61 cl::desc(
"Verify that debug locations are handled"),
65 "Verify legalizations"),
67 "legalizations+artifactcombiners",
68 "Verify legalizations and artifact combines")),
78 "Legalize the Machine IR a function's Machine IR",
false,
85 "Legalize the Machine IR a function's Machine IR",
false,
102 switch (
MI.getOpcode()) {
105 case TargetOpcode::G_TRUNC:
106 case TargetOpcode::G_ZEXT:
107 case TargetOpcode::G_ANYEXT:
108 case TargetOpcode::G_SEXT:
109 case TargetOpcode::G_MERGE_VALUES:
110 case TargetOpcode::G_UNMERGE_VALUES:
111 case TargetOpcode::G_CONCAT_VECTORS:
112 case TargetOpcode::G_BUILD_VECTOR:
113 case TargetOpcode::G_EXTRACT:
115 case TargetOpcode::G_INSERT:
132 : InstList(Insts), ArtifactList(Arts) {}
148 createdOrChangedInstr(
MI);
151 void printNewInstrs() {
153 for (
const auto *
MI : NewMIs)
154 dbgs() <<
".. .. New MI: " << *
MI;
173 createdOrChangedInstr(
MI);
184 MIRBuilder.
setMF(MF);
194 for (
auto *
MBB : RPOT) {
212 LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);
222 LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder, Libcalls, VT);
228 assert(RetryList.
empty() &&
"Expected no instructions in RetryList");
229 unsigned NumArtifacts = ArtifactList.
size();
230 while (!InstList.
empty()) {
233 "Expecting generic opcode");
249 LLVM_DEBUG(
dbgs() <<
".. Not legalized, moving to artifacts retry\n");
250 assert(NumArtifacts == 0 &&
251 "Artifacts are only expected in instruction list starting the "
252 "second iteration, but each iteration starting second must "
253 "start with an empty artifacts list");
261 WorkListObserver.printNewInstrs();
267 if (!RetryList.
empty()) {
268 if (!ArtifactList.
empty()) {
269 while (!RetryList.
empty())
272 LLVM_DEBUG(
dbgs() <<
"No new artifacts created, not retrying!\n");
278 while (!ArtifactList.
empty()) {
281 "Expecting generic opcode");
291 WorkListObserver.printNewInstrs();
303 LLVM_DEBUG(
dbgs() <<
".. Not combined, moving to instructions list\n");
307 }
while (!InstList.
empty());
327 std::unique_ptr<MachineIRBuilder> MIRBuilder;
331 MIRBuilder = std::make_unique<CSEMIRBuilder>();
332 CSEInfo = GetCSEInfo();
333 MIRBuilder->setCSEInfo(CSEInfo);
335 MIRBuilder = std::make_unique<MachineIRBuilder>();
339 if (EnableCSE && CSEInfo) {
355 MF, LI, AuxObservers, LocObserver, *MIRBuilder, LibcallInfo, VT);
357 if (Result.FailedOn) {
359 "unable to legalize instruction", *Result.FailedOn);
369 <<
" debug locations during pass";
384 return Result.Changed;
402 *
F.getParent(), Subtarget));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This contains common code to allow clients to notify changes to machine instr.
Provides analysis for querying information about KnownBits during GISel passes.
GISelWorkList< 128 > ArtifactListTy
@ LegalizationsAndArtifactCombiners
static cl::opt< DebugLocVerifyLevel > VerifyDebugLocs("verify-legalizer-debug-locs", cl::desc("Verify that debug locations are handled"), cl::values(clEnumValN(DebugLocVerifyLevel::None, "none", "No verification"), clEnumValN(DebugLocVerifyLevel::Legalizations, "legalizations", "Verify legalizations"), clEnumValN(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners, "legalizations+artifactcombiners", "Verify legalizations and artifact combines")), cl::init(DebugLocVerifyLevel::Legalizations))
static cl::opt< bool > EnableCSEInLegalizer("enable-cse-in-legalizer", cl::desc("Should enable CSE in Legalizer"), cl::Optional, cl::init(false))
static bool isCSEEnabled()
static bool runLegalizerOnMachineFunction(MachineFunction &MF, function_ref< GISelCSEInfo *()> GetCSEInfo, function_ref< GISelValueTracking *()> GetVTInfo, const LibcallLoweringInfo *LibcallInfo)
static cl::opt< bool > AllowGInsertAsArtifact("allow-ginsert-as-artifact", cl::desc("Allow G_INSERT to be considered an artifact. Hack around AMDGPU " "test infinite loops."), cl::Optional, cl::init(true))
GISelWorkList< 256 > InstListTy
static bool isArtifact(const MachineInstr &MI)
Tracks DebugLocs between checkpoints and verifies that they are transferred.
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
Target-Independent Code Generator Pass Configuration Options pass.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
DISubprogram * getSubprogram() const
Get the attached subprogram.
The actual analysis pass wrapper.
Simple wrapper that does the following.
Abstract class that contains various methods for clients to notify about changes.
Simple wrapper observer that takes several observers, and calls each one for each event.
void addObserver(GISelChangeObserver *O)
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
MachineInstr * pop_back_val()
void deferred_insert(MachineInstr *I)
void remove(const MachineInstr *I)
Remove I from the worklist if it exists.
bool tryCombineInstruction(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, GISelObserverWrapper &WrapperObserver)
Try to combine away MI.
@ Legalized
Instruction has been legalized and the MachineFunction changed.
@ UnableToLegalize
Some kind of error has occurred and we could not legalize this instruction.
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.
LLVM_ABI LegalizeResult legalizeInstrStep(MachineInstr &MI, LostDebugLocObserver &LocObserver)
Replace MI by a sequence of legal instructions that can implement the same operation.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Tracks which library functions to use for a particular subtarget or function.
void checkpoint(bool CheckDebugLocs=true)
Call this to indicate that it's a good point to assess whether locations have been lost.
unsigned getNumLostDebugLocs() const
An RAII based helper class to modify MachineFunctionProperties when running pass.
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Helper class to build MachineInstr.
void stopObservingChanges()
void setMF(MachineFunction &MF)
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Class to install both of the above.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Target-Independent Code Generator Pass Configuration Options.
virtual std::unique_ptr< CSEConfigBase > getCSEConfig() const
Returns the CSEConfig object to use for the current optimization level.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const LegalizerInfo * getLegalizerInfo() const
An efficient, type-erasing, non-owning reference to a callable.
Pass manager infrastructure for declaring and invalidating analyses.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI void reportGISelWarning(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel warning as a missed optimization remark to the LLVMContext's diagnostic stream.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void reportGISelFailure(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
LegalizerMFResult legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, ArrayRef< GISelChangeObserver * > AuxObservers, LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder, const LibcallLoweringInfo *Libcalls, GISelValueTracking *VT)
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
LLVM_ABI void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
LLVM_ABI void eraseInstrs(ArrayRef< MachineInstr * > DeadInstrs, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
LLVM_ABI bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Check whether an instruction MI is dead: it only defines dead virtual registers, and doesn't have oth...