From 58756e5d3463749ede0188e37cf0a29d2f2d06e5 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 8 Mar 2017 14:48:50 -0800 Subject: [PATCH] Add is_call and is_return instruction attributes. --- lib/cretonne/meta/base/instructions.py | 10 ++++------ lib/cretonne/meta/cdsl/instructions.py | 18 +++++++++++++++--- lib/cretonne/meta/gen_instr.py | 26 ++++---------------------- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/lib/cretonne/meta/base/instructions.py b/lib/cretonne/meta/base/instructions.py index 09cd2c75c7..a61f98cefe 100644 --- a/lib/cretonne/meta/base/instructions.py +++ b/lib/cretonne/meta/base/instructions.py @@ -111,7 +111,7 @@ x_return = Instruction( provided return values. The list of return values must match the function signature's return types. """, - ins=rvals, is_terminator=True) + ins=rvals, is_return=True, is_terminator=True) raddr = Operand('raddr', iAddr, doc='Return address') @@ -130,7 +130,7 @@ return_reg = Instruction( :inst:`return` will be legalized into this instruction on these architectures. """, - ins=(raddr, rvals), is_terminator=True) + ins=(raddr, rvals), is_return=True, is_terminator=True) FN = Operand( 'FN', @@ -145,8 +145,7 @@ call = Instruction( Call a function which has been declared in the preamble. The argument types must match the function's signature. """, - ins=(FN, args), - outs=rvals) + ins=(FN, args), outs=rvals, is_call=True) SIG = Operand('SIG', entities.sig_ref, doc='function signature') callee = Operand('callee', iAddr, doc='address of function to call') @@ -158,8 +157,7 @@ call_indirect = Instruction( Call the function pointed to by `callee` with the given arguments. The called function must match the specified signature. """, - ins=(SIG, callee, args), - outs=rvals) + ins=(SIG, callee, args), outs=rvals, is_call=True) # # Materializing constants. diff --git a/lib/cretonne/meta/cdsl/instructions.py b/lib/cretonne/meta/cdsl/instructions.py index 4040e5338b..fcce1684fd 100644 --- a/lib/cretonne/meta/cdsl/instructions.py +++ b/lib/cretonne/meta/cdsl/instructions.py @@ -80,9 +80,22 @@ class Instruction(object): values or `variable_args`. :param is_terminator: This is a terminator instruction. :param is_branch: This is a branch instruction. + :param is_call: This is a call instruction. + :param is_return: This is a return instruction. :param can_trap: This instruction can trap. """ + # Boolean instruction attributes that can be passed as keyword arguments to + # the constructor. Map attribute name to doc comment for generated Rust + # code. + ATTRIBS = { + 'is_terminator': 'True for instructions that terminate the EBB.', + 'is_branch': 'True for all branch or jump instructions.', + 'is_call': 'Is this a call instruction?', + 'is_return': 'Is this a return instruction?', + 'can_trap': 'Can this instruction cause a trap?', + } + def __init__(self, name, doc, ins=(), outs=(), **kwargs): # type: (str, str, OpList, OpList, **Any) -> None # noqa self.name = name @@ -95,9 +108,8 @@ class Instruction(object): self.value_results = tuple( i for i, o in enumerate(self.outs) if o.is_value()) self._verify_polymorphic() - self.is_branch = 'is_branch' in kwargs - self.is_terminator = 'is_terminator' in kwargs - self.can_trap = 'can_trap' in kwargs + for attr in Instruction.ATTRIBS: + setattr(self, attr, not not kwargs.get(attr, False)) InstructionGroup.append(self) def __str__(self): diff --git a/lib/cretonne/meta/gen_instr.py b/lib/cretonne/meta/gen_instr.py index 166967698e..353fa60551 100644 --- a/lib/cretonne/meta/gen_instr.py +++ b/lib/cretonne/meta/gen_instr.py @@ -288,31 +288,13 @@ def gen_opcodes(groups, fmt): fmt.line() with fmt.indented('impl Opcode {', '}'): - attrs = [ - { - 'name': 'is_branch', - 'comment': 'True for all branch instructions.' - }, - { - 'name': 'is_terminator', - 'comment': 'True for instructions that terminate EBB.' - }, - { - 'name': 'can_trap', - 'comment': 'True if instruction could trap.' - } - ] - - for attr in attrs: - if attr != attrs[0]: - fmt.line() - - fmt.doc_comment(attr['comment']) + for attr in sorted(Instruction.ATTRIBS.keys()): + fmt.doc_comment(Instruction.ATTRIBS[attr]) with fmt.indented('pub fn {}(self) -> bool {{' - .format(attr['name']), '}'): + .format(attr), '}'): with fmt.indented('match self {', '}'): for i in instrs: - if getattr(i, attr['name']): + if getattr(i, attr): fmt.format( 'Opcode::{} => true,', i.camel_name, i.name)