From ef879d153637a764675e8bd18d6074bb2a7ca2c6 Mon Sep 17 00:00:00 2001 From: andy <unknown> Date: Sun, 11 Jun 2000 08:12:02 +0000 Subject: [PATCH] [project @ 2000-06-11 08:12:02 by andy] Adding change that handles trivial use of primitives (compares, integer arithmetic, etc) better when generating Java. --- ghc/compiler/javaGen/JavaGen.lhs | 150 ++++++++++++++++++++++++++++--- 1 file changed, 136 insertions(+), 14 deletions(-) diff --git a/ghc/compiler/javaGen/JavaGen.lhs b/ghc/compiler/javaGen/JavaGen.lhs index 5af2b0a3b376..e3a978d7ac4f 100644 --- a/ghc/compiler/javaGen/JavaGen.lhs +++ b/ghc/compiler/javaGen/JavaGen.lhs @@ -43,7 +43,8 @@ module JavaGen( javaGen ) where import Java import Literal ( Literal(..) ) -import Id ( Id, isDataConId_maybe, isId, idName, isDeadBinder, idPrimRep ) +import Id ( Id, isDataConId_maybe, isId, idName, isDeadBinder, idPrimRep + , isPrimOpId_maybe ) import Name ( NamedThing(..), getOccString, isGlobalName , nameModule ) import PrimRep ( PrimRep(..) ) @@ -54,11 +55,15 @@ import qualified CoreSyn import CoreSyn ( CoreBind, CoreExpr, CoreAlt, CoreBndr, Bind(..), Alt, AltCon(..), collectBinders, isValArg ) +import TysWiredIn ( boolTy, trueDataCon, falseDataCon ) import qualified CoreUtils import Module ( Module, moduleString ) import TyCon ( TyCon, isDataTyCon, tyConDataCons ) import Outputable +import Maybe +import PrimOp + #include "HsVersions.h" \end{code} @@ -216,7 +221,8 @@ javaVar v | isGlobalName (idName v) = mkNew (javaIdType v) [] javaLit :: Literal.Literal -> Expr javaLit (MachInt i) = Literal (IntLit (fromInteger i)) -javaLit (MachChar c) = Literal (CharLit c) +javaLit (MachChar c) = Literal (CharLit c) +javaLit (MachStr fs) = Literal (StringLit (_UNPK_ fs)) javaLit other = pprPanic "javaLit" (ppr other) -- Pass in the 'shape' of the result. @@ -245,13 +251,28 @@ javaCase :: (Expr -> Statement) -> CoreExpr -> Id -> [CoreAlt] -> [Statement] -- } else return null javaCase r e x alts - -- TODO: This will need to map prims to "haskell.runtime.Value". - = javaArg Nothing e ++ + | isIfThenElse && isPrimCmp = + javaIfThenElse r (fromJust maybePrim) tExpr fExpr + | otherwise = + javaArg Nothing e ++ [ var [Final] (javaName x) (whnf primRep (vmPOP (primRepToType primRep))) , IfThenElse (map mk_alt alts) (Just (Return javaNull)) ] where + isIfThenElse = CoreUtils.exprType e == boolTy + -- also need to check that x is not free in + -- any of the branches. + maybePrim = findCmpPrim e [] + isPrimCmp = isJust maybePrim + tExpr = matches trueDataCon alts + fExpr = matches falseDataCon alts + + matches con [] = error "no match for true or false branch of if/then/else" + matches con ((DataAlt d,[],rhs):rest) | con == d = rhs + matches con ((DEFAULT,[],rhs):_) = rhs + matches con (other:rest) = matches con rest + primRep = idPrimRep x whnf PtrRep = vmWHNF -- needs evaluation whnf _ = id @@ -264,6 +285,7 @@ javaCase r e x alts eqLit (MachInt n) = Op (Literal (IntLit n)) + "==" (Var (javaName x)) eqLit (MachChar n) = Op (Literal (CharLit n)) @@ -279,6 +301,23 @@ javaCase r e x alts , not (isDeadBinder b) ] +javaIfThenElse r cmp tExpr fExpr +{- + - Now what we need to do is generate code for the if/then/else. + - [all arguments are already check for simpleness (Var or Lit).] + - + - if (<prim> arg1 arg2 arg3 ...) { + - trueCode + - } else { + - falseCode + - } + -} + = [IfThenElse [(cmp,j_tExpr)] (Just j_fExpr)] + where + j_tExpr, j_fExpr :: Statement + j_tExpr = Block (javaExpr r tExpr) + j_fExpr = Block (javaExpr r fExpr) + javaBind (NonRec x rhs) {- x = ...rhs_x... @@ -355,6 +394,7 @@ javaApp r (CoreSyn.Var f) as (javaPops as) Nothing)] ; other -> -- Not a saturated constructor + -- TODO: case isPrimOpId_maybe java_apply r (CoreSyn.Var f) as } @@ -384,14 +424,16 @@ javaPops args = [ vmPOP (primRepToType (Type.typePrimRep (CoreUtils.exprType a)) -- pushing onto the stack (via one of the VM.PUSH* commands) -- the argument, perhaps thunked. --- Later: this might take an argument that allows assignment --- into a variable rather than pushing onto the stack. - javaArg :: Maybe Name -> CoreExpr -> [Statement] javaArg _ (CoreSyn.Type t) = pprPanic "javaArg" (ppr t) javaArg ret e - | isPrim primty && CoreUtils.exprIsTrivial e = javaExpr push e - | isPrim primty = + | isPrimCall = [push (fromJust maybePrim)] + -- This is a shortcut, + -- basic names and literals do not need a code block + -- to compute the value. + -- (Perhaps String literals might??) + | isPrim primty && exprIsTrivial e = javaExpr push e + | isPrim primty = let expr = javaExpr vmRETURN e code = access (vmWHNF (newCode expr)) (primRepToType primty) in [push code] @@ -399,22 +441,32 @@ javaArg ret e let expr = javaExpr vmRETURN e code = newCode expr code' = if CoreUtils.exprIsValue e - || CoreUtils.exprIsTrivial e + || exprIsTrivial e || isPrim primty then code else newThunk code in [push code'] where + maybePrim = findFnPrim e [] + isPrimCall = isJust maybePrim + push e = case ret of Just name -> var [Final] name e Nothing -> vmPUSH e corety = CoreUtils.exprType e primty = Type.typePrimRep corety - isPrim PtrRep = False - isPrim IntRep = True - isPrim CharRep = True + isPrim PtrRep = False -- only this needs updated + isPrim _ = True coreTypeToType = primRepToType . Type.typePrimRep . CoreUtils.exprType + +-- The GOO version of this function +exprIsTrivial (CoreSyn.Var v) + | Just op <- isPrimOpId_maybe v = primOpIsDupable op + | otherwise = True +exprIsTrivial (CoreSyn.Lit (MachInt _)) = True +exprIsTrivial (CoreSyn.Lit (MachChar _)) = True +exprIsTrivial other = False \end{code} %************************************************************************ @@ -487,6 +539,70 @@ newThunk e = New thunkType [e] Nothing vmArg :: Parameter vmArg = Parameter [Final] vmName + +{- +data HaskPrim + = FunPrimOp Int -- number of arguments expected + ([Expr] -> Expr) -- mapping from arguments + | CmpPrimOp -- to prim call + +getPrimTrans :: +-} + +-- This is called with boolean compares, checking +-- to see if we can do an obvious shortcut. +-- If there is, we return a (GOO) function for doing this, + +-- so if, we have case (#< x y) of { True -> e1; False -> e2 }, +-- we will call splitCmpFn with (#< x y) +-- This return Right (Op x "<" y) + +findCmpPrim :: CoreExpr -> [Expr] -> Maybe Expr +findCmpPrim (CoreSyn.App f a) as = + case a of + CoreSyn.Var v -> findCmpPrim f (javaVar v:as) + CoreSyn.Lit l -> findCmpPrim f (javaLit l:as) + _ -> Nothing +findCmpPrim (CoreSyn.Var p) as = + case isPrimOpId_maybe p of + Just prim -> find_cmp_prim prim as + Nothing -> Nothing +findCmpPrim _ as = Nothing + +find_cmp_prim cmpPrim args@[a,b] = + case cmpPrim of + IntGtOp -> fn ">" + IntGeOp -> fn ">=" + IntEqOp -> fn "==" + IntNeOp -> fn "/=" + IntLtOp -> fn "<" + IntLeOp -> fn "<=" + _ -> Nothing + where + fn op = Just (Op a op b) +find_cmp_prim _ _ = Nothing + +findFnPrim :: CoreExpr -> [Expr] -> Maybe Expr +findFnPrim (CoreSyn.App f a) as = + case a of + CoreSyn.Var v -> findFnPrim f (javaVar v:as) + CoreSyn.Lit l -> findFnPrim f (javaLit l:as) + _ -> Nothing +findFnPrim (CoreSyn.Var p) as = + case isPrimOpId_maybe p of + Just prim -> find_fn_prim prim as + Nothing -> Nothing +findFnPrim _ as = Nothing + +find_fn_prim cmpPrim args@[a,b] = + case cmpPrim of + IntAddOp -> fn "+" + IntSubOp -> fn "-" + IntMulOp -> fn "*" + _ -> Nothing + where + fn op = Just (Op a op b) +find_fn_prim _ _ = Nothing \end{code} %************************************************************************ @@ -501,11 +617,15 @@ exprType (Literal lit) = litType lit exprType (Cast t _) = t exprType (New t _ _) = t exprType (Call _ (Name _ t) _) = t +exprType (Op _ op _) | op `elem` ["==","/=","<","<=","=>",">"] + = PrimType PrimBoolean +exprType (Op x op _) | op `elem` ["+","-","*"] + = exprType x exprType expr = error ("can't figure out an expression type: " ++ show expr) litType (IntLit i) = PrimType PrimInt litType (CharLit i) = PrimType PrimChar -litType (StringLit i) = error "<string?>" +litType (StringLit i) = stringType \end{code} %************************************************************************ @@ -626,6 +746,8 @@ primRepToType ::PrimRep -> Type primRepToType PtrRep = objectType primRepToType IntRep = inttype primRepToType CharRep = chartype +primRepToType AddrRep = objectType +primRepToType other = pprPanic "primRepToType" (ppr other) -- The function that makes the constructor name javaConstrWkrType :: DataCon -> Type -- GitLab