forked from OSchip/llvm-project
Make tail merging the default, except on powerPC. There was no prior art
for a target-dependent default with a command-line override; this way should be generally usable. llvm-svn: 37285
This commit is contained in:
parent
83d7dd419a
commit
82810c8a13
|
@ -79,7 +79,7 @@ namespace llvm {
|
||||||
/// optimizations to delete branches to branches, eliminate branches to
|
/// optimizations to delete branches to branches, eliminate branches to
|
||||||
/// successor blocks (creating fall throughs), and eliminating branches over
|
/// successor blocks (creating fall throughs), and eliminating branches over
|
||||||
/// branches.
|
/// branches.
|
||||||
FunctionPass *createBranchFoldingPass();
|
FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge);
|
||||||
|
|
||||||
/// IfConverter Pass - This pass performs machine code if conversion.
|
/// IfConverter Pass - This pass performs machine code if conversion.
|
||||||
FunctionPass *createIfConverterPass();
|
FunctionPass *createIfConverterPass();
|
||||||
|
|
|
@ -544,6 +544,28 @@ public:
|
||||||
|
|
||||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
|
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// parser<boolOrDefault>
|
||||||
|
enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
|
||||||
|
template<>
|
||||||
|
class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
|
||||||
|
public:
|
||||||
|
// parse - Return true on error.
|
||||||
|
bool parse(Option &O, const char *ArgName, const std::string &Arg,
|
||||||
|
boolOrDefault &Val);
|
||||||
|
|
||||||
|
enum ValueExpected getValueExpectedFlagDefault() const {
|
||||||
|
return ValueOptional;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getValueName - Do not print =<value> at all.
|
||||||
|
virtual const char *getValueName() const { return 0; }
|
||||||
|
|
||||||
|
// An out-of-line virtual method to provide a 'home' for this class.
|
||||||
|
virtual void anchor();
|
||||||
|
};
|
||||||
|
|
||||||
|
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// parser<int>
|
// parser<int>
|
||||||
|
|
|
@ -185,6 +185,10 @@ public:
|
||||||
AssemblyFile, ObjectFile, DynamicLibrary
|
AssemblyFile, ObjectFile, DynamicLibrary
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// DoTailMergeDefault - Whether it is generally a good idea to do this
|
||||||
|
/// on this target. User flag overrides.
|
||||||
|
virtual const bool DoTailMergeDefault() const { return true; }
|
||||||
|
|
||||||
/// addPassesToEmitFile - Add passes to the specified pass manager to get the
|
/// addPassesToEmitFile - Add passes to the specified pass manager to get the
|
||||||
/// specified file emitted. Typically this will involve several steps of code
|
/// specified file emitted. Typically this will involve several steps of code
|
||||||
/// generation. If Fast is set to true, the code generator should emit code
|
/// generation. If Fast is set to true, the code generator should emit code
|
||||||
|
@ -315,6 +319,10 @@ public:
|
||||||
MachineCodeEmitter &MCE) {
|
MachineCodeEmitter &MCE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// DoTailMergeDefault - Whether it is generally a good idea to do this
|
||||||
|
/// on this target. User flag overrides.
|
||||||
|
virtual const bool DoTailMergeDefault() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
|
@ -35,12 +35,19 @@ using namespace llvm;
|
||||||
STATISTIC(NumDeadBlocks, "Number of dead blocks removed");
|
STATISTIC(NumDeadBlocks, "Number of dead blocks removed");
|
||||||
STATISTIC(NumBranchOpts, "Number of branches optimized");
|
STATISTIC(NumBranchOpts, "Number of branches optimized");
|
||||||
STATISTIC(NumTailMerge , "Number of block tails merged");
|
STATISTIC(NumTailMerge , "Number of block tails merged");
|
||||||
static cl::opt<bool> EnableTailMerge("enable-tail-merge", cl::Hidden);
|
static cl::opt<cl::boolOrDefault> FlagEnableTailMerge("enable-tail-merge",
|
||||||
|
cl::init(cl::BOU_UNSET), cl::Hidden);
|
||||||
namespace {
|
namespace {
|
||||||
struct BranchFolder : public MachineFunctionPass {
|
struct BranchFolder : public MachineFunctionPass {
|
||||||
static char ID;
|
static char ID;
|
||||||
BranchFolder() : MachineFunctionPass((intptr_t)&ID) {}
|
BranchFolder(bool defaultEnableTailMerge) :
|
||||||
|
MachineFunctionPass((intptr_t)&ID) {
|
||||||
|
switch (FlagEnableTailMerge) {
|
||||||
|
case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break;
|
||||||
|
case cl::BOU_TRUE: EnableTailMerge = true; break;
|
||||||
|
case cl::BOU_FALSE: EnableTailMerge = false; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool runOnMachineFunction(MachineFunction &MF);
|
virtual bool runOnMachineFunction(MachineFunction &MF);
|
||||||
virtual const char *getPassName() const { return "Control Flow Optimizer"; }
|
virtual const char *getPassName() const { return "Control Flow Optimizer"; }
|
||||||
|
@ -49,6 +56,7 @@ namespace {
|
||||||
bool MadeChange;
|
bool MadeChange;
|
||||||
private:
|
private:
|
||||||
// Tail Merging.
|
// Tail Merging.
|
||||||
|
bool EnableTailMerge;
|
||||||
bool TailMergeBlocks(MachineFunction &MF);
|
bool TailMergeBlocks(MachineFunction &MF);
|
||||||
bool TryMergeBlocks(MachineBasicBlock* SuccBB,
|
bool TryMergeBlocks(MachineBasicBlock* SuccBB,
|
||||||
MachineBasicBlock* PredBB);
|
MachineBasicBlock* PredBB);
|
||||||
|
@ -79,7 +87,8 @@ static bool CorrectExtraCFGEdges(MachineBasicBlock &MBB,
|
||||||
bool isCond,
|
bool isCond,
|
||||||
MachineFunction::iterator FallThru);
|
MachineFunction::iterator FallThru);
|
||||||
|
|
||||||
FunctionPass *llvm::createBranchFoldingPass() { return new BranchFolder(); }
|
FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) {
|
||||||
|
return new BranchFolder(DefaultEnableTailMerge); }
|
||||||
|
|
||||||
/// RemoveDeadBlock - Remove the specified dead machine basic block from the
|
/// RemoveDeadBlock - Remove the specified dead machine basic block from the
|
||||||
/// function, updating the CFG.
|
/// function, updating the CFG.
|
||||||
|
|
|
@ -78,7 +78,7 @@ LLVMTargetMachine::addPassesToEmitFile(FunctionPassManager &PM,
|
||||||
|
|
||||||
// Branch folding must be run after regalloc and prolog/epilog insertion.
|
// Branch folding must be run after regalloc and prolog/epilog insertion.
|
||||||
if (!Fast)
|
if (!Fast)
|
||||||
PM.add(createBranchFoldingPass());
|
PM.add(createBranchFoldingPass(DoTailMergeDefault()));
|
||||||
|
|
||||||
// Fold redundant debug labels.
|
// Fold redundant debug labels.
|
||||||
PM.add(createDebugLabelFoldingPass());
|
PM.add(createDebugLabelFoldingPass());
|
||||||
|
@ -181,7 +181,7 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
|
||||||
|
|
||||||
// Branch folding must be run after regalloc and prolog/epilog insertion.
|
// Branch folding must be run after regalloc and prolog/epilog insertion.
|
||||||
if (!Fast)
|
if (!Fast)
|
||||||
PM.add(createBranchFoldingPass());
|
PM.add(createBranchFoldingPass(DoTailMergeDefault()));
|
||||||
|
|
||||||
if (addPreEmitPass(PM, Fast) && PrintMachineCode)
|
if (addPreEmitPass(PM, Fast) && PrintMachineCode)
|
||||||
PM.add(createMachineFunctionPrinterPass(cerr));
|
PM.add(createMachineFunctionPrinterPass(cerr));
|
||||||
|
|
|
@ -36,6 +36,7 @@ using namespace cl;
|
||||||
// Template instantiations and anchors.
|
// Template instantiations and anchors.
|
||||||
//
|
//
|
||||||
TEMPLATE_INSTANTIATION(class basic_parser<bool>);
|
TEMPLATE_INSTANTIATION(class basic_parser<bool>);
|
||||||
|
TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
|
||||||
TEMPLATE_INSTANTIATION(class basic_parser<int>);
|
TEMPLATE_INSTANTIATION(class basic_parser<int>);
|
||||||
TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
|
TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
|
||||||
TEMPLATE_INSTANTIATION(class basic_parser<double>);
|
TEMPLATE_INSTANTIATION(class basic_parser<double>);
|
||||||
|
@ -50,6 +51,7 @@ TEMPLATE_INSTANTIATION(class opt<bool>);
|
||||||
void Option::anchor() {}
|
void Option::anchor() {}
|
||||||
void basic_parser_impl::anchor() {}
|
void basic_parser_impl::anchor() {}
|
||||||
void parser<bool>::anchor() {}
|
void parser<bool>::anchor() {}
|
||||||
|
void parser<boolOrDefault>::anchor() {}
|
||||||
void parser<int>::anchor() {}
|
void parser<int>::anchor() {}
|
||||||
void parser<unsigned>::anchor() {}
|
void parser<unsigned>::anchor() {}
|
||||||
void parser<double>::anchor() {}
|
void parser<double>::anchor() {}
|
||||||
|
@ -767,6 +769,22 @@ bool parser<bool>::parse(Option &O, const char *ArgName,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parser<boolOrDefault> implementation
|
||||||
|
//
|
||||||
|
bool parser<boolOrDefault>::parse(Option &O, const char *ArgName,
|
||||||
|
const std::string &Arg, boolOrDefault &Value) {
|
||||||
|
if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
|
||||||
|
Arg == "1") {
|
||||||
|
Value = BOU_TRUE;
|
||||||
|
} else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {
|
||||||
|
Value = BOU_FALSE;
|
||||||
|
} else {
|
||||||
|
return O.error(": '" + Arg +
|
||||||
|
"' is invalid value for boolean argument! Try 0 or 1");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// parser<int> implementation
|
// parser<int> implementation
|
||||||
//
|
//
|
||||||
bool parser<int>::parse(Option &O, const char *ArgName,
|
bool parser<int>::parse(Option &O, const char *ArgName,
|
||||||
|
|
|
@ -96,6 +96,10 @@ PPCTargetMachine::PPCTargetMachine(const Module &M, const std::string &FS,
|
||||||
setRelocationModel(Reloc::Static);
|
setRelocationModel(Reloc::Static);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Override this for PowerPC. Tail merging happily breaks up instruction issue
|
||||||
|
/// groups, which typically degrades performance.
|
||||||
|
const bool PPCTargetMachine::DoTailMergeDefault() const { return false; }
|
||||||
|
|
||||||
PPC32TargetMachine::PPC32TargetMachine(const Module &M, const std::string &FS)
|
PPC32TargetMachine::PPC32TargetMachine(const Module &M, const std::string &FS)
|
||||||
: PPCTargetMachine(M, FS, false) {
|
: PPCTargetMachine(M, FS, false) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ public:
|
||||||
MachineCodeEmitter &MCE);
|
MachineCodeEmitter &MCE);
|
||||||
virtual bool addSimpleCodeEmitter(FunctionPassManager &PM, bool Fast,
|
virtual bool addSimpleCodeEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
MachineCodeEmitter &MCE);
|
MachineCodeEmitter &MCE);
|
||||||
|
virtual const bool DoTailMergeDefault() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// PPC32TargetMachine - PowerPC 32-bit target machine.
|
/// PPC32TargetMachine - PowerPC 32-bit target machine.
|
||||||
|
|
Loading…
Reference in New Issue