module LinearScan.Main where import Debug.Trace (trace, traceShow) import qualified Prelude import qualified Data.IntMap import qualified Data.IntSet import qualified Data.List import qualified Data.Ord import qualified Data.Functor.Identity import qualified LinearScan.Utils import qualified LinearScan.Allocate as Allocate import qualified LinearScan.Assign as Assign import qualified LinearScan.Blocks as Blocks import qualified LinearScan.Build as Build import qualified LinearScan.IntMap as IntMap import qualified LinearScan.Interval as Interval import qualified LinearScan.Lib as Lib import qualified LinearScan.LiveSets as LiveSets import qualified LinearScan.Loops as Loops import qualified LinearScan.Monad as Monad import qualified LinearScan.Morph as Morph import qualified LinearScan.Resolve as Resolve import qualified LinearScan.ScanState as ScanState import qualified LinearScan.Ssrnat as Ssrnat data FinalStage = BuildingIntervalsFailed | AllocatingRegistersFailed data ScanStateDescSet = Build_ScanStateDescSet Prelude.Int ([] Interval.IntervalDesc) ([] (Prelude.Maybe Interval.IntervalDesc)) ([] ((,) Prelude.Int Prelude.Int)) ([] ((,) Prelude.Int Prelude.Int)) ([] ((,) Prelude.Int Prelude.Int)) ([] ((,) Prelude.Int (Prelude.Maybe Prelude.Int))) toScanStateDescSet :: Prelude.Int -> ScanState.ScanStateDesc -> ScanStateDescSet toScanStateDescSet maxReg sd = Build_ScanStateDescSet (ScanState.nextInterval maxReg sd) (LinearScan.Utils.vmap (ScanState.nextInterval maxReg sd) (\x -> Interval.getIntervalDesc ( x)) (ScanState.intervals maxReg sd)) (LinearScan.Utils.vmap maxReg (\mx -> case mx of { Prelude.Just x -> Prelude.Just (Interval.getIntervalDesc ( x)); Prelude.Nothing -> Prelude.Nothing}) (ScanState.fixedIntervals maxReg sd)) (Prelude.map (\i -> (,) ( (Prelude.fst i)) (Prelude.snd i)) (ScanState.unhandled maxReg sd)) (Prelude.map (\i -> (,) ( (Prelude.fst i)) ( (Prelude.snd i))) (ScanState.active maxReg sd)) (Prelude.map (\i -> (,) ( (Prelude.fst i)) ( (Prelude.snd i))) (ScanState.inactive maxReg sd)) (Prelude.map (\i -> (,) ( (Prelude.fst i)) (Lib.option_map (\x -> x) (Prelude.snd i))) (ScanState.handled maxReg sd)) data Details blockType1 blockType2 = Build_Details (Prelude.Maybe ((,) Morph.SSError FinalStage)) (IntMap.IntMap LiveSets.BlockLiveSets) ([] blockType1) ([] blockType2) (Prelude.Maybe ScanStateDescSet) (Prelude.Maybe ScanStateDescSet) Loops.LoopState linearScan :: (Monad.Monad a1) -> Prelude.Int -> (Blocks.BlockInfo a1 a2 a3 a4 a5) -> (Blocks.OpInfo a1 a4 a5) -> ([] a2) -> ((Details a2 a3) -> a6) -> a1 linearScan dict maxReg binfo oinfo blocks k = Monad.bind dict (\z -> case z of { (,) loops blocks1 -> Monad.bind dict (\liveSets -> Monad.bind dict (\liveSets' -> Monad.bind dict (\ints -> case ints of { Prelude.Left err -> Monad.pure (Monad.is_applicative dict) (k (Build_Details (Prelude.Just ((,) err BuildingIntervalsFailed)) liveSets' blocks1 [] Prelude.Nothing Prelude.Nothing loops)); Prelude.Right ssig -> let { opCount = (Prelude.succ) (Blocks.countOps dict binfo blocks1)} in case Allocate.walkIntervals maxReg ( ssig) opCount of { Prelude.Left p -> case p of { (,) err ssig' -> Monad.pure (Monad.is_applicative dict) (k (Build_Details (Prelude.Just ((,) err AllocatingRegistersFailed)) liveSets' blocks1 [] (Prelude.Just (toScanStateDescSet maxReg ( ssig))) (Prelude.Just (toScanStateDescSet maxReg ( ssig'))) loops))}; Prelude.Right ssig' -> let { sd = Allocate.finalizeScanState maxReg ( ssig') (Ssrnat.double opCount)} in let {allocs = Allocate.determineAllocations maxReg sd} in Monad.bind dict (\mappings -> Monad.bind dict (\blocks2 -> Monad.pure (Monad.is_applicative dict) (k (Build_Details Prelude.Nothing liveSets' blocks1 blocks2 (Prelude.Just (toScanStateDescSet maxReg ( ssig))) (Prelude.Just (toScanStateDescSet maxReg sd)) loops))) (Assign.assignRegNum maxReg dict binfo oinfo allocs liveSets' mappings blocks1)) (Resolve.resolveDataFlow maxReg dict binfo allocs blocks1 liveSets')}}) (Build.buildIntervals maxReg dict binfo oinfo blocks1 loops liveSets')) (LiveSets.computeGlobalLiveSetsRecursively dict binfo blocks1 liveSets)) (LiveSets.computeLocalLiveSets maxReg dict binfo oinfo blocks1)}) (Loops.computeBlockOrder dict binfo blocks)