1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
module GHC.Llvm.MetaData where
import GHC.Prelude
import GHC.Llvm.Types
import GHC.Utils.Outputable
-- The LLVM Metadata System.
--
-- The LLVM metadata feature is poorly documented but roughly follows the
-- following design:
-- - Metadata can be constructed in a few different ways (See below).
-- - After which it can either be attached to LLVM statements to pass along
-- extra information to the optimizer and code generator OR specifically named
-- metadata has an affect on the whole module (i.e., linking behaviour).
--
--
-- # Constructing metadata
-- Metadata comes largely in three forms:
--
-- - Metadata expressions -- these are the raw metadata values that encode
-- information. They consist of metadata strings, metadata nodes, regular
-- LLVM values (both literals and references to global variables) and
-- metadata expressions (i.e., recursive data type). Some examples:
-- !{ !"hello", !0, i32 0 }
-- !{ !1, !{ i32 0 } }
--
-- - Metadata nodes -- global metadata variables that attach a metadata
-- expression to a number. For example:
-- !0 = !{ [<metadata expressions>] !}
--
-- - Named metadata -- global metadata variables that attach a metadata nodes
-- to a name. Used ONLY to communicated module level information to LLVM
-- through a meaningful name. For example:
-- !llvm.module.linkage = !{ !0, !1 }
--
--
-- # Using Metadata
-- Using metadata depends on the form it is in:
--
-- - Attach to instructions -- metadata can be attached to LLVM instructions
-- using a specific reference as follows:
-- %l = load i32* @glob, !nontemporal !10
-- %m = load i32* @glob, !nontemporal !{ i32 0, !{ i32 0 } }
-- Only metadata nodes or expressions can be attached, named metadata cannot.
-- Refer to LLVM documentation for which instructions take metadata and its
-- meaning.
--
-- - As arguments -- llvm functions can take metadata as arguments, for
-- example:
-- call void @llvm.dbg.value(metadata !{ i32 0 }, i64 0, metadata !1)
-- As with instructions, only metadata nodes or expressions can be attached.
--
-- - As a named metadata -- Here the metadata is simply declared in global
-- scope using a specific name to communicate module level information to LLVM.
-- For example:
-- !llvm.module.linkage = !{ !0, !1 }
--
-- | A reference to an un-named metadata node.
newtype MetaId = MetaId Int
deriving (Eq, Ord, Enum)
instance Outputable MetaId where
ppr (MetaId n) = char '!' <> int n
-- | LLVM metadata expressions
data MetaExpr = MetaStr !LMString
| MetaNode !MetaId
| MetaVar !LlvmVar
| MetaStruct [MetaExpr]
deriving (Eq)
-- | Associates some metadata with a specific label for attaching to an
-- instruction.
data MetaAnnot = MetaAnnot LMString MetaExpr
deriving (Eq)
-- | Metadata declarations. Metadata can only be declared in global scope.
data MetaDecl
-- | Named metadata. Only used for communicating module information to
-- LLVM. ('!name = !{ [!\<n>] }' form).
= MetaNamed !LMString [MetaId]
-- | Metadata node declaration.
-- ('!0 = metadata !{ \<metadata expression> }' form).
| MetaUnnamed !MetaId !MetaExpr
|