diff options
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp index 25fae5487187..75a8f03fcb3f 100644 --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -11,7 +11,11 @@ #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/Twine.h" +#include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Analysis/LazyBlockFrequencyInfo.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" @@ -50,16 +54,29 @@ INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE, false, false) INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) +INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass) INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE, "Select target instructions out of generic instructions", false, false) -InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) { } +InstructionSelect::InstructionSelect(CodeGenOpt::Level OL) + : MachineFunctionPass(ID), OptLevel(OL) {} + +// In order not to crash when calling getAnalysis during testing with -run-pass +// we use the default opt level here instead of None, so that the addRequired() +// calls are made in getAnalysisUsage(). +InstructionSelect::InstructionSelect() + : MachineFunctionPass(ID), OptLevel(CodeGenOpt::Default) {} void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<TargetPassConfig>(); - AU.addRequired<GISelKnownBitsAnalysis>(); - AU.addPreserved<GISelKnownBitsAnalysis>(); + if (OptLevel != CodeGenOpt::None) { + AU.addRequired<GISelKnownBitsAnalysis>(); + AU.addPreserved<GISelKnownBitsAnalysis>(); + AU.addRequired<ProfileSummaryInfoWrapperPass>(); + LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU); + } getSelectionDAGFallbackAnalysisUsage(AU); MachineFunctionPass::getAnalysisUsage(AU); } @@ -71,13 +88,26 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { return false; LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); - GISelKnownBits &KB = getAnalysis<GISelKnownBitsAnalysis>().get(MF); const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); + + CodeGenOpt::Level OldOptLevel = OptLevel; + auto RestoreOptLevel = make_scope_exit([=]() { OptLevel = OldOptLevel; }); + OptLevel = MF.getFunction().hasOptNone() ? CodeGenOpt::None + : MF.getTarget().getOptLevel(); + + GISelKnownBits *KB = nullptr; + if (OptLevel != CodeGenOpt::None) { + KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF); + PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); + if (PSI && PSI->hasProfileSummary()) + BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI(); + } + CodeGenCoverage CoverageInfo; assert(ISel && "Cannot work without InstructionSelector"); - ISel->setupMF(MF, KB, CoverageInfo); + ISel->setupMF(MF, KB, CoverageInfo, PSI, BFI); // An optimization remark emitter. Used to report failures. MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); @@ -102,6 +132,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { #endif for (MachineBasicBlock *MBB : post_order(&MF)) { + ISel->CurMBB = MBB; if (MBB->empty()) continue; @@ -133,6 +164,25 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { continue; } + // Eliminate hints. + if (isPreISelGenericOptimizationHint(MI.getOpcode())) { + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); + + // At this point, the destination register class of the hint may have + // been decided. + // + // Propagate that through to the source register. + const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg); + if (DstRC) + MRI.setRegClass(SrcReg, DstRC); + assert(canReplaceReg(DstReg, SrcReg, MRI) && + "Must be able to replace dst with src!"); + MI.eraseFromParent(); + MRI.replaceRegWith(DstReg, SrcReg); + continue; + } + if (!ISel->select(MI)) { // FIXME: It would be nice to dump all inserted instructions. It's // not obvious how, esp. considering select() can insert after MI. |
