Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/codegen/src/ir/globalvalue.rs
1693 views
1
//! Global values.
2
3
use crate::ir::immediates::{Imm64, Offset32};
4
use crate::ir::{ExternalName, GlobalValue, MemFlags, Type};
5
use crate::isa::TargetIsa;
6
use core::fmt;
7
8
#[cfg(feature = "enable-serde")]
9
use serde_derive::{Deserialize, Serialize};
10
11
/// Information about a global value declaration.
12
#[derive(Debug, Clone, PartialEq, Hash)]
13
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
14
pub enum GlobalValueData {
15
/// Value is the address of the VM context struct.
16
VMContext,
17
18
/// Value is pointed to by another global value.
19
///
20
/// The `base` global value is assumed to contain a pointer. This global value is computed
21
/// by loading from memory at that pointer value. The memory must be accessible, and
22
/// naturally aligned to hold a value of the type. The data at this address is assumed
23
/// to never change while the current function is executing.
24
Load {
25
/// The base pointer global value.
26
base: GlobalValue,
27
28
/// Offset added to the base pointer before doing the load.
29
offset: Offset32,
30
31
/// Type of the loaded value.
32
global_type: Type,
33
34
/// Specifies the memory flags to be used by the load. Guaranteed to be notrap and aligned.
35
flags: MemFlags,
36
},
37
38
/// Value is an offset from another global value.
39
IAddImm {
40
/// The base pointer global value.
41
base: GlobalValue,
42
43
/// Byte offset to be added to the value.
44
offset: Imm64,
45
46
/// Type of the iadd.
47
global_type: Type,
48
},
49
50
/// Value is symbolic, meaning it's a name which will be resolved to an
51
/// actual value later (eg. by linking). Cranelift itself does not interpret
52
/// this name; it's used by embedders to link with other data structures.
53
///
54
/// For now, symbolic values always have pointer type, and represent
55
/// addresses, however in the future they could be used to represent other
56
/// things as well.
57
Symbol {
58
/// The symbolic name.
59
name: ExternalName,
60
61
/// Offset from the symbol. This can be used instead of IAddImm to represent folding an
62
/// offset into a symbol.
63
offset: Imm64,
64
65
/// Will this symbol be defined nearby, such that it will always be a certain distance
66
/// away, after linking? If so, references to it can avoid going through a GOT. Note that
67
/// symbols meant to be preemptible cannot be colocated.
68
///
69
/// If `true`, some backends may use relocation forms that have limited range: for example,
70
/// a +/- 2^27-byte range on AArch64. See the documentation for
71
/// `RelocDistance` for more details.
72
colocated: bool,
73
74
/// Does this symbol refer to a thread local storage value?
75
tls: bool,
76
},
77
78
/// Value is a multiple of how many instances of `vector_type` will fit in
79
/// a target vector register.
80
DynScaleTargetConst {
81
/// Base vector type.
82
vector_type: Type,
83
},
84
}
85
86
impl GlobalValueData {
87
/// Assume that `self` is an `GlobalValueData::Symbol` and return its name.
88
pub fn symbol_name(&self) -> &ExternalName {
89
match *self {
90
Self::Symbol { ref name, .. } => name,
91
_ => panic!("only symbols have names"),
92
}
93
}
94
95
/// Return the type of this global.
96
pub fn global_type(&self, isa: &dyn TargetIsa) -> Type {
97
match *self {
98
Self::VMContext { .. } | Self::Symbol { .. } => isa.pointer_type(),
99
Self::IAddImm { global_type, .. } | Self::Load { global_type, .. } => global_type,
100
Self::DynScaleTargetConst { .. } => isa.pointer_type(),
101
}
102
}
103
}
104
105
impl fmt::Display for GlobalValueData {
106
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107
match *self {
108
Self::VMContext => write!(f, "vmctx"),
109
Self::Load {
110
base,
111
offset,
112
global_type,
113
flags,
114
} => write!(f, "load.{global_type}{flags} {base}{offset}"),
115
Self::IAddImm {
116
global_type,
117
base,
118
offset,
119
} => write!(f, "iadd_imm.{global_type} {base}, {offset}"),
120
Self::Symbol {
121
ref name,
122
offset,
123
colocated,
124
tls,
125
} => {
126
write!(
127
f,
128
"symbol {}{}{}",
129
if colocated { "colocated " } else { "" },
130
if tls { "tls " } else { "" },
131
name.display(None)
132
)?;
133
let offset_val: i64 = offset.into();
134
if offset_val > 0 {
135
write!(f, "+")?;
136
}
137
if offset_val != 0 {
138
write!(f, "{offset}")?;
139
}
140
Ok(())
141
}
142
Self::DynScaleTargetConst { vector_type } => {
143
write!(f, "dyn_scale_target_const.{vector_type}")
144
}
145
}
146
}
147
}
148
149