Index: bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c =================================================================== --- bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c +++ bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c @@ -147,6 +147,12 @@ } /* [ unit */ +CAMLprim value llvm_add_select_elimination(LLVMPassManagerRef PM) { + LLVMAddSelectEliminationPass(PM); + return Val_unit; +} + +/* [ unit */ CAMLprim value llvm_add_memcpy_opt(LLVMPassManagerRef PM) { LLVMAddMemCpyOptPass(PM); return Val_unit; Index: include/llvm-c/Transforms/Scalar.h =================================================================== --- include/llvm-c/Transforms/Scalar.h +++ include/llvm-c/Transforms/Scalar.h @@ -50,6 +50,9 @@ /** See llvm::createGVNPass function. */ void LLVMAddGVNPass(LLVMPassManagerRef PM); +/** See llvm::createSelectEliminationPass function. */ +void LLVMAddSelectEliminationPass(LLVMPassManagerRef PM); + /** See llvm::createIndVarSimplifyPass function. */ void LLVMAddIndVarSimplifyPass(LLVMPassManagerRef PM); Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -239,6 +239,7 @@ void initializeSROA_SSAUpPass(PassRegistry&); void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&); void initializeScalarEvolutionPass(PassRegistry&); +void initializeSelectEliminationPass(PassRegistry &); void initializeSimpleInlinerPass(PassRegistry&); void initializeRegisterCoalescerPass(PassRegistry&); void initializeSingleLoopExtractorPass(PassRegistry&); Index: include/llvm/LinkAllPasses.h =================================================================== --- include/llvm/LinkAllPasses.h +++ include/llvm/LinkAllPasses.h @@ -137,6 +137,7 @@ (void) llvm::createEarlyCSEPass(); (void)llvm::createMergedLoadStoreMotionPass(); (void) llvm::createGVNPass(); + (void)llvm::createSelectEliminationPass(); (void) llvm::createMemCpyOptPass(); (void) llvm::createLoopDeletionPass(); (void) llvm::createPostDomTree(); Index: include/llvm/Transforms/Scalar.h =================================================================== --- include/llvm/Transforms/Scalar.h +++ include/llvm/Transforms/Scalar.h @@ -302,6 +302,12 @@ //===----------------------------------------------------------------------===// // +// SelectElimination - This pass removes selects when possible. +// +FunctionPass *createSelectEliminationPass(); + +//===----------------------------------------------------------------------===// +// // MemCpyOpt - This pass performs optimizations related to eliminating memcpy // calls and/or combining multiple stores into memset's. // Index: lib/LTO/LTOCodeGenerator.cpp =================================================================== --- lib/LTO/LTOCodeGenerator.cpp +++ lib/LTO/LTOCodeGenerator.cpp @@ -110,6 +110,7 @@ initializeLICMPass(R); initializeMergedLoadStoreMotionPass(R); initializeGVNPass(R); + initializeSelectEliminationPass(R); initializeMemCpyOptPass(R); initializeDCEPass(R); initializeCFGSimplifyPassPass(R); Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -226,6 +226,7 @@ MPM.add(createMergedLoadStoreMotionPass()); // Merge load/stores in diamond MPM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies } + MPM.add(createSelectEliminationPass()); // Remove selects MPM.add(createMemCpyOptPass()); // Remove memcpy / form memset MPM.add(createSCCPPass()); // Constant prop with SCCP @@ -381,6 +382,7 @@ PM.add(createLICMPass()); // Hoist loop invariants. PM.add(createMergedLoadStoreMotionPass()); // Merge load/stores in diamonds PM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies. + PM.add(createSelectEliminationPass()); // Remove selects PM.add(createMemCpyOptPass()); // Remove dead memcpys. // Nuke dead stores. Index: lib/Transforms/Scalar/CMakeLists.txt =================================================================== --- lib/Transforms/Scalar/CMakeLists.txt +++ lib/Transforms/Scalar/CMakeLists.txt @@ -32,6 +32,7 @@ Scalar.cpp ScalarReplAggregates.cpp Scalarizer.cpp + SelectElimination.cpp SeparateConstOffsetFromGEP.cpp SimplifyCFGPass.cpp Sink.cpp Index: lib/Transforms/Scalar/Scalar.cpp =================================================================== --- lib/Transforms/Scalar/Scalar.cpp +++ lib/Transforms/Scalar/Scalar.cpp @@ -58,6 +58,7 @@ initializeReassociatePass(Registry); initializeRegToMemPass(Registry); initializeSCCPPass(Registry); + initializeSelectEliminationPass(Registry); initializeIPSCCPPass(Registry); initializeSROAPass(Registry); initializeSROA_DTPass(Registry); @@ -171,6 +172,10 @@ unwrap(PM)->add(createScalarReplAggregatesPass(Threshold)); } +void LLVMAddSelectEliminationPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createSelectEliminationPass()); +} + void LLVMAddSimplifyLibCallsPass(LLVMPassManagerRef PM) { // NOTE: The simplify-libcalls pass has been removed. } Index: lib/Transforms/Scalar/SelectElimination.cpp =================================================================== --- /dev/null +++ lib/Transforms/Scalar/SelectElimination.cpp @@ -0,0 +1,225 @@ +//===- SelectElimination.cpp - remove redundant select instructions ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// \file +// \brief Eliminate select statements by replacing them with bit operations +// +//===----------------------------------------------------------------------===// +// Example: +// +// entry: +// ... +// %3 = icmp eq i64* %.m, %.n +// %4 = select i1 %3, %C* %0, %C* null +// %5 = icmp eq %C* %4, null +// br i1 %5, label %9, label %7 +// +//;