+
+data Repr = ProdRepr {
+ prod_components :: [Type]
+ , prod_tycon :: TyCon
+ , prod_data_con :: DataCon
+ , prod_arr_tycon :: TyCon
+ , prod_arr_data_con :: DataCon
+ }
+
+ | SumRepr {
+ sum_components :: [Repr]
+ , sum_tycon :: TyCon
+ , sum_arr_tycon :: TyCon
+ , sum_arr_data_con :: DataCon
+ }
+
+ | IdRepr Type
+
+ | VoidRepr {
+ void_tycon :: TyCon
+ , void_bottom :: CoreExpr
+ }
+
+ | EnumRepr {
+ enum_tycon :: TyCon
+ , enum_data_con :: DataCon
+ , enum_arr_tycon :: TyCon
+ , enum_arr_data_con :: DataCon
+ }
+
+voidRepr :: VM Repr
+voidRepr
+ = do
+ tycon <- builtin voidTyCon
+ var <- builtin voidVar
+ return $ VoidRepr {
+ void_tycon = tycon
+ , void_bottom = Var var
+ }
+
+{-
+enumRepr :: VM Repr
+enumRepr
+ = do
+ tycon <- builtin enumerationTyCon
+ let [data_con] = tyConDataCons tycon
+ (arr_tycon, _) <- parrayReprTyCon (mkTyConApp tycon [])
+ let [arr_data_con] = tyConDataCons arr_tycon
+
+ return $ EnumRepr {
+ enum_tycon = tycon
+ , enum_data_con = data_con
+ , enum_arr_tycon = arr_tycon
+ , enum_arr_data_con = arr_data_con
+ }
+-}
+
+unboxedProductRepr :: [Type] -> VM Repr
+unboxedProductRepr [] = voidRepr
+unboxedProductRepr [ty] = return $ IdRepr ty
+unboxedProductRepr tys = boxedProductRepr tys
+
+boxedProductRepr :: [Type] -> VM Repr
+boxedProductRepr tys
+ = do
+ tycon <- builtin (prodTyCon arity)
+ let [data_con] = tyConDataCons tycon
+
+ tys' <- mapM boxType tys
+ (arr_tycon, _) <- parrayReprTyCon $ mkTyConApp tycon tys'
+ let [arr_data_con] = tyConDataCons arr_tycon
+
+ return $ ProdRepr {
+ prod_components = tys
+ , prod_tycon = tycon
+ , prod_data_con = data_con
+ , prod_arr_tycon = arr_tycon
+ , prod_arr_data_con = arr_data_con
+ }
+ where
+ arity = length tys
+
+sumRepr :: [Repr] -> VM Repr
+sumRepr [] = voidRepr
+sumRepr [repr] = boxRepr repr
+sumRepr reprs
+ = do
+ tycon <- builtin (sumTyCon arity)
+ (arr_tycon, _) <- parrayReprTyCon
+ . mkTyConApp tycon
+ $ map reprType reprs
+
+ let [arr_data_con] = tyConDataCons arr_tycon
+
+ return $ SumRepr {
+ sum_components = reprs
+ , sum_tycon = tycon
+ , sum_arr_tycon = arr_tycon
+ , sum_arr_data_con = arr_data_con
+ }
+ where
+ arity = length reprs
+
+splitSumRepr :: Repr -> [Repr]
+splitSumRepr (SumRepr { sum_components = reprs }) = reprs
+splitSumRepr repr = [repr]
+
+boxRepr :: Repr -> VM Repr
+boxRepr (VoidRepr {}) = boxedProductRepr []
+boxRepr (IdRepr ty) = boxedProductRepr [ty]
+boxRepr repr = return repr
+
+reprType :: Repr -> Type
+reprType (ProdRepr { prod_tycon = tycon, prod_components = tys })
+ = mkTyConApp tycon tys
+reprType (SumRepr { sum_tycon = tycon, sum_components = reprs })
+ = mkTyConApp tycon (map reprType reprs)
+reprType (IdRepr ty) = ty
+reprType (VoidRepr { void_tycon = tycon }) = mkTyConApp tycon []
+reprType (EnumRepr { enum_tycon = tycon }) = mkTyConApp tycon []
+
+arrReprType :: Repr -> VM Type
+arrReprType = mkPArrayType . reprType
+
+arrShapeTys :: Repr -> VM [Type]
+arrShapeTys (SumRepr {}) = sumShapeTys
+arrShapeTys (ProdRepr {}) = return [intPrimTy]
+arrShapeTys (IdRepr _) = return []
+arrShapeTys (VoidRepr {}) = return [intPrimTy]
+arrShapeTys (EnumRepr {}) = sumShapeTys
+
+sumShapeTys :: VM [Type]
+sumShapeTys = do
+ int_arr <- builtin intPrimArrayTy
+ return [intPrimTy, int_arr, int_arr]
+
+
+arrShapeVars :: Repr -> VM [Var]
+arrShapeVars repr = mapM (newLocalVar (fsLit "sh")) =<< arrShapeTys repr
+
+replicateShape :: Repr -> CoreExpr -> CoreExpr -> VM [CoreExpr]
+replicateShape (ProdRepr {}) len _ = return [len]
+replicateShape (SumRepr {}) len tag = replicateSumShape len tag
+replicateShape (IdRepr _) _ _ = return []
+replicateShape (VoidRepr {}) len _ = return [len]
+replicateShape (EnumRepr {}) len tag = replicateSumShape len tag
+
+replicateSumShape :: CoreExpr -> CoreExpr -> VM [CoreExpr]
+replicateSumShape len tag
+ = do
+ rep <- builtin replicatePAIntPrimVar
+ up <- builtin upToPAIntPrimVar
+ return [len, Var rep `mkApps` [len, tag], Var up `App` len]
+
+arrSelector :: Repr -> [CoreExpr] -> VM (CoreExpr, CoreExpr, CoreExpr)
+arrSelector (SumRepr {}) [len, sel, is] = return (len, sel, is)
+arrSelector (EnumRepr {}) [len, sel, is] = return (len, sel, is)
+arrSelector _ _ = panic "arrSelector"
+
+emptyArrRepr :: Repr -> VM [CoreExpr]
+emptyArrRepr (SumRepr { sum_components = prods })
+ = liftM concat $ mapM emptyArrRepr prods
+emptyArrRepr (ProdRepr { prod_components = [] })
+ = return [Var unitDataConId]
+emptyArrRepr (ProdRepr { prod_components = tys })
+ = mapM emptyPA tys
+emptyArrRepr (IdRepr ty)
+ = liftM singleton $ emptyPA ty
+emptyArrRepr (VoidRepr { void_tycon = tycon })
+ = liftM singleton $ emptyPA (mkTyConApp tycon [])
+emptyArrRepr (EnumRepr {})
+ = return []
+
+arrReprTys :: Repr -> VM [Type]
+arrReprTys (SumRepr { sum_components = reprs })
+ = liftM concat $ mapM arrReprTys reprs
+arrReprTys (ProdRepr { prod_components = [] })
+ = return [unitTy]
+arrReprTys (ProdRepr { prod_components = tys })
+ = mapM mkPArrayType tys
+arrReprTys (IdRepr ty)
+ = liftM singleton $ mkPArrayType ty
+arrReprTys (VoidRepr { void_tycon = tycon })
+ = liftM singleton $ mkPArrayType (mkTyConApp tycon [])
+arrReprTys (EnumRepr {})
+ = return []
+
+arrReprTys' :: Repr -> VM [[Type]]
+arrReprTys' (SumRepr { sum_components = reprs })
+ = mapM arrReprTys reprs
+arrReprTys' repr = liftM singleton $ arrReprTys repr
+
+arrReprVars :: Repr -> VM [[Var]]
+arrReprVars repr
+ = mapM (mapM (newLocalVar (fsLit "rs"))) =<< arrReprTys' repr
+
+mkRepr :: TyCon -> VM Repr
+mkRepr vect_tc
+ | [tys] <- rep_tys = boxedProductRepr tys
+ -- removed: | all null rep_tys = enumRepr
+ | otherwise = sumRepr =<< mapM unboxedProductRepr rep_tys
+ where
+ rep_tys = map dataConRepArgTys $ tyConDataCons vect_tc
+