X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=scripts%2Fir_spec.py;h=45259748eed539564a1661b1cffc3af5a149594b;hb=4de03dcc6a6b5cff24c69afeeb2698c4a4506b19;hp=b4d5710f6a0cb7f453837e82ad1802784f9be86a;hpb=99f23ed8dfa68ab6d96a4080e1d83fc8d4d68dd2;p=libfirm diff --git a/scripts/ir_spec.py b/scripts/ir_spec.py index b4d5710f6..45259748e 100755 --- a/scripts/ir_spec.py +++ b/scripts/ir_spec.py @@ -31,23 +31,25 @@ class Add(Binop): class Alloc(Op): """allocates a block of memory. - It can be specified whether the variable should be allocated to the stack - or to the heap.""" + It can be specified whether the memory should be allocated to the stack + or to the heap. + Allocates memory for one or more objects (depending on value on count input). + """ ins = [ ("mem", "memory dependency" ), ("count", "number of objects to allocate" ), ] outs = [ ("M", "memory result"), + ("res", "pointer to newly allocated memory"), ("X_regular", "control flow when no exception occurs"), ("X_except", "control flow when exception occured"), - ("res", "pointer to newly allocated memory"), ] attrs = [ dict( name = "type", type = "ir_type*", - comment = "type of the allocated variable", + comment = "type of the objects to allocate", ), dict( name = "where", @@ -56,7 +58,9 @@ class Alloc(Op): ) ] flags = [ "fragile", "uses_memory" ] - pinned = "yes" + pinned = "exception" + throws_init = "false" + pinned_init = "op_pin_state_pinned" attr_struct = "alloc_attr" class Anchor(Op): @@ -90,6 +94,9 @@ class ASM(Op): attr_struct = "asm_attr" attrs_name = "assem" customSerializer = True + ins = [ + ("mem", "memory dependency"), + ] attrs = [ dict( name = "input_constraints", @@ -98,7 +105,7 @@ class ASM(Op): ), dict( name = "n_output_constraints", - type = "int", + type = "size_t", noprop = True, comment = "number of output constraints", ), @@ -109,7 +116,7 @@ class ASM(Op): ), dict( name = "n_clobbers", - type = "int", + type = "size_t", noprop = True, comment = "number of clobbered registers/memory", ), @@ -162,7 +169,7 @@ class Deleted(Op): flags = [ ] pinned = "yes" noconstructor = True - customSerializer = True + customSerializer = True # this has no serializer class Block(Op): """A basic block""" @@ -173,6 +180,14 @@ class Block(Op): arity = "variable" flags = [ "labeled" ] attr_struct = "block_attr" + attrs = [ + dict( + name = "entity", + type = "ir_entity*", + comment = "entity representing this block", + init = "NULL", + ), + ] customSerializer = True init = ''' @@ -202,15 +217,15 @@ class Bound(Op): ] outs = [ ("M", "memory result"), + ("res", "the checked index"), ("X_regular", "control flow when no exception occurs"), ("X_except", "control flow when exception occured"), - ("res", "the checked index"), ] flags = [ "fragile", "highlevel" ] pinned = "exception" pinned_init = "op_pin_state_pinned" + throws_init = "false" attr_struct = "bound_attr" - attrs_name = "bound" class Builtin(Op): """performs a backend-specific builtin.""" @@ -219,8 +234,8 @@ class Builtin(Op): ] arity = "variable" outs = [ - ("M", "memory result"), - ("1_result", "first result"), + ("M", "memory result"), + # results follow here ] flags = [ "uses_memory" ] attrs = [ @@ -254,9 +269,9 @@ class Call(Op): arity = "variable" outs = [ ("M", "memory result"), + ("T_result", "tuple containing all results"), ("X_regular", "control flow when no exception occurs"), ("X_except", "control flow when exception occured"), - ("T_result", "tuple containing all results"), ] flags = [ "fragile", "uses_memory" ] attrs = [ @@ -265,16 +280,11 @@ class Call(Op): name = "type", comment = "type of the call (usually type of the called procedure)", ), - dict( - type = "unsigned", - name = "tail_call", - # the tail call attribute can only be set by analysis - init = "0", - ) ] attr_struct = "call_attr" pinned = "memory" pinned_init = "op_pin_state_pinned" + throws_init = "false" init = ''' assert((get_unknown_type() == type) || is_Method_type(type)); ''' @@ -313,19 +323,7 @@ class Cmp(Binop): attr_struct = "cmp_attr" class Cond(Op): - """Conditionally change control flow. There are two versions of this node: - - Boolean Cond: - Input: A value of mode_b - Output: A tuple of two control flows. The first is taken if the input is - false, the second if it is true. - - Switch Cond: - Input: A value of mode_Iu - Output: A tuple of n control flows. If the Cond's input is i, control flow - will proceed along output i. If the input is >= n control flow proceeds - along output def_proj. - """ + """Conditionally change control flow.""" ins = [ ("selector", "condition parameter"), ] @@ -336,21 +334,42 @@ class Cond(Op): flags = [ "cfopcode", "forking" ] pinned = "yes" attrs = [ - dict( - name = "default_proj", - type = "long", - init = "0", - comment = "Proj-number of default case for switch-Cond", - ), dict( name = "jmp_pred", type = "cond_jmp_predicate", init = "COND_JMP_PRED_NONE", comment = "can indicate the most likely jump", - ) + ), ] attr_struct = "cond_attr" +class Switch(Op): + """Change control flow. The destination is choosen based on an integer input value which is looked up in a table. + + Backends can implement this efficiently using a jump table.""" + ins = [ + ("selector", "input selector"), + ] + outs = [ + ("default", "control flow if no other case matches"), + ] + flags = [ "cfopcode", "forking" ] + pinned = "yes" + attrs = [ + dict( + name = "n_outs", + type = "unsigned", + comment = "number of outputs (including pn_Switch_default)", + ), + dict( + name = "table", + type = "ir_switch_table*", + comment = "table describing mapping from input values to Proj numbers", + ), + ] + attr_struct = "switch_attr" + attrs_name = "switcha" + class Confirm(Op): """Specifies constraints for a value. This allows explicit representation of path-sensitive properties. (Example: This value is always >= 0 on 1 @@ -376,7 +395,6 @@ class Confirm(Op): ), ] attr_struct = "confirm_attr" - attrs_name = "confirm" class Const(Op): """Returns a constant value.""" @@ -407,10 +425,9 @@ class Conv(Unop): ) ] attr_struct = "conv_attr" - attrs_name = "conv" class CopyB(Op): - """Copies a block of memory""" + """Copies a block of memory with statically known size/type.""" ins = [ ("mem", "memory dependency"), ("dst", "destination address"), @@ -430,9 +447,9 @@ class CopyB(Op): ) ] attr_struct = "copyb_attr" - attrs_name = "copyb" pinned = "memory" pinned_init = "op_pin_state_pinned" + throws_init = "false" class Div(Op): """returns the quotient of its 2 operands""" @@ -443,12 +460,11 @@ class Div(Op): ] outs = [ ("M", "memory result"), + ("res", "result of computation"), ("X_regular", "control flow when no exception occurs"), ("X_except", "control flow when exception occured"), - ("res", "result of computation"), ] flags = [ "fragile", "uses_memory" ] - attrs_name = "div" attrs = [ dict( type = "ir_mode*", @@ -463,6 +479,7 @@ class Div(Op): ] attr_struct = "div_attr" pinned = "exception" + throws_init = "false" op_index = 1 arity_override = "oparity_binary" @@ -486,10 +503,11 @@ class End(Op): knownBlock = True block = "get_irg_end_block(irg)" singleton = True - customSerializer = True class Eor(Binop): - """returns the result of a bitwise exclusive or operation of its operands""" + """returns the result of a bitwise exclusive or operation of its operands. + + This is also known as the Xor operation.""" flags = [ "commutative" ] class Free(Op): @@ -497,7 +515,7 @@ class Free(Op): ins = [ ("mem", "memory dependency" ), ("ptr", "pointer to the object to free"), - ("size", "number of objects to allocate" ), + ("count", "number of objects to allocate" ), ] mode = "mode_M" flags = [ "uses_memory" ] @@ -517,7 +535,10 @@ class Free(Op): attr_struct = "free_attr" class Id(Op): - """Returns its operand unchanged.""" + """Returns its operand unchanged. + + This is mainly used when exchanging nodes. Usually you shouldn't see Id + nodes since the getters/setters for node inputs skip them automatically.""" ins = [ ("pred", "the value which is returned unchanged") ] @@ -543,9 +564,9 @@ class InstOf(Op): ] outs = [ ("M", "memory result"), + ("res", "checked object pointer"), ("X_regular", "control flow when no exception occurs"), ("X_except", "control flow when exception occured"), - ("res", "checked object pointer"), ] flags = [ "highlevel" ] attrs = [ @@ -574,9 +595,9 @@ class Load(Op): ] outs = [ ("M", "memory result"), + ("res", "result of load operation"), ("X_regular", "control flow when no exception occurs"), ("X_except", "control flow when exception occured"), - ("res", "result of load operation"), ] flags = [ "fragile", "uses_memory" ] pinned = "exception" @@ -591,12 +612,14 @@ class Load(Op): name = "volatility", comment = "volatile loads are a visible side-effect and may not be optimized", init = "flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile", + to_flags = "%s == volatility_is_volatile ? cons_volatile : 0" ), dict( type = "ir_align", name = "unaligned", comment = "pointers to unaligned loads don't need to respect the load-mode/type alignments", init = "flags & cons_unaligned ? align_non_aligned : align_is_aligned", + to_flags = "%s == align_non_aligned ? cons_unaligned : 0" ), ] attr_struct = "load_attr" @@ -608,6 +631,7 @@ class Load(Op): ), ] pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned" + throws_init = "(flags & cons_throws_exception) != 0" class Minus(Unop): """returns the difference between its operands""" @@ -617,6 +641,7 @@ class Mod(Op): """returns the remainder of its operands from an implied division. Examples: + * mod(5,3) produces 2 * mod(5,-3) produces 2 * mod(-5,3) produces -2 @@ -629,12 +654,11 @@ class Mod(Op): ] outs = [ ("M", "memory result"), + ("res", "result of computation"), ("X_regular", "control flow when no exception occurs"), ("X_except", "control flow when exception occured"), - ("res", "result of computation"), ] flags = [ "fragile", "uses_memory" ] - attrs_name = "mod" attrs = [ dict( type = "ir_mode*", @@ -644,6 +668,7 @@ class Mod(Op): ] attr_struct = "mod_attr" pinned = "exception" + throws_init = "false" op_index = 1 arity_override = "oparity_binary" @@ -677,9 +702,7 @@ class NoMem(Op): singleton = True class Not(Unop): - """returns the logical complement of a value. Works for integer values too. - If the input is false/zero then true/one is returned, otherwise false/zero - is returned.""" + """returns the bitwise complement of a value. Works for boolean values, too.""" flags = [] class Or(Binop): @@ -701,6 +724,7 @@ class Phi(Op): As we can't distinguish these easily we keep all of them alive. */ if (is_Phi(res) && mode == mode_M) add_End_keepalive(get_irg_end(irg), res);''' + customSerializer = True class Pin(Op): """Pin the value of the node node in the current block. No users of the Pin @@ -724,7 +748,6 @@ class Proj(Op): knownGraph = True block = "get_nodes_block(irn_pred)" graph = "get_irn_irg(irn_pred)" - customSerializer = True attrs = [ dict( type = "long", @@ -767,7 +790,10 @@ class Rotl(Binop): class Sel(Op): """Computes the address of a entity of a compound type given the base - address of an instance of the compound type.""" + address of an instance of the compound type. + + Optimisations assume that a Sel node can only produce a NULL pointer if the + ptr input was NULL.""" ins = [ ("mem", "memory dependency"), ("ptr", "pointer to object to select from"), @@ -814,7 +840,6 @@ class Start(Op): flags = [ "cfopcode" ] singleton = True knownBlock = True - customSerializer = True block = "get_irg_start_block(irg)" class Store(Op): @@ -833,18 +858,21 @@ class Store(Op): pinned = "exception" attr_struct = "store_attr" pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned" + throws_init = "(flags & cons_throws_exception) != 0" attrs = [ dict( type = "ir_volatility", name = "volatility", comment = "volatile stores are a visible side-effect and may not be optimized", init = "flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile", + to_flags = "%s == volatility_is_volatile ? cons_volatile : 0" ), dict( type = "ir_align", name = "unaligned", comment = "pointers to unaligned stores don't need to respect the load-mode/type alignments", init = "flags & cons_unaligned ? align_non_aligned : align_is_aligned", + to_flags = "%s == align_non_aligned ? cons_unaligned : 0" ), ] constructor_args = [ @@ -862,21 +890,19 @@ class Sub(Binop): class SymConst(Op): """A symbolic constant. - - symconst_type_tag The symbolic constant represents a type tag. The - type the tag stands for is given explicitly. - - symconst_type_size The symbolic constant represents the size of a type. - The type of which the constant represents the size - is given explicitly. - - symconst_type_align The symbolic constant represents the alignment of a - type. The type of which the constant represents the - size is given explicitly. - - symconst_addr_ent The symbolic constant represents the address of an - entity (variable or method). The variable is given - explicitly by a firm entity. - - symconst_ofs_ent The symbolic constant represents the offset of an - entity in its owner type. - - symconst_enum_const The symbolic constant is a enumeration constant of - an enumeration type.""" + - *symconst_type_size* The symbolic constant represents the size of a type. + The type of which the constant represents the size + is given explicitly. + - *symconst_type_align* The symbolic constant represents the alignment of a + type. The type of which the constant represents the + size is given explicitly. + - *symconst_addr_ent* The symbolic constant represents the address of an + entity (variable or method). The variable is given + explicitly by a firm entity. + - *symconst_ofs_ent* The symbolic constant represents the offset of an + entity in its owner type. + - *symconst_enum_const* The symbolic constant is a enumeration constant of + an enumeration type.""" mode = "mode_P" flags = [ "constlike", "start_block" ] knownBlock = True