diff options
Diffstat (limited to 'compiler/GHC/CoreToByteCode.hs')
-rw-r--r-- | compiler/GHC/CoreToByteCode.hs | 133 |
1 files changed, 74 insertions, 59 deletions
diff --git a/compiler/GHC/CoreToByteCode.hs b/compiler/GHC/CoreToByteCode.hs index 99a90c92e9..1cac00320f 100644 --- a/compiler/GHC/CoreToByteCode.hs +++ b/compiler/GHC/CoreToByteCode.hs @@ -204,19 +204,19 @@ newtype ByteOff = ByteOff Int newtype WordOff = WordOff Int deriving (Enum, Eq, Integral, Num, Ord, Real) -wordsToBytes :: DynFlags -> WordOff -> ByteOff -wordsToBytes dflags = fromIntegral . (* wORD_SIZE dflags) . fromIntegral +wordsToBytes :: Platform -> WordOff -> ByteOff +wordsToBytes platform = fromIntegral . (* platformWordSizeInBytes platform) . fromIntegral -- Used when we know we have a whole number of words -bytesToWords :: DynFlags -> ByteOff -> WordOff -bytesToWords dflags (ByteOff bytes) = - let (q, r) = bytes `quotRem` (wORD_SIZE dflags) +bytesToWords :: Platform -> ByteOff -> WordOff +bytesToWords platform (ByteOff bytes) = + let (q, r) = bytes `quotRem` (platformWordSizeInBytes platform) in if r == 0 then fromIntegral q else panic $ "GHC.CoreToByteCode.bytesToWords: bytes=" ++ show bytes -wordSize :: DynFlags -> ByteOff -wordSize dflags = ByteOff (wORD_SIZE dflags) +wordSize :: Platform -> ByteOff +wordSize platform = ByteOff (platformWordSizeInBytes platform) type Sequel = ByteOff -- back off to this depth before ENTER @@ -381,6 +381,7 @@ schemeR_wrk fvs nm original_body (args, body) = do dflags <- getDynFlags let + platform = targetPlatform dflags all_args = reverse args ++ fvs arity = length all_args -- all_args are the args in reverse order. We're compiling a function @@ -389,14 +390,14 @@ schemeR_wrk fvs nm original_body (args, body) -- Stack arguments always take a whole number of words, we never pack -- them unlike constructor fields. - szsb_args = map (wordsToBytes dflags . idSizeW dflags) all_args + szsb_args = map (wordsToBytes platform . idSizeW dflags) all_args sum_szsb_args = sum szsb_args p_init = Map.fromList (zip all_args (mkStackOffsets 0 szsb_args)) -- make the arg bitmap bits = argBits dflags (reverse (map bcIdArgRep all_args)) bitmap_size = genericLength bits - bitmap = mkBitmap dflags bits + bitmap = mkBitmap platform bits body_code <- schemeER_wrk sum_szsb_args p_init body emitBc (mkProtoBCO dflags nm body_code (Right original_body) @@ -410,7 +411,8 @@ schemeER_wrk d p rhs cc_arr <- getCCArray this_mod <- moduleName <$> getCurrentModule dflags <- getDynFlags - let idOffSets = getVarOffSets dflags d p fvs + let platform = targetPlatform dflags + let idOffSets = getVarOffSets platform d p fvs let breakInfo = CgBreakInfo { cgb_vars = idOffSets , cgb_resty = exprType (deAnnotate' newRhs) @@ -425,8 +427,8 @@ schemeER_wrk d p rhs return $ breakInstr `consOL` code | otherwise = schemeE d 0 p rhs -getVarOffSets :: DynFlags -> StackDepth -> BCEnv -> [Id] -> [Maybe (Id, Word16)] -getVarOffSets dflags depth env = map getOffSet +getVarOffSets :: Platform -> StackDepth -> BCEnv -> [Id] -> [Maybe (Id, Word16)] +getVarOffSets platform depth env = map getOffSet where getOffSet id = case lookupBCEnv_maybe id env of Nothing -> Nothing @@ -439,7 +441,7 @@ getVarOffSets dflags depth env = map getOffSet -- BRK_FUN in Interpreter.c In any case, this is used only when -- we trigger a breakpoint. let !var_depth_ws = - trunc16W $ bytesToWords dflags (depth - offset) + 2 + trunc16W $ bytesToWords platform (depth - offset) + 2 in Just (id, var_depth_ws) truncIntegral16 :: Integral a => a -> Word16 @@ -482,10 +484,11 @@ returnUnboxedAtom -- Heave it on the stack, SLIDE, and RETURN. returnUnboxedAtom d s p e e_rep = do dflags <- getDynFlags + let platform = targetPlatform dflags (push, szb) <- pushAtom d p e - return (push -- value onto stack - `appOL` mkSlideB dflags szb (d - s) -- clear to sequel - `snocOL` RETURN_UBX e_rep) -- go + return (push -- value onto stack + `appOL` mkSlideB platform szb (d - s) -- clear to sequel + `snocOL` RETURN_UBX e_rep) -- go -- Compile code to apply the given expression to the remaining args -- on the stack, returning a HNF. @@ -516,7 +519,8 @@ schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body)) -- Just allocate the constructor and carry on alloc_code <- mkConAppCode d s p data_con args_r_to_l dflags <- getDynFlags - let !d2 = d + wordSize dflags + let platform = targetPlatform dflags + let !d2 = d + wordSize platform body_code <- schemeE d2 s (Map.insert x d2 p) body return (alloc_code `appOL` body_code) @@ -526,6 +530,7 @@ schemeE d s p (AnnLet binds (_,body)) = do dflags <- getDynFlags let (xs,rhss) = case binds of AnnNonRec x rhs -> ([x],[rhs]) AnnRec xs_n_rhss -> unzip xs_n_rhss + platform = targetPlatform dflags n_binds = genericLength xs fvss = map (fvsToEnv p' . fst) rhss @@ -544,9 +549,9 @@ schemeE d s p (AnnLet binds (_,body)) = do -- are ptrs, so all have size 1 word. d' and p' reflect the stack -- after the closures have been allocated in the heap (but not -- filled in), and pointers to them parked on the stack. - offsets = mkStackOffsets d (genericReplicate n_binds (wordSize dflags)) + offsets = mkStackOffsets d (genericReplicate n_binds (wordSize platform)) p' = Map.insertList (zipE xs' offsets) p - d' = d + wordsToBytes dflags n_binds + d' = d + wordsToBytes platform n_binds zipE = zipEqual "schemeE" -- ToDo: don't build thunks for things with no free variables @@ -831,8 +836,9 @@ schemeT d s p app | Just con <- maybe_saturated_dcon = do alloc_con <- mkConAppCode d s p con args_r_to_l dflags <- getDynFlags + let platform = targetPlatform dflags return (alloc_con `appOL` - mkSlideW 1 (bytesToWords dflags $ d - s) `snocOL` + mkSlideW 1 (bytesToWords platform $ d - s) `snocOL` ENTER) -- Case 4: Tail call of function @@ -875,6 +881,7 @@ mkConAppCode orig_d _ p con args_r_to_l = where app_code = do dflags <- getDynFlags + let platform = targetPlatform dflags -- The args are initially in reverse order, but mkVirtHeapOffsets -- expects them to be left-to-right. @@ -894,7 +901,7 @@ mkConAppCode orig_d _ p con args_r_to_l = more_push_code <- do_pushery (d + arg_bytes) args return (push `appOL` more_push_code) do_pushery !d [] = do - let !n_arg_words = trunc16W $ bytesToWords dflags (d - orig_d) + let !n_arg_words = trunc16W $ bytesToWords platform (d - orig_d) return (unitOL (PACK con n_arg_words)) -- Push on the stack in the reverse order. @@ -928,15 +935,17 @@ doTailCall init_d s p fn args = do_pushes init_d args (map atomRep args) ASSERT( null reps ) return () (push_fn, sz) <- pushAtom d p (AnnVar fn) dflags <- getDynFlags - ASSERT( sz == wordSize dflags ) return () - let slide = mkSlideB dflags (d - init_d + wordSize dflags) (init_d - s) + let platform = targetPlatform dflags + ASSERT( sz == wordSize platform ) return () + let slide = mkSlideB platform (d - init_d + wordSize platform) (init_d - s) return (push_fn `appOL` (slide `appOL` unitOL ENTER)) do_pushes !d args reps = do let (push_apply, n, rest_of_reps) = findPushSeq reps (these_args, rest_of_args) = splitAt n args (next_d, push_code) <- push_seq d these_args dflags <- getDynFlags - instrs <- do_pushes (next_d + wordSize dflags) rest_of_args rest_of_reps + let platform = targetPlatform dflags + instrs <- do_pushes (next_d + wordSize platform) rest_of_args rest_of_reps -- ^^^ for the PUSH_APPLY_ instruction return (push_code `appOL` (push_apply `consOL` instrs)) @@ -995,6 +1004,7 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple dflags <- getDynFlags hsc_env <- getHscEnv let + platform = targetPlatform dflags profiling | Just interp <- hsc_interp hsc_env = interpreterProfiled interp @@ -1005,21 +1015,21 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple -- When an alt is entered, it assumes the returned value is -- on top of the itbl. ret_frame_size_b :: StackDepth - ret_frame_size_b = 2 * wordSize dflags + ret_frame_size_b = 2 * wordSize platform -- The extra frame we push to save/restore the CCCS when profiling - save_ccs_size_b | profiling = 2 * wordSize dflags + save_ccs_size_b | profiling = 2 * wordSize platform | otherwise = 0 -- An unlifted value gets an extra info table pushed on top -- when it is returned. unlifted_itbl_size_b :: StackDepth unlifted_itbl_size_b | isAlgCase = 0 - | otherwise = wordSize dflags + | otherwise = wordSize platform -- depth of stack after the return value has been pushed d_bndr = - d + ret_frame_size_b + wordsToBytes dflags (idSizeW dflags bndr) + d + ret_frame_size_b + wordsToBytes platform (idSizeW dflags bndr) -- depth of stack after the extra info table for an unboxed return -- has been pushed, if any. This is the stack depth at the @@ -1061,7 +1071,7 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple ] size = WordOff tot_wds - stack_bot = d_alts + wordsToBytes dflags size + stack_bot = d_alts + wordsToBytes platform size -- convert offsets from Sp into offsets into the virtual stack p' = Map.insertList @@ -1111,10 +1121,10 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple -- really want a bitmap up to depth (d-s). This affects compilation of -- case-of-case expressions, which is the only time we can be compiling a -- case expression with s /= 0. - bitmap_size = trunc16W $ bytesToWords dflags (d - s) + bitmap_size = trunc16W $ bytesToWords platform (d - s) bitmap_size' :: Int bitmap_size' = fromIntegral bitmap_size - bitmap = intsToReverseBitmap dflags bitmap_size'{-size-} + bitmap = intsToReverseBitmap platform bitmap_size'{-size-} (sort (filter (< bitmap_size') rel_slots)) where binds = Map.toList p @@ -1123,7 +1133,7 @@ doCase d s p (_,scrut) bndr alts is_unboxed_tuple rel_slots = nub $ map fromIntegral $ concatMap spread binds spread (id, offset) | isFollowableArg (bcIdArgRep id) = [ rel_offset ] | otherwise = [] - where rel_offset = trunc16W $ bytesToWords dflags (d - offset) + where rel_offset = trunc16W $ bytesToWords platform (d - offset) alt_stuff <- mapM codeAlt alts alt_final <- mkMultiBranch maybe_ncons alt_stuff @@ -1167,9 +1177,10 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l dflags <- getDynFlags let + platform = targetPlatform dflags -- useful constants addr_size_b :: ByteOff - addr_size_b = wordSize dflags + addr_size_b = wordSize platform -- Get the args on the stack, with tags and suitably -- dereferenced for the CCall. For each arg, return the @@ -1228,7 +1239,7 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l a_reps_sizeW = sum (map (repSizeWords dflags) a_reps_pushed_r_to_l) push_args = concatOL pushs_arg - !d_after_args = d0 + wordsToBytes dflags a_reps_sizeW + !d_after_args = d0 + wordsToBytes platform a_reps_sizeW a_reps_pushed_RAW | null a_reps_pushed_r_to_l || not (isVoidRep (head a_reps_pushed_r_to_l)) = panic "GHC.CoreToByteCode.generateCCall: missing or invalid World token?" @@ -1290,9 +1301,9 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l Just (LitLabel target mb_size IsFunction) where mb_size - | OSMinGW32 <- platformOS (targetPlatform dflags) + | OSMinGW32 <- platformOS platform , StdCallConv <- cconv - = Just (fromIntegral a_reps_sizeW * wORD_SIZE dflags) + = Just (fromIntegral a_reps_sizeW * platformWordSizeInBytes platform) | otherwise = Nothing @@ -1316,7 +1327,7 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l -- Push the return placeholder. For a call returning nothing, -- this is a V (tag). r_sizeW = repSizeWords dflags r_rep - d_after_r = d_after_Addr + wordsToBytes dflags r_sizeW + d_after_r = d_after_Addr + wordsToBytes platform r_sizeW push_r = if returns_void then nilOL @@ -1328,7 +1339,7 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l -- instruction needs to describe the chunk of stack containing -- the ccall args to the GC, so it needs to know how large it -- is. See comment in Interpreter.c with the CCALL instruction. - stk_offset = trunc16W $ bytesToWords dflags (d_after_r - s) + stk_offset = trunc16W $ bytesToWords platform (d_after_r - s) conv = case cconv of CCallConv -> FFICCall @@ -1340,8 +1351,8 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l -- address of this to the CCALL instruction. - let ffires = primRepToFFIType dflags r_rep - ffiargs = map (primRepToFFIType dflags) a_reps + let ffires = primRepToFFIType platform r_rep + ffiargs = map (primRepToFFIType platform) a_reps hsc_env <- getHscEnv token <- ioToBc $ iservCmd hsc_env (PrepFFI conv ffiargs ffires) recordFFIBc token @@ -1355,7 +1366,7 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l PlayRisky -> 0x2 -- slide and return - d_after_r_min_s = bytesToWords dflags (d_after_r - s) + d_after_r_min_s = bytesToWords platform (d_after_r - s) wrapup = mkSlideW (trunc16W r_sizeW) (d_after_r_min_s - r_sizeW) `snocOL` RETURN_UBX (toArgRep r_rep) --trace (show (arg1_offW, args_offW , (map argRepSizeW a_reps) )) $ @@ -1364,8 +1375,8 @@ generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l push_Addr `appOL` push_r `appOL` do_call `appOL` wrapup ) -primRepToFFIType :: DynFlags -> PrimRep -> FFIType -primRepToFFIType dflags r +primRepToFFIType :: Platform -> PrimRep -> FFIType +primRepToFFIType platform r = case r of VoidRep -> FFIVoid IntRep -> signed_word @@ -1377,10 +1388,9 @@ primRepToFFIType dflags r DoubleRep -> FFIDouble _ -> panic "primRepToFFIType" where - (signed_word, unsigned_word) - | wORD_SIZE dflags == 4 = (FFISInt32, FFIUInt32) - | wORD_SIZE dflags == 8 = (FFISInt64, FFIUInt64) - | otherwise = panic "primTyDescChar" + (signed_word, unsigned_word) = case platformWordSize platform of + PW4 -> (FFISInt32, FFIUInt32) + PW8 -> (FFISInt64, FFIUInt64) -- Make a dummy literal, to be used as a placeholder for FFI return -- values on the stack. @@ -1506,8 +1516,9 @@ implement_tagToId d s p arg names dflags <- getDynFlags let infos = zip4 labels (tail labels ++ [label_fail]) [0 ..] names + platform = targetPlatform dflags steps = map (mkStep label_exit) infos - slide_ws = bytesToWords dflags (d - s + arg_bytes) + slide_ws = bytesToWords platform (d - s + arg_bytes) return (push_arg `appOL` unitOL (PUSH_UBX LitNullAddr 1) @@ -1564,24 +1575,26 @@ pushAtom d p (AnnVar var) | Just primop <- isPrimOpId_maybe var = do - dflags <-getDynFlags - return (unitOL (PUSH_PRIMOP primop), wordSize dflags) + dflags <- getDynFlags + let platform = targetPlatform dflags + return (unitOL (PUSH_PRIMOP primop), wordSize platform) | Just d_v <- lookupBCEnv_maybe var p -- var is a local variable = do dflags <- getDynFlags + let platform = targetPlatform dflags let !szb = idSizeCon dflags var with_instr instr = do let !off_b = trunc16B $ d - d_v - return (unitOL (instr off_b), wordSize dflags) + return (unitOL (instr off_b), wordSize platform) case szb of 1 -> with_instr PUSH8_W 2 -> with_instr PUSH16_W 4 -> with_instr PUSH32_W _ -> do - let !szw = bytesToWords dflags szb - !off_w = trunc16W $ bytesToWords dflags (d - d_v) + szw - 1 + let !szw = bytesToWords platform szb + !off_w = trunc16W $ bytesToWords platform (d - d_v) + szw - 1 return (toOL (genericReplicate szw (PUSH_L off_w)), szb) -- d - d_v offset from TOS to the first slot of the object -- @@ -1598,16 +1611,18 @@ pushAtom d p (AnnVar var) fromIntegral $ ptrToWordPtr $ fromRemotePtr ptr Nothing -> do let sz = idSizeCon dflags var - MASSERT( sz == wordSize dflags ) + let platform = targetPlatform dflags + MASSERT( sz == wordSize platform ) return (unitOL (PUSH_G (getName var)), sz) pushAtom _ _ (AnnLit lit) = do dflags <- getDynFlags + let platform = targetPlatform dflags let code rep = let size_words = WordOff (argRepSizeW dflags rep) in return (unitOL (PUSH_UBX lit (trunc16W size_words)), - wordsToBytes dflags size_words) + wordsToBytes platform size_words) case lit of LitLabel _ _ _ -> code N @@ -1858,11 +1873,11 @@ unsupportedCConvException = throwGhcException (ProgramError ("Error: bytecode compiler can't handle some foreign calling conventions\n"++ " Workaround: use -fobject-code, or compile this module to .o separately.")) -mkSlideB :: DynFlags -> ByteOff -> ByteOff -> OrdList BCInstr -mkSlideB dflags !nb !db = mkSlideW n d +mkSlideB :: Platform -> ByteOff -> ByteOff -> OrdList BCInstr +mkSlideB platform !nb !db = mkSlideW n d where - !n = trunc16W $ bytesToWords dflags nb - !d = bytesToWords dflags db + !n = trunc16W $ bytesToWords platform nb + !d = bytesToWords platform db mkSlideW :: Word16 -> WordOff -> OrdList BCInstr mkSlideW !n !ws |