diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -46,6 +46,7 @@ Analysis AsmPrinter Core + IPO CodeGen MC RISCVDesc diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h @@ -135,6 +135,8 @@ virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override; + bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; + // Calculate target-specific information for a set of outlining candidates. outliner::OutlinedFunction getOutliningCandidateInfo( std::vector &RepeatedSequenceLocs) const override; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1196,6 +1196,11 @@ MachineOutlinerDefault }; +bool RISCVInstrInfo::shouldOutlineFromFunctionByDefault( + MachineFunction &MF) const { + return MF.getFunction().hasMinSize(); +} + outliner::OutlinedFunction RISCVInstrInfo::getOutliningCandidateInfo( std::vector &RepeatedSequenceLocs) const { @@ -1246,7 +1251,12 @@ if (MI.isPosition()) { // We can manually strip out CFI instructions later. if (MI.isCFIInstruction()) - return outliner::InstrType::Invisible; + // If current function has exception handling code, we can't outline & + // strip these CFI instructions since it may break .eh_frame section + // needed in unwinding. + return MI.getMF()->getFunction().needsUnwindTableEntry() + ? outliner::InstrType::Illegal + : outliner::InstrType::Invisible; return outliner::InstrType::Illegal; } @@ -1272,7 +1282,8 @@ // Make sure the operands don't reference something unsafe. for (const auto &MO : MI.operands()) - if (MO.isMBB() || MO.isBlockAddress() || MO.isCPI() || MO.isJTI()) + if (MO.isMBB() || MO.isBlockAddress() || MO.isCPI() || MO.isJTI() || + MO.isCFIIndex() || MO.isFI() || MO.isTargetIndex()) return outliner::InstrType::Illegal; // Don't allow instructions which won't be materialized to impact outlining diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -30,6 +30,7 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Transforms/IPO.h" using namespace llvm; static cl::opt EnableRedundantCopyElimination( @@ -77,6 +78,7 @@ // RISC-V supports the MachineOutliner. setMachineOutliner(true); + setSupportsDefaultOutlining(true); } const RISCVSubtarget * @@ -138,6 +140,7 @@ } void addIRPasses() override; + bool addPreISel() override; bool addInstSelector() override; bool addIRTranslator() override; bool addLegalizeMachineIR() override; @@ -164,6 +167,16 @@ TargetPassConfig::addIRPasses(); } +bool RISCVPassConfig::addPreISel() { + if (TM->getOptLevel() != CodeGenOpt::None) { + // Add a barrier before instruction selection so that we will not get + // deleted block address after enabling default outlining. See D99707 for + // more details. + addPass(createBarrierNoopPass()); + } + return false; +} + bool RISCVPassConfig::addInstSelector() { addPass(createRISCVISelDag(getRISCVTargetMachine())); diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll --- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll +++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll @@ -60,9 +60,12 @@ ; CHECK-NEXT: CodeGen Prepare ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Exception handling preparation +; CHECK-NEXT: A No-Op Barrier Pass +; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Safe Stack instrumentation pass ; CHECK-NEXT: Insert stack protectors ; CHECK-NEXT: Module Verifier +; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) ; CHECK-NEXT: Function Alias Analysis Results ; CHECK-NEXT: Natural Loop Information @@ -151,6 +154,8 @@ ; CHECK-NEXT: Contiguously Lay Out Funclets ; CHECK-NEXT: StackMap Liveness Analysis ; CHECK-NEXT: Live DEBUG_VALUE analysis +; CHECK-NEXT: Machine Outliner +; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: RISCV pseudo instruction expansion pass ; CHECK-NEXT: RISCV atomic pseudo instruction expansion pass ; CHECK-NEXT: Lazy Machine Block Frequency Analysis