Skip to content

Commit

Permalink
Share dependencyInfo in data-dependencies (#11620)
Browse files Browse the repository at this point in the history
No need to recompute this everytime given that the dependencies do not change.

changelog_begin
changelog_end
  • Loading branch information
cocreature authored Nov 10, 2021
1 parent 4eed1d9 commit d0c313d
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

module DA.Daml.Compiler.DataDependencies
( Config (..)
, buildDependencyInfo
, generateSrcPkgFromLf
, prefixDependencyModule
) where
Expand Down Expand Up @@ -73,8 +74,8 @@ data Config = Config
, configStablePackages :: MS.Map LF.PackageId UnitId
-- ^ map from a package id of a stable package to the unit id
-- of the corresponding package, i.e., daml-prim/daml-stdlib.
, configDependencyPackages :: Set LF.PackageId
-- ^ set of package ids for dependencies (not data-dependencies)
, configDependencyInfo :: DependencyInfo
-- ^ Information about dependencies (not data-dependencies)
, configSdkPrefix :: [T.Text]
-- ^ prefix to use for current SDK in data-dependencies
}
Expand All @@ -87,11 +88,8 @@ data Env = Env
-- ^ World built from dependencies, stable packages, and current package.
, envHiddenRefMap :: HMS.HashMap Ref Bool
-- ^ Set of references that should be hidden, not exposed.
, envDepClassMap :: DepClassMap
-- ^ Map of typeclasses from dependencies.
, envDepInstances :: MS.Map LF.TypeSynName [LF.Qualified ExpandedType]
-- ^ Map of instances from dependencies.
-- We only store the name since the real check happens in `isDuplicate`.
, envDependencyInfo :: DependencyInfo
-- ^ Information about dependencies (as opposed to data-dependencies)
, envMod :: LF.Module
-- ^ The module under consideration.
}
Expand Down Expand Up @@ -120,6 +118,14 @@ worldLfVersion = LF.packageLfVersion . LF.getWorldSelf
envLfVersion :: Env -> LF.Version
envLfVersion = worldLfVersion . envWorld

data DependencyInfo = DependencyInfo
{ depClassMap :: !DepClassMap
-- ^ Map of typeclasses from dependencies.
, depInstances :: !(MS.Map LF.TypeSynName [LF.Qualified ExpandedType])
-- ^ Map of instances from dependencies.
-- We only store the name since the real check happens in `isDuplicate`.
}

-- | Type classes coming from dependencies. This maps a (module, synonym)
-- name pair to a corresponding dependency package id and synonym type (closed over synonym variables).
newtype DepClassMap = DepClassMap
Expand All @@ -128,21 +134,26 @@ newtype DepClassMap = DepClassMap
(LF.PackageId, ExpandedType)
}

buildDepClassMap :: Config -> LF.World -> DepClassMap
buildDepClassMap Config{..} world = DepClassMap $ MS.fromList
buildDependencyInfo :: [LF.ExternalPackage] -> LF.World -> DependencyInfo
buildDependencyInfo deps world =
DependencyInfo
{ depClassMap = buildDepClassMap deps world
, depInstances = buildDepInstances deps world
}

buildDepClassMap :: [LF.ExternalPackage] -> LF.World -> DepClassMap
buildDepClassMap deps world = DepClassMap $ MS.fromList
[ ((moduleName, synName), (packageId, synTy))
| packageId <- Set.toList configDependencyPackages
, Just LF.Package{..} <- [MS.lookup packageId configPackages]
| LF.ExternalPackage packageId LF.Package{..} <- deps
, LF.Module{..} <- NM.toList packageModules
, dsyn@LF.DefTypeSyn{..} <- NM.toList moduleSynonyms
, let synTy = ExpandedType (panicOnError $ LF.runGamma world (worldLfVersion world) $ LF.expandTypeSynonyms $ closedSynType dsyn)
]

