Go to the documentation of this file.
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,
96 switch (
MI.getOpcode()) {
99 case TargetOpcode::G_TRUNC:
100 case TargetOpcode::G_ZEXT:
101 case TargetOpcode::G_ANYEXT:
102 case TargetOpcode::G_SEXT:
103 case TargetOpcode::G_MERGE_VALUES:
104 case TargetOpcode::G_UNMERGE_VALUES:
105 case TargetOpcode::G_CONCAT_VECTORS:
106 case TargetOpcode::G_BUILD_VECTOR:
107 case TargetOpcode::G_EXTRACT:
109 case TargetOpcode::G_INSERT:
126 : InstList(Insts), ArtifactList(Arts) {}
142 createdOrChangedInstr(
MI);
145 void printNewInstrs() {
147 for (
const auto *
MI : NewMIs)
148 dbgs() <<
".. .. New MI: " << *
MI;
167 createdOrChangedInstr(
MI);
177 MIRBuilder.
setMF(MF);
187 for (
auto *
MBB : RPOT) {
205 LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);
217 bool Changed =
false;
221 assert(RetryList.empty() &&
"Expected no instructions in RetryList");
222 unsigned NumArtifacts = ArtifactList.
size();
223 while (!InstList.
empty()) {
226 "Expecting generic opcode");
242 LLVM_DEBUG(
dbgs() <<
".. Not legalized, moving to artifacts retry\n");
243 assert(NumArtifacts == 0 &&
244 "Artifacts are only expected in instruction list starting the "
245 "second iteration, but each iteration starting second must "
246 "start with an empty artifacts list");
248 RetryList.push_back(&
MI);
252 return {Changed, &
MI};
254 WorkListObserver.printNewInstrs();
260 if (!RetryList.empty()) {
261 if (!ArtifactList.
empty()) {
262 while (!RetryList.empty())
265 LLVM_DEBUG(
dbgs() <<
"No new artifacts created, not retrying!\n");
267 return {Changed, RetryList.front()};
271 while (!ArtifactList.
empty()) {
274 "Expecting generic opcode");
284 WorkListObserver.printNewInstrs();
296 LLVM_DEBUG(
dbgs() <<
".. Not combined, moving to instructions list\n");
300 }
while (!InstList.
empty());
302 return {Changed,
nullptr};
314 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
317 const size_t NumBlocks = MF.
size();
319 std::unique_ptr<MachineIRBuilder> MIRBuilder;
325 MIRBuilder = std::make_unique<CSEMIRBuilder>();
327 MIRBuilder->setCSEInfo(CSEInfo);
329 MIRBuilder = std::make_unique<MachineIRBuilder>();
332 if (EnableCSE && CSEInfo) {
334 AuxObservers.push_back(CSEInfo);
339 AuxObservers.push_back(&LocObserver);
345 if (Result.FailedOn) {
347 "unable to legalize instruction", *Result.FailedOn);
352 if (MF.
size() != NumBlocks) {
356 R <<
"inserting blocks is not supported yet";
367 <<
" debug locations during pass";
388 return Result.Changed;
void setMF(MachineFunction &MF)
bool hasProperty(Property P) const
This is an optimization pass for GlobalISel generic memory operations.
void deferred_insert(MachineInstr *I)
The actual analysis pass wrapper.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
DISubprogram * getSubprogram() const
Get the attached subprogram.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
@ UnableToLegalize
Some kind of error has occurred and we could not legalize this instruction.
void eraseInstrs(ArrayRef< MachineInstr * > DeadInstrs, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
static cl::opt< bool > EnableCSEInLegalizer("enable-cse-in-legalizer", cl::desc("Should enable CSE in Legalizer"), cl::Optional, cl::init(false))
Legalize the Machine IR a function s Machine IR
DiagnosticInfoOptimizationBase::Argument NV
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
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.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool isGISelCSEEnabled() const
Check whether continuous CSE should be enabled in GISel passes.
=0.0 ? 0.0 :(a > 0.0 ? 1.0 :-1.0) a
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))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
@ LegalizationsAndArtifactCombiners
void checkpoint(bool CheckDebugLocs=true)
Call this to indicate that it's a good point to assess whether locations have been lost.
Represent the analysis usage information of a pass.
const MachineFunctionProperties & getProperties() const
Get the function properties.
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...
INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE, "Legalize the Machine IR a function's Machine IR", false, false) INITIALIZE_PASS_END(Legalizer
int getNumOccurrences() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
unsigned getNumLostDebugLocs() const
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Target-Independent Code Generator Pass Configuration Options.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Helper class to build MachineInstr.
void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
Representation of each machine instruction.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
multiplies can be turned into SHL s
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
initializer< Ty > init(const Ty &Val)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
print Print MemDeps of function
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
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...
MachineInstr * pop_back_val()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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))
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
void remove(const MachineInstr *I)
Remove I from the worklist if it exists.
Abstract class that contains various methods for clients to notify about changes.
unsigned const MachineRegisterInfo * MRI
static MFResult legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, ArrayRef< GISelChangeObserver * > AuxObservers, LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder)
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
virtual std::unique_ptr< CSEConfigBase > getCSEConfig() const
Returns the CSEConfig object to use for the current optimization level.
virtual const LegalizerInfo * getLegalizerInfo() const
Function & getFunction()
Return the LLVM function that this machine code represents.
constexpr std::nullopt_t None
Simple wrapper that does the following.
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.
COFF::MachineTypes Machine
void addObserver(GISelChangeObserver *O)
static bool isArtifact(const MachineInstr &MI)
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.
bool tryCombineInstruction(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, GISelObserverWrapper &WrapperObserver)
Try to combine away MI.
Simple wrapper observer that takes several observers, and calls each one for each event.
AnalysisUsage & addRequired()
void stopObservingChanges()
LegalizeResult legalizeInstrStep(MachineInstr &MI, LostDebugLocObserver &LocObserver)
Replace MI by a sequence of legal instructions that can implement the same operation.
@ Legalized
Instruction has been legalized and the MachineFunction changed.
Class to install both of the above.