[MachineOutliner] Add support for target-default outlining.

This adds functionality to the outliner that allows targets to
specify certain functions that should be outlined from by default.

If a target supports default outlining, then it specifies that in
its TargetOptions. In the case that it does, and the user hasn't
specified that they *never* want to outline, the outliner will
be added to the pass pipeline and will run on those default functions.

This is a preliminary patch for turning the outliner on by default
under -Oz for AArch64.

https://reviews.llvm.org/D48776

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336040 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jessica Paquette 2018-06-30 03:56:03 +00:00
parent 8c0bb2f036
commit c549767db5
7 changed files with 56 additions and 10 deletions

View File

@ -423,7 +423,7 @@ namespace llvm {
/// This pass performs outlining on machine instructions directly before
/// printing assembly.
ModulePass *createMachineOutlinerPass();
ModulePass *createMachineOutlinerPass(bool RunOnAllFunctions = true);
/// This pass expands the experimental reduction intrinsics into sequences of
/// shuffles.

View File

@ -1652,6 +1652,11 @@ public:
"TargetInstrInfo::isFunctionSafeToOutlineFrom!");
}
/// Return true if the function should be outlined from by default.
virtual bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const {
return false;
}
private:
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
unsigned CatchRetOpcode;

View File

@ -205,6 +205,9 @@ public:
void setMachineOutliner(bool Enable) {
Options.EnableMachineOutliner = Enable;
}
void setSupportsDefaultOutlining(bool Enable) {
Options.SupportsDefaultOutlining = Enable;
}
bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }

View File

@ -111,7 +111,7 @@ namespace llvm {
NoTrapAfterNoreturn(false),
EmulatedTLS(false), ExplicitEmulatedTLS(false),
EnableIPRA(false), EmitStackSizeSection(false),
EnableMachineOutliner(false) {}
EnableMachineOutliner(false), SupportsDefaultOutlining(false) {}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
/// option is specified on the command line, and should enable debugging
@ -235,6 +235,9 @@ namespace llvm {
/// Enables the MachineOutliner pass.
unsigned EnableMachineOutliner : 1;
/// Set if the target supports default outlining behaviour.
unsigned SupportsDefaultOutlining : 1;
/// FloatABIType - This setting is set by -float-abi=xxx option is specfied
/// on the command line. This setting may either be Default, Soft, or Hard.
/// Default selects the target's default behavior. Soft selects the ABI for

View File

@ -688,6 +688,12 @@ struct MachineOutliner : public ModulePass {
/// linkonceodr linkage.
bool OutlineFromLinkOnceODRs = false;
/// Set to true if the outliner should run on all functions in the module
/// considered safe for outlining.
/// Set to true by default for compatibility with llc's -run-pass option.
/// Set when the pass is constructed in TargetPassConfig.
bool RunOnAllFunctions = true;
// Collection of IR functions created by the outliner.
std::vector<Function *> CreatedIRFunctions;
@ -806,8 +812,10 @@ struct MachineOutliner : public ModulePass {
char MachineOutliner::ID = 0;
namespace llvm {
ModulePass *createMachineOutlinerPass() {
return new MachineOutliner();
ModulePass *createMachineOutlinerPass(bool RunOnAllFunctions) {
MachineOutliner *OL = new MachineOutliner();
OL->RunOnAllFunctions = RunOnAllFunctions;
return OL;
}
} // namespace llvm
@ -1331,6 +1339,20 @@ bool MachineOutliner::runOnModule(Module &M) {
const TargetRegisterInfo *TRI = STI.getRegisterInfo();
const TargetInstrInfo *TII = STI.getInstrInfo();
// If the user passed -enable-machine-outliner=always or
// -enable-machine-outliner, the pass will run on all functions in the module.
// Otherwise, if the target supports default outlining, it will run on all
// functions deemed by the target to be worth outlining from by default. Tell
// the user how the outliner is running.
LLVM_DEBUG(
dbgs() << "Machine Outliner: Running on ";
if (RunOnAllFunctions)
dbgs() << "all functions";
else
dbgs() << "target-default functions";
dbgs() << "\n"
);
// If the user specifies that they want to outline from linkonceodrs, set
// it here.
OutlineFromLinkOnceODRs = EnableLinkOnceODROutlining;
@ -1355,6 +1377,9 @@ bool MachineOutliner::runOnModule(Module &M) {
if (!MF)
continue;
if (!RunOnAllFunctions && !TII->shouldOutlineFromFunctionByDefault(*MF))
continue;
// We have a MachineFunction. Ask the target if it's suitable for outlining.
// If it isn't, then move on to the next Function in the module.
if (!TII->isFunctionSafeToOutlineFrom(*MF, OutlineFromLinkOnceODRs))

View File

@ -111,11 +111,11 @@ static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
cl::desc("Verify generated machine code"),
cl::init(false),
cl::ZeroOrMore);
enum RunOutliner { AlwaysOutline, NeverOutline };
enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault };
// Enable or disable the MachineOutliner.
static cl::opt<RunOutliner> EnableMachineOutliner(
"enable-machine-outliner", cl::desc("Enable the machine outliner"),
cl::Hidden, cl::ValueOptional, cl::init(NeverOutline),
cl::Hidden, cl::ValueOptional, cl::init(TargetDefault),
cl::values(clEnumValN(AlwaysOutline, "always",
"Run on all functions guaranteed to be beneficial"),
clEnumValN(NeverOutline, "never", "Disable all outlining"),
@ -914,8 +914,13 @@ void TargetPassConfig::addMachinePasses() {
addPass(&PatchableFunctionID, false);
if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
EnableMachineOutliner == AlwaysOutline)
addPass(createMachineOutlinerPass());
EnableMachineOutliner != NeverOutline) {
bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline);
bool AddOutliner = RunOnAllFunctions ||
TM->Options.SupportsDefaultOutlining;
if (AddOutliner)
addPass(createMachineOutlinerPass(RunOnAllFunctions));
}
// Add passes that directly emit MI after all other MI passes.
addPreEmitPass2();

View File

@ -1,9 +1,12 @@
; REQUIRES: asserts
; RUN: llc %s -debug-pass=Structure -verify-machineinstrs \
; RUN: -enable-machine-outliner=always -mtriple arm64---- -o /dev/null 2>&1 \
; RUN: --debug-only=machine-outliner -enable-machine-outliner=always \
; RUN: -mtriple arm64---- -o /dev/null 2>&1 \
; RUN: | FileCheck %s -check-prefix=ALWAYS
; RUN: llc %s -debug-pass=Structure -verify-machineinstrs \
; RUN: -enable-machine-outliner -mtriple arm64---- -o /dev/null 2>&1 \
; RUN: --debug-only=machine-outliner -enable-machine-outliner \
; RUN: -mtriple arm64---- -o /dev/null 2>&1 \
; RUN: | FileCheck %s -check-prefix=ENABLE
; RUN: llc %s -debug-pass=Structure -verify-machineinstrs \
@ -31,7 +34,9 @@
; * -enable-machine-outliner=never is passed
; ALWAYS: Machine Outliner
; ALWAYS: Machine Outliner: Running on all functions
; ENABLE: Machine Outliner
; ENABLE: Machine Outliner: Running on all functions
; NEVER-NOT: Machine Outliner
; NOT-ADDED-NOT: Machine Outliner
; OPTNONE-NOT: Machine Outliner