Adds the libcall_call_conv setting and use it for libcall calls expansion;

This commit is contained in:
Benjamin Bouvier
2019-08-05 12:23:39 +02:00
committed by Dan Gohman
parent c7b4b98cac
commit d8d3602257
5 changed files with 63 additions and 4 deletions

View File

@@ -94,6 +94,29 @@ pub fn define() -> SettingGroup {
// Settings specific to the `baldrdash` calling convention.
settings.add_enum(
"libcall_call_conv",
r#"
Defines the calling convention to use for LibCalls call expansion,
since it may be different from the ISA default calling convention.
The default value is to use the same calling convention as the ISA
default calling convention.
This list should be kept in sync with the list of calling
conventions available in isa/call_conv.rs.
"#,
vec![
"isa_default",
"fast",
"cold",
"system_v",
"windows_fastcall",
"baldrdash",
"probestack",
],
);
settings.add_num(
"baldrdash_prologue_words",
r#"

View File

@@ -108,11 +108,13 @@ impl LibCall {
/// If there is an existing reference, use it, otherwise make a new one.
pub fn get_libcall_funcref(
libcall: LibCall,
call_conv: CallConv,
func: &mut Function,
inst: Inst,
isa: &dyn TargetIsa,
) -> FuncRef {
find_funcref(libcall, func).unwrap_or_else(|| make_funcref_for_inst(libcall, func, inst, isa))
find_funcref(libcall, func)
.unwrap_or_else(|| make_funcref_for_inst(libcall, call_conv, func, inst, isa))
}
/// Get a function reference for the probestack function in `func`.
@@ -164,11 +166,12 @@ fn make_funcref_for_probestack(
/// Create a funcref for `libcall` with a signature matching `inst`.
fn make_funcref_for_inst(
libcall: LibCall,
call_conv: CallConv,
func: &mut Function,
inst: Inst,
isa: &dyn TargetIsa,
) -> FuncRef {
let mut sig = Signature::new(isa.default_call_conv());
let mut sig = Signature::new(call_conv);
for &v in func.dfg.inst_args(inst) {
sig.params.push(AbiParam::new(func.dfg.value_type(v)));
}
@@ -176,6 +179,14 @@ fn make_funcref_for_inst(
sig.returns.push(AbiParam::new(func.dfg.value_type(v)));
}
if call_conv == CallConv::Baldrdash {
// Adds the special VMContext parameter to the signature.
sig.params.push(AbiParam::special(
isa.pointer_type(),
ArgumentPurpose::VMContext,
));
}
make_funcref(libcall, func, sig, isa)
}

View File

@@ -1,3 +1,5 @@
use crate::isa::TargetIsa;
use crate::settings::LibcallCallConv;
use core::fmt;
use core::str;
use target_lexicon::{CallingConvention, Triple};
@@ -29,6 +31,19 @@ impl CallConv {
Ok(CallingConvention::WindowsFastcall) => CallConv::WindowsFastcall,
}
}
/// Returns the calling convention used for libcalls for the given ISA.
pub fn for_libcall(isa: &dyn TargetIsa) -> Self {
match isa.flags().libcall_call_conv() {
LibcallCallConv::IsaDefault => isa.default_call_conv(),
LibcallCallConv::Fast => CallConv::Fast,
LibcallCallConv::Cold => CallConv::Cold,
LibcallCallConv::SystemV => CallConv::SystemV,
LibcallCallConv::WindowsFastcall => CallConv::WindowsFastcall,
LibcallCallConv::Baldrdash => CallConv::Baldrdash,
LibcallCallConv::Probestack => CallConv::Probestack,
}
}
}
impl fmt::Display for CallConv {

View File

@@ -2,7 +2,7 @@
use crate::ir;
use crate::ir::{get_libcall_funcref, InstBuilder};
use crate::isa::TargetIsa;
use crate::isa::{CallConv, TargetIsa};
use crate::legalizer::boundary::legalize_libcall_signature;
use std::vec::Vec;
@@ -18,8 +18,17 @@ pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function, isa: &dyn Targ
// Now we convert `inst` to a call. First save the arguments.
let mut args = Vec::new();
args.extend_from_slice(func.dfg.inst_args(inst));
let call_conv = CallConv::for_libcall(isa);
if call_conv == CallConv::Baldrdash {
let vmctx = func
.special_param(ir::ArgumentPurpose::VMContext)
.expect("Missing vmctx parameter for baldrdash libcall");
args.push(vmctx);
}
// The replace builder will preserve the instruction result values.
let funcref = get_libcall_funcref(libcall, func, inst, isa);
let funcref = get_libcall_funcref(libcall, call_conv, func, inst, isa);
func.dfg.replace(inst).call(funcref, &args);
// Ask the ISA to legalize the signature.

View File

@@ -379,6 +379,7 @@ mod tests {
f.to_string(),
"[shared]\n\
opt_level = \"default\"\n\
libcall_call_conv = \"isa_default\"\n\
baldrdash_prologue_words = 0\n\
probestack_size_log2 = 12\n\
enable_verifier = true\n\