buildDepInstances :: Config -> LF.World -> MS.Map LF.TypeSynName [LF.Qualified ExpandedType]
buildDepInstances Config{..} world = MS.fromListWith (<>)
buildDepInstances :: [LF.ExternalPackage] -> LF.World -> MS.Map LF.TypeSynName [LF.Qualified ExpandedType]
buildDepInstances deps world = MS.fromListWith (<>)
[ (clsName, [LF.Qualified (LF.PRImport packageId) moduleName ty])
| packageId <- Set.toList configDependencyPackages
, Just LF.Package{..} <- [MS.lookup packageId configPackages]
| LF.ExternalPackage packageId LF.Package{..} <- deps
, LF.Module{..} <- NM.toList packageModules
, dval@LF.DefValue{..} <- NM.toList moduleValues
, Just dfun <- [getDFunSig dval]
Expand All @@ -153,7 +164,7 @@ buildDepInstances Config{..} world = MS.fromListWith (<>)
envLookupDepClass :: LF.TypeSynName -> Env -> Maybe (LF.PackageId, ExpandedType)
envLookupDepClass synName env =
let modName = LF.moduleName (envMod env)
classMap = unDepClassMap (envDepClassMap env)
classMap = unDepClassMap (depClassMap $ envDependencyInfo env)
in MS.lookup (modName, synName) classMap

-- | Determine whether two type synonym definitions are similar enough to
Expand Down Expand Up @@ -518,7 +529,7 @@ generateSrcFromLf env = noLoc mod
Just dfunSig <- [getDFunSig dval]
guard (shouldExposeInstance dval)
let clsName = LF.qualObject $ dfhName $ dfsHead dfunSig
case find (isDuplicate env (snd dvalBinder) . LF.qualObject) (MS.findWithDefault [] clsName $ envDepInstances env) of
case find (isDuplicate env (snd dvalBinder) . LF.qualObject) (MS.findWithDefault [] clsName $ depInstances $ envDependencyInfo env) of
Just qualInstance ->
-- If the instance already exists, we still
-- need to import it so that we can refer to it from other
Expand Down Expand Up @@ -1051,8 +1062,7 @@ generateSrcPkgFromLf envConfig pkg = do
where
env envMod = Env {..}
envQualifyThisModule = False
envDepClassMap = buildDepClassMap envConfig envWorld
envDepInstances = buildDepInstances envConfig envWorld
envDependencyInfo = configDependencyInfo envConfig
envWorld = buildWorld envConfig
envHiddenRefMap = buildHiddenRefMap envConfig envWorld
header =
Expand Down
14 changes: 10 additions & 4 deletions compiler/damlc/lib/DA/Cli/Damlc/Packaging.hs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ createProjectPackageDb projectRoot (disableScenarioService -> opts) modulePrefix

Logger.logDebug loggerH "Building dependency package graph"

let (depGraph, vertexToNode) = buildLfPackageGraph dalfsFromDataDependencies stablePkgs dependenciesInPkgDb
let (depGraph, vertexToNode) = buildLfPackageGraph (optDamlLfVersion opts) dalfsFromDataDependencies stablePkgs dependenciesInPkgDb


validatedModulePrefixes <- either exitWithError pure (prefixModules modulePrefixes (dalfsFromDependencies <> dalfsFromDataDependencies))
Expand Down Expand Up @@ -430,13 +430,14 @@ lfVersionString = DA.Pretty.renderPretty

-- | The graph will have an edge from package A to package B if A depends on B.
buildLfPackageGraph
:: [DecodedDalf]
:: LF.Version
-> [DecodedDalf]
-> MS.Map (UnitId, LF.ModuleName) LF.DalfPackage
-> MS.Map UnitId LF.DalfPackage
-> ( Graph
, Vertex -> (PackageNode, LF.PackageId)
)
buildLfPackageGraph pkgs stablePkgs dependencyPkgs = (depGraph, vertexToNode')
buildLfPackageGraph targetLfVersion pkgs stablePkgs dependencyPkgs = (depGraph, vertexToNode')
where
-- mapping from package id's to unit id's. if the same package is imported with
-- different unit id's, we would loose a unit id here.
Expand Down Expand Up @@ -467,12 +468,17 @@ buildLfPackageGraph pkgs stablePkgs dependencyPkgs = (depGraph, vertexToNode')
-- We don’t care about outgoing edges.
(node, key, _keys) -> (node, key)

dependencyInfo =
buildDependencyInfo
(map LF.dalfPackagePkg $ MS.elems dependencyPkgs)
(LF.initWorld (map (uncurry LF.ExternalPackage) (MS.toList packages)) targetLfVersion)

config pkgId unitId = DataDeps.Config
{ configPackages = packages
, configGetUnitId = getUnitId unitId pkgMap
, configSelfPkgId = pkgId
, configStablePackages = MS.fromList [ (LF.dalfPackageId dalfPkg, unitId) | ((unitId, _), dalfPkg) <- MS.toList stablePkgs ]
, configDependencyPackages = Set.fromList $ map LF.dalfPackageId $ MS.elems dependencyPkgs
, configDependencyInfo = dependencyInfo
, configSdkPrefix = [T.pack currentSdkPrefix]
}

Expand Down

0 comments on commit d0c313d

Please sign in to comment.