Path: blob/main/cranelift/codegen/src/ir/globalvalue.rs
1693 views
//! Global values.12use crate::ir::immediates::{Imm64, Offset32};3use crate::ir::{ExternalName, GlobalValue, MemFlags, Type};4use crate::isa::TargetIsa;5use core::fmt;67#[cfg(feature = "enable-serde")]8use serde_derive::{Deserialize, Serialize};910/// Information about a global value declaration.11#[derive(Debug, Clone, PartialEq, Hash)]12#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]13pub enum GlobalValueData {14/// Value is the address of the VM context struct.15VMContext,1617/// Value is pointed to by another global value.18///19/// The `base` global value is assumed to contain a pointer. This global value is computed20/// by loading from memory at that pointer value. The memory must be accessible, and21/// naturally aligned to hold a value of the type. The data at this address is assumed22/// to never change while the current function is executing.23Load {24/// The base pointer global value.25base: GlobalValue,2627/// Offset added to the base pointer before doing the load.28offset: Offset32,2930/// Type of the loaded value.31global_type: Type,3233/// Specifies the memory flags to be used by the load. Guaranteed to be notrap and aligned.34flags: MemFlags,35},3637/// Value is an offset from another global value.38IAddImm {39/// The base pointer global value.40base: GlobalValue,4142/// Byte offset to be added to the value.43offset: Imm64,4445/// Type of the iadd.46global_type: Type,47},4849/// Value is symbolic, meaning it's a name which will be resolved to an50/// actual value later (eg. by linking). Cranelift itself does not interpret51/// this name; it's used by embedders to link with other data structures.52///53/// For now, symbolic values always have pointer type, and represent54/// addresses, however in the future they could be used to represent other55/// things as well.56Symbol {57/// The symbolic name.58name: ExternalName,5960/// Offset from the symbol. This can be used instead of IAddImm to represent folding an61/// offset into a symbol.62offset: Imm64,6364/// Will this symbol be defined nearby, such that it will always be a certain distance65/// away, after linking? If so, references to it can avoid going through a GOT. Note that66/// symbols meant to be preemptible cannot be colocated.67///68/// If `true`, some backends may use relocation forms that have limited range: for example,69/// a +/- 2^27-byte range on AArch64. See the documentation for70/// `RelocDistance` for more details.71colocated: bool,7273/// Does this symbol refer to a thread local storage value?74tls: bool,75},7677/// Value is a multiple of how many instances of `vector_type` will fit in78/// a target vector register.79DynScaleTargetConst {80/// Base vector type.81vector_type: Type,82},83}8485impl GlobalValueData {86/// Assume that `self` is an `GlobalValueData::Symbol` and return its name.87pub fn symbol_name(&self) -> &ExternalName {88match *self {89Self::Symbol { ref name, .. } => name,90_ => panic!("only symbols have names"),91}92}9394/// Return the type of this global.95pub fn global_type(&self, isa: &dyn TargetIsa) -> Type {96match *self {97Self::VMContext { .. } | Self::Symbol { .. } => isa.pointer_type(),98Self::IAddImm { global_type, .. } | Self::Load { global_type, .. } => global_type,99Self::DynScaleTargetConst { .. } => isa.pointer_type(),100}101}102}103104impl fmt::Display for GlobalValueData {105fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {106match *self {107Self::VMContext => write!(f, "vmctx"),108Self::Load {109base,110offset,111global_type,112flags,113} => write!(f, "load.{global_type}{flags} {base}{offset}"),114Self::IAddImm {115global_type,116base,117offset,118} => write!(f, "iadd_imm.{global_type} {base}, {offset}"),119Self::Symbol {120ref name,121offset,122colocated,123tls,124} => {125write!(126f,127"symbol {}{}{}",128if colocated { "colocated " } else { "" },129if tls { "tls " } else { "" },130name.display(None)131)?;132let offset_val: i64 = offset.into();133if offset_val > 0 {134write!(f, "+")?;135}136if offset_val != 0 {137write!(f, "{offset}")?;138}139Ok(())140}141Self::DynScaleTargetConst { vector_type } => {142write!(f, "dyn_scale_target_const.{vector_type}")143}144}145}146}147148149