33#define DEBUG_TYPE "legalizer"
39 cl::desc(
"Should enable CSE in Legalizer"),
44 "allow-ginsert-as-artifact",
45 cl::desc(
"Allow G_INSERT to be considered an artifact. Hack around AMDGPU "
46 "test infinite loops."),
56 "verify-legalizer-debug-locs",
57 cl::desc(
"Verify that debug locations are handled"),
61 "Verify legalizations"),
63 "legalizations+artifactcombiners",
64 "Verify legalizations and artifact combines")),
74 "Legalize the Machine IR a function's Machine IR",
false,
99 switch (
MI.getOpcode()) {
102 case TargetOpcode::G_TRUNC:
103 case TargetOpcode::G_ZEXT:
104 case TargetOpcode::G_ANYEXT:
105 case TargetOpcode::G_SEXT:
106 case TargetOpcode::G_MERGE_VALUES:
107 case TargetOpcode::G_UNMERGE_VALUES:
108 case TargetOpcode::G_CONCAT_VECTORS:
109 case TargetOpcode::G_BUILD_VECTOR:
110 case TargetOpcode::G_EXTRACT:
112 case TargetOpcode::G_INSERT:
129 : InstList(Insts), ArtifactList(Arts) {}
145 createdOrChangedInstr(
MI);
148 void printNewInstrs() {
150 for (
const auto *
MI : NewMIs)
151 dbgs() <<
".. .. New MI: " << *
MI;
170 createdOrChangedInstr(
MI);
181 MIRBuilder.
setMF(MF);
191 for (
auto *
MBB : RPOT) {
209 LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);
221 bool Changed =
false;
225 assert(RetryList.
empty() &&
"Expected no instructions in RetryList");
226 unsigned NumArtifacts = ArtifactList.
size();
227 while (!InstList.
empty()) {
230 "Expecting generic opcode");
246 LLVM_DEBUG(
dbgs() <<
".. Not legalized, moving to artifacts retry\n");
247 assert(NumArtifacts == 0 &&
248 "Artifacts are only expected in instruction list starting the "
249 "second iteration, but each iteration starting second must "
250 "start with an empty artifacts list");
256 return {Changed, &
MI};
258 WorkListObserver.printNewInstrs();
264 if (!RetryList.
empty()) {
265 if (!ArtifactList.
empty()) {
266 while (!RetryList.
empty())
269 LLVM_DEBUG(
dbgs() <<
"No new artifacts created, not retrying!\n");
271 return {Changed, RetryList.
front()};
275 while (!ArtifactList.
empty()) {
278 "Expecting generic opcode");
288 WorkListObserver.printNewInstrs();
292 DebugLocVerifyLevel::LegalizationsAndArtifactCombiners);
300 LLVM_DEBUG(
dbgs() <<
".. Not combined, moving to instructions list\n");
304 }
while (!InstList.
empty());
306 return {Changed,
nullptr};
318 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
321 std::unique_ptr<MachineIRBuilder> MIRBuilder;
327 MIRBuilder = std::make_unique<CSEMIRBuilder>();
329 MIRBuilder->setCSEInfo(CSEInfo);
331 MIRBuilder = std::make_unique<MachineIRBuilder>();
334 if (EnableCSE && CSEInfo) {
344 GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
350 if (Result.FailedOn) {
352 "unable to legalize instruction", *Result.FailedOn);
362 <<
" debug locations during pass";
383 return Result.Changed;
unsigned const MachineRegisterInfo * MRI
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
AMDGPU Register Bank Legalize
COFF::MachineTypes Machine
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)
Performs the initial survey of the specified function
This contains common code to allow clients to notify changes to machine instr.
Provides analysis for querying information about KnownBits during GISel passes.
Legalize the Machine IR a function s Machine IR
@ 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 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))
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Target-Independent Code Generator Pass Configuration Options pass.
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.
ArrayRef - 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.
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis...
Simple wrapper observer that takes several observers, and calls each one for each event.
void addObserver(GISelChangeObserver *O)
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.
LegalizeResult legalizeInstrStep(MachineInstr &MI, LostDebugLocObserver &LocObserver)
Replace MI by a sequence of legal instructions that can implement the same operation.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static MFResult legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, ArrayRef< GISelChangeObserver * > AuxObservers, LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder, GISelKnownBits *KB)
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
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool hasProperty(Property P) const
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,...
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.
virtual bool isGISelCSEEnabled() const
Check whether continuous CSE should be enabled in GISel passes.
virtual const LegalizerInfo * getLegalizerInfo() const
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.
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.
void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
void eraseInstrs(ArrayRef< MachineInstr * > DeadInstrs, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
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...
void reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel warning as a missed optimization remark to the LLVMContext's diagnostic stream.