Move second_result outside boxed storage.

In instruction formats that have multiple results AND boxed storage,
place the second_result field outside the boxed storage. The 16-byte
instruction format has room for opcode, type, second_result in the first
8 bytes, and the boxed pointer in the last 8 bytes.

This provides a simpler implementation of the second_result() and
second_result_mut() InstructionData methods.
This commit is contained in:
Jakob Stoklund Olesen
2016-10-12 16:01:06 -07:00
parent 3ff28ed064
commit 93f79d7a48
3 changed files with 16 additions and 34 deletions

View File

@@ -158,6 +158,7 @@ pub enum InstructionData {
TernaryOverflow { TernaryOverflow {
opcode: Opcode, opcode: Opcode,
ty: Type, ty: Type,
second_result: Value,
data: Box<TernaryOverflowData>, data: Box<TernaryOverflowData>,
}, },
InsertLane { InsertLane {
@@ -203,6 +204,7 @@ pub enum InstructionData {
Call { Call {
opcode: Opcode, opcode: Opcode,
ty: Type, ty: Type,
second_result: Value,
data: Box<CallData>, data: Box<CallData>,
}, },
Return { Return {
@@ -284,7 +286,6 @@ impl Display for UnaryImmVectorData {
/// Payload data for ternary instructions with multiple results, such as `iadd_carry`. /// Payload data for ternary instructions with multiple results, such as `iadd_carry`.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct TernaryOverflowData { pub struct TernaryOverflowData {
pub second_result: Value,
pub args: [Value; 3], pub args: [Value; 3],
} }
@@ -334,9 +335,6 @@ impl Display for BranchData {
/// Payload of a call instruction. /// Payload of a call instruction.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct CallData { pub struct CallData {
/// Second result value for a call producing multiple return values.
second_result: Value,
/// Callee function. /// Callee function.
pub func_ref: FuncRef, pub func_ref: FuncRef,

View File

@@ -1089,10 +1089,8 @@ impl<'a> Parser<'a> {
InstructionData::TernaryOverflow { InstructionData::TernaryOverflow {
opcode: opcode, opcode: opcode,
ty: VOID, ty: VOID,
data: Box::new(TernaryOverflowData {
second_result: NO_VALUE, second_result: NO_VALUE,
args: [lhs, rhs, cin], data: Box::new(TernaryOverflowData { args: [lhs, rhs, cin] }),
}),
} }
} }
InstructionFormat::Jump => { InstructionFormat::Jump => {

View File

@@ -87,23 +87,16 @@ def gen_instruction_data_impl(fmt):
'pub fn second_result(&self) -> Option<Value> {', '}'): 'pub fn second_result(&self) -> Option<Value> {', '}'):
with fmt.indented('match *self {', '}'): with fmt.indented('match *self {', '}'):
for f in cretonne.InstructionFormat.all_formats: for f in cretonne.InstructionFormat.all_formats:
if not f.multiple_results: if f.multiple_results:
# Single or no results.
fmt.line(
'InstructionData::{} {{ .. }} => None,'
.format(f.name))
elif f.boxed_storage:
# Multiple results, boxed storage.
fmt.line(
'InstructionData::' + f.name +
' { ref data, .. }' +
' => Some(data.second_result),')
else:
# Multiple results, inline storage.
fmt.line( fmt.line(
'InstructionData::' + f.name + 'InstructionData::' + f.name +
' { second_result, .. }' + ' { second_result, .. }' +
' => Some(second_result),') ' => Some(second_result),')
else:
# Single or no results.
fmt.line(
'InstructionData::{} {{ .. }} => None,'
.format(f.name))
fmt.doc_comment('Mutable reference to second result value, if any.') fmt.doc_comment('Mutable reference to second result value, if any.')
with fmt.indented( with fmt.indented(
@@ -111,23 +104,16 @@ def gen_instruction_data_impl(fmt):
" -> Option<&'a mut Value> {", '}'): " -> Option<&'a mut Value> {", '}'):
with fmt.indented('match *self {', '}'): with fmt.indented('match *self {', '}'):
for f in cretonne.InstructionFormat.all_formats: for f in cretonne.InstructionFormat.all_formats:
if not f.multiple_results: if f.multiple_results:
# Single or no results.
fmt.line(
'InstructionData::{} {{ .. }} => None,'
.format(f.name))
elif f.boxed_storage:
# Multiple results, boxed storage.
fmt.line(
'InstructionData::' + f.name +
' { ref mut data, .. }' +
' => Some(&mut data.second_result),')
else:
# Multiple results, inline storage.
fmt.line( fmt.line(
'InstructionData::' + f.name + 'InstructionData::' + f.name +
' { ref mut second_result, .. }' + ' { ref mut second_result, .. }' +
' => Some(second_result),') ' => Some(second_result),')
else:
# Single or no results.
fmt.line(
'InstructionData::{} {{ .. }} => None,'
.format(f.name))
fmt.doc_comment('Get the controlling type variable operand.') fmt.doc_comment('Get the controlling type variable operand.')
with fmt.indented( with fmt.indented(