module LLVM.Util.Optimize(optimizeModule) where
import Control.Monad
import Foreign.Ptr(nullPtr)
import LLVM.Core.Util(Module, withModule)
import qualified LLVM.FFI.Core as FFI
import LLVM.FFI.Target(addTargetData, createTargetData)
import LLVM.FFI.Transforms.IPO
import LLVM.FFI.Transforms.Scalar
optimizeModule :: Int -> Module -> IO Int
optimizeModule optLevel mdl = withModule mdl $ \ m -> do
passes <- FFI.createPassManager
target <- FFI.getDataLayout m >>= createTargetData
addTargetData target passes
let fPasses = nullPtr
addLowerSetJmpPass passes
addOptimizationPasses passes fPasses optLevel
rc <- FFI.runPassManager passes m
return (fromIntegral rc)
addOptimizationPasses :: FFI.PassManagerRef -> FFI.PassManagerRef -> Int -> IO ()
addOptimizationPasses passes fPasses optLevel = do
createStandardFunctionPasses fPasses optLevel
let inline = addFunctionInliningPass
createStandardModulePasses passes optLevel True (optLevel > 1) True True inline
createStandardFunctionPasses :: FFI.PassManagerRef -> Int -> IO ()
createStandardFunctionPasses fPasses optLevel = do
when False $ do
addCFGSimplificationPass fPasses
if optLevel == 1 then
addPromoteMemoryToRegisterPass fPasses
else
addScalarReplAggregatesPass fPasses
addInstructionCombiningPass fPasses
createStandardModulePasses :: FFI.PassManagerRef -> Int -> Bool -> Bool -> Bool -> Bool -> (FFI.PassManagerRef -> IO()) -> IO ()
createStandardModulePasses passes optLevel unitAtATime unrollLoops simplifyLibCalls haveExceptions inliningPass = do
when unitAtATime $ do
addRaiseAllocationsPass passes
addCFGSimplificationPass passes
addPromoteMemoryToRegisterPass passes
when unitAtATime $ do
addGlobalOptimizerPass passes
addGlobalDCEPass passes
addIPConstantPropagationPass passes
addDeadArgEliminationPass passes
addInstructionCombiningPass passes
addCFGSimplificationPass passes
when unitAtATime $ do
when haveExceptions $ addPruneEHPass passes
addFunctionAttrsPass passes
inliningPass passes
when (optLevel > 2) $ do
addArgumentPromotionPass passes
when simplifyLibCalls $ do
addSimplifyLibCallsPass passes
addInstructionCombiningPass passes
addJumpThreadingPass passes
addCFGSimplificationPass passes
addScalarReplAggregatesPass passes
addInstructionCombiningPass passes
addCondPropagationPass passes
addTailCallEliminationPass passes
addCFGSimplificationPass passes
addReassociatePass passes
addLoopRotatePass passes
addLICMPass passes
addLoopUnswitchPass passes
addInstructionCombiningPass passes
addIndVarSimplifyPass passes
addLoopDeletionPass passes
when unrollLoops $
addLoopUnrollPass passes
addInstructionCombiningPass passes
addGVNPass passes
addMemCpyOptPass passes
addSCCPPass passes
addInstructionCombiningPass passes
addCondPropagationPass passes
addDeadStoreEliminationPass passes
addAggressiveDCEPass passes
addCFGSimplificationPass passes
when unitAtATime $ do
addStripDeadPrototypesPass passes
addDeadTypeEliminationPass passes
when (optLevel > 1 && unitAtATime) $
addConstantMergePass passes