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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37285 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index bd13664..e7a97cf 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -79,7 +79,7 @@
   /// optimizations to delete branches to branches, eliminate branches to
   /// successor blocks (creating fall throughs), and eliminating branches over
   /// branches.
-  FunctionPass *createBranchFoldingPass();
+  FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge);
 
   /// IfConverter Pass - This pass performs machine code if conversion.
   FunctionPass *createIfConverterPass();
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index c31d79f..08aca81 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -544,6 +544,28 @@
 
 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>
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index e5fceba..faf3c35 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -185,6 +185,10 @@
     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
   /// specified file emitted.  Typically this will involve several steps of code
   /// generation.  If Fast is set to true, the code generator should emit code
@@ -315,6 +319,10 @@
                                     MachineCodeEmitter &MCE) {
     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
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index d8ec340..7cc4c2d 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -35,12 +35,19 @@
 STATISTIC(NumDeadBlocks, "Number of dead blocks removed");
 STATISTIC(NumBranchOpts, "Number of branches optimized");
 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 {
   struct BranchFolder : public MachineFunctionPass {
     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 const char *getPassName() const { return "Control Flow Optimizer"; }
@@ -49,6 +56,7 @@
     bool MadeChange;
   private:
     // Tail Merging.
+    bool EnableTailMerge;
     bool TailMergeBlocks(MachineFunction &MF);
     bool TryMergeBlocks(MachineBasicBlock* SuccBB,
                         MachineBasicBlock* PredBB);
@@ -79,7 +87,8 @@
                                  bool isCond, 
                                  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
 /// function, updating the CFG.
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 34c45f3..41f7e19 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -78,7 +78,7 @@
   
   // Branch folding must be run after regalloc and prolog/epilog insertion.
   if (!Fast)
-    PM.add(createBranchFoldingPass());
+    PM.add(createBranchFoldingPass(DoTailMergeDefault()));
     
   // Fold redundant debug labels.
   PM.add(createDebugLabelFoldingPass());
@@ -181,7 +181,7 @@
   
   // Branch folding must be run after regalloc and prolog/epilog insertion.
   if (!Fast)
-    PM.add(createBranchFoldingPass());
+    PM.add(createBranchFoldingPass(DoTailMergeDefault()));
   
   if (addPreEmitPass(PM, Fast) && PrintMachineCode)
     PM.add(createMachineFunctionPrinterPass(cerr));
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 2b0798a..1f5008a 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -36,6 +36,7 @@
 // Template instantiations and anchors.
 //
 TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
 TEMPLATE_INSTANTIATION(class basic_parser<int>);
 TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
 TEMPLATE_INSTANTIATION(class basic_parser<double>);
@@ -50,6 +51,7 @@
 void Option::anchor() {}
 void basic_parser_impl::anchor() {}
 void parser<bool>::anchor() {}
+void parser<boolOrDefault>::anchor() {}
 void parser<int>::anchor() {}
 void parser<unsigned>::anchor() {}
 void parser<double>::anchor() {}
@@ -767,6 +769,22 @@
   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
 //
 bool parser<int>::parse(Option &O, const char *ArgName,
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index df3e3d2..6d5e050 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -96,6 +96,10 @@
       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) 
   : PPCTargetMachine(M, FS, false) {
 }
diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h
index a249952..fdf9d35 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/lib/Target/PowerPC/PPCTargetMachine.h
@@ -73,6 +73,7 @@
                               MachineCodeEmitter &MCE);
   virtual bool addSimpleCodeEmitter(FunctionPassManager &PM, bool Fast,
                                     MachineCodeEmitter &MCE);
+  virtual const bool DoTailMergeDefault() const;
 };
 
 /// PPC32TargetMachine - PowerPC 32-bit target machine.