summaryrefslogtreecommitdiff
path: root/compiler/GHC/CmmToLlvm
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2020-06-23 15:01:25 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-07-12 02:53:55 -0400
commitc4de6a7a5c6433ae8c4df8a9fa09fbd9f3bbd0bf (patch)
treea7514919b3df80af5f09cbcdfac3d4fab25a77d2 /compiler/GHC/CmmToLlvm
parentde139cc496c0e0110e252a1208ae346f47f8061e (diff)
downloadhaskell-c4de6a7a5c6433ae8c4df8a9fa09fbd9f3bbd0bf.tar.gz
Give Uniq[D]FM a phantom type for its key.
This fixes #17667 and should help to avoid such issues going forward. The changes are mostly mechanical in nature. With two notable exceptions. * The register allocator. The register allocator references registers by distinct uniques. However they come from the types of VirtualReg, Reg or Unique in various places. As a result we sometimes cast the key type of the map and use functions which operate on the now typed map but take a raw Unique as actual key. The logic itself has not changed it just becomes obvious where we do so now. * <Type>Env Modules. As an example a ClassEnv is currently queried using the types `Class`, `Name`, and `TyCon`. This is safe since for a distinct class value all these expressions give the same unique. getUnique cls getUnique (classTyCon cls) getUnique (className cls) getUnique (tcName $ classTyCon cls) This is for the most part contained within the modules defining the interface. However it requires us to play dirty when we are given a `Name` to lookup in a `UniqFM Class a` map. But again the logic did not change and it's for the most part hidden behind the Env Module. Some of these cases could be avoided by refactoring but this is left for future work. We also bump the haddock submodule as it uses UniqFM.
Diffstat (limited to 'compiler/GHC/CmmToLlvm')
-rw-r--r--compiler/GHC/CmmToLlvm/Base.hs12
1 files changed, 6 insertions, 6 deletions
diff --git a/compiler/GHC/CmmToLlvm/Base.hs b/compiler/GHC/CmmToLlvm/Base.hs
index 7f60d660cb..ead3572a79 100644
--- a/compiler/GHC/CmmToLlvm/Base.hs
+++ b/compiler/GHC/CmmToLlvm/Base.hs
@@ -305,7 +305,7 @@ data LlvmEnv = LlvmEnv
, envOutput :: BufHandle -- ^ Output buffer
, envMask :: !Char -- ^ Mask for creating unique values
, envFreshMeta :: MetaId -- ^ Supply of fresh metadata IDs
- , envUniqMeta :: UniqFM MetaId -- ^ Global metadata nodes
+ , envUniqMeta :: UniqFM Unique MetaId -- ^ Global metadata nodes
, envFunMap :: LlvmEnvMap -- ^ Global functions so far, with type
, envAliases :: UniqSet LMString -- ^ Globals that we had to alias, see [Llvm Forward References]
, envUsedVars :: [LlvmVar] -- ^ Pointers to be added to llvm.used (see @cmmUsedLlvmGens@)
@@ -315,7 +315,7 @@ data LlvmEnv = LlvmEnv
, envStackRegs :: [GlobalReg] -- ^ Non-constant registers (alloca'd in the function prelude)
}
-type LlvmEnvMap = UniqFM LlvmType
+type LlvmEnvMap = UniqFM Unique LlvmType
-- | The Llvm monad. Wraps @LlvmEnv@ state as well as the @IO@ monad
newtype LlvmM a = LlvmM { runLlvmM :: LlvmEnv -> IO (a, LlvmEnv) }
@@ -397,13 +397,13 @@ withClearVars m = LlvmM $ \env -> do
-- | Insert variables or functions into the environment.
varInsert, funInsert :: Uniquable key => key -> LlvmType -> LlvmM ()
-varInsert s t = modifyEnv $ \env -> env { envVarMap = addToUFM (envVarMap env) s t }
-funInsert s t = modifyEnv $ \env -> env { envFunMap = addToUFM (envFunMap env) s t }
+varInsert s t = modifyEnv $ \env -> env { envVarMap = addToUFM (envVarMap env) (getUnique s) t }
+funInsert s t = modifyEnv $ \env -> env { envFunMap = addToUFM (envFunMap env) (getUnique s) t }
-- | Lookup variables or functions in the environment.
varLookup, funLookup :: Uniquable key => key -> LlvmM (Maybe LlvmType)
-varLookup s = getEnv (flip lookupUFM s . envVarMap)
-funLookup s = getEnv (flip lookupUFM s . envFunMap)
+varLookup s = getEnv (flip lookupUFM (getUnique s) . envVarMap)
+funLookup s = getEnv (flip lookupUFM (getUnique s) . envFunMap)
-- | Set a register as allocated on the stack
markStackReg :: GlobalReg -> LlvmM ()