Custom legalization for global_addr.
The code to compute the address of a global variable depends on the kind of variable, so custom legalization is required. - Add a legalizer::globalvar module which exposes an expand_global_addr() function. This module is likely to grow as we add more types of global variables. - Add a ArgumentPurpose::VMContext enumerator. This is used to represent special 'vmctx' arguments that are used as base pointers for vmctx globals.
This commit is contained in:
@@ -56,6 +56,7 @@ pub fn legalize_signatures(func: &mut Function, isa: &TargetIsa) {
|
||||
fn legalize_entry_arguments(func: &mut Function, entry: Ebb) {
|
||||
let mut has_sret = false;
|
||||
let mut has_link = false;
|
||||
let mut has_vmctx = false;
|
||||
|
||||
// Insert position for argument conversion code.
|
||||
// We want to insert instructions before the first instruction in the entry block.
|
||||
@@ -86,6 +87,10 @@ fn legalize_entry_arguments(func: &mut Function, entry: Ebb) {
|
||||
assert!(!has_sret, "Multiple sret arguments found");
|
||||
has_sret = true;
|
||||
}
|
||||
ArgumentPurpose::VMContext => {
|
||||
assert!(!has_vmctx, "Multiple vmctx arguments found");
|
||||
has_vmctx = true;
|
||||
}
|
||||
_ => panic!("Unexpected special-purpose arg {}", abi_types[abi_arg]),
|
||||
}
|
||||
abi_arg += 1;
|
||||
@@ -134,7 +139,12 @@ fn legalize_entry_arguments(func: &mut Function, entry: Ebb) {
|
||||
assert!(!has_sret, "Multiple sret arguments found");
|
||||
has_sret = true;
|
||||
}
|
||||
ArgumentPurpose::VMContext => {
|
||||
assert!(!has_vmctx, "Multiple vmctx arguments found");
|
||||
has_vmctx = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Just create entry block values to match here. We will use them in `handle_return_abi()`
|
||||
// below.
|
||||
func.dfg.append_ebb_arg(entry, arg.value_type);
|
||||
@@ -503,14 +513,15 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph
|
||||
return false;
|
||||
}
|
||||
|
||||
// Count the special-purpose return values (`link` and `sret`) that were appended to the
|
||||
// legalized signature.
|
||||
// Count the special-purpose return values (`link`, `sret`, and `vmctx`) that were appended to
|
||||
// the legalized signature.
|
||||
let special_args = sig.return_types
|
||||
.iter()
|
||||
.rev()
|
||||
.take_while(|&rt| {
|
||||
rt.purpose == ArgumentPurpose::Link ||
|
||||
rt.purpose == ArgumentPurpose::StructReturn
|
||||
rt.purpose == ArgumentPurpose::StructReturn ||
|
||||
rt.purpose == ArgumentPurpose::VMContext
|
||||
})
|
||||
.count();
|
||||
|
||||
@@ -522,8 +533,8 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph
|
||||
|_, abi_arg| sig.return_types[abi_arg]);
|
||||
assert_eq!(dfg.inst_variable_args(inst).len(), abi_args);
|
||||
|
||||
// Append special return arguments for any `sret` and `link` return values added to the
|
||||
// legalized signature. These values should simply be propagated from the entry block
|
||||
// Append special return arguments for any `sret`, `link`, and `vmctx` return values added to
|
||||
// the legalized signature. These values should simply be propagated from the entry block
|
||||
// arguments.
|
||||
if special_args > 0 {
|
||||
dbg!("Adding {} special-purpose arguments to {}",
|
||||
@@ -533,13 +544,14 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph
|
||||
for arg in &sig.return_types[abi_args..] {
|
||||
match arg.purpose {
|
||||
ArgumentPurpose::Link |
|
||||
ArgumentPurpose::StructReturn => {}
|
||||
ArgumentPurpose::StructReturn |
|
||||
ArgumentPurpose::VMContext => {}
|
||||
ArgumentPurpose::Normal => panic!("unexpected return value {}", arg),
|
||||
_ => panic!("Unsupported special purpose return value {}", arg),
|
||||
}
|
||||
// A `link` or `sret` return value can only appear in a signature that has a unique
|
||||
// matching argument. They are appended at the end, so search the signature from the
|
||||
// end.
|
||||
// A `link`/`sret`/`vmctx` return value can only appear in a signature that has a
|
||||
// unique matching argument. They are appended at the end, so search the signature from
|
||||
// the end.
|
||||
let idx = sig.argument_types
|
||||
.iter()
|
||||
.rposition(|t| t.purpose == arg.purpose)
|
||||
|
||||
Reference in New Issue
Block a